• 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 	const GLuint padding = alignment - GetTypeSize(m_basic_type) * m_n_rows;
182 	const GLuint data_size = alignment * m_n_columns - padding;
183 
184 	std::vector<GLubyte> data;
185 	data.resize(data_size);
186 
187 	for (GLuint column = 0; column < m_n_columns; ++column)
188 	{
189 		GLvoid* ptr = (GLvoid*)&data[column * alignment];
190 
191 		switch (m_basic_type)
192 		{
193 		case Double:
194 		{
195 			GLdouble* d_ptr = (GLdouble*)ptr;
196 
197 			for (GLuint i = 0; i < m_n_rows; ++i)
198 			{
199 				d_ptr[i] = GetRandDouble();
200 			}
201 		}
202 		break;
203 		case Float:
204 		{
205 			GLfloat* f_ptr = (GLfloat*)ptr;
206 
207 			for (GLuint i = 0; i < m_n_rows; ++i)
208 			{
209 				f_ptr[i] = GetRandFloat();
210 			}
211 		}
212 		break;
213 		case Int:
214 		{
215 			GLint* i_ptr = (GLint*)ptr;
216 
217 			for (GLuint i = 0; i < m_n_rows; ++i)
218 			{
219 				i_ptr[i] = GetRandInt();
220 			}
221 		}
222 		break;
223 		case Uint:
224 		{
225 			GLuint* ui_ptr = (GLuint*)ptr;
226 
227 			for (GLuint i = 0; i < m_n_rows; ++i)
228 			{
229 				ui_ptr[i] = GetRandUint();
230 			}
231 		}
232 		break;
233 		}
234 	}
235 
236 	return data;
237 }
238 
239 /** Generate data for type. This routine packs data tightly.
240  *
241  * @return Vector of bytes filled with data
242  **/
GenerateDataPacked() const243 std::vector<GLubyte> Type::GenerateDataPacked() const
244 {
245 	const GLuint basic_size = GetTypeSize(m_basic_type);
246 	const GLuint n_elements = m_n_columns * m_n_rows;
247 	const GLuint size		= basic_size * n_elements;
248 
249 	std::vector<GLubyte> data;
250 	data.resize(size);
251 
252 	GLvoid* ptr = (GLvoid*)&data[0];
253 
254 	switch (m_basic_type)
255 	{
256 	case Double:
257 	{
258 		GLdouble* d_ptr = (GLdouble*)ptr;
259 
260 		for (GLuint i = 0; i < n_elements; ++i)
261 		{
262 			d_ptr[i] = GetRandDouble();
263 		}
264 	}
265 	break;
266 	case Float:
267 	{
268 		GLfloat* f_ptr = (GLfloat*)ptr;
269 
270 		for (GLuint i = 0; i < n_elements; ++i)
271 		{
272 			f_ptr[i] = GetRandFloat();
273 		}
274 	}
275 	break;
276 	case Int:
277 	{
278 		GLint* i_ptr = (GLint*)ptr;
279 
280 		for (GLuint i = 0; i < n_elements; ++i)
281 		{
282 			i_ptr[i] = GetRandInt();
283 		}
284 	}
285 	break;
286 	case Uint:
287 	{
288 		GLuint* ui_ptr = (GLuint*)ptr;
289 
290 		for (GLuint i = 0; i < n_elements; ++i)
291 		{
292 			ui_ptr[i] = GetRandUint();
293 		}
294 	}
295 	break;
296 	}
297 
298 	return data;
299 }
300 
301 /** Calculate "actual alignment". It work under assumption that align value is valid
302  *
303  * @param align    Requested alignment, eg with "align" qualifier
304  * @param is_array Selects if an array of type or single instance should be considered
305  *
306  * @return Calculated value
307  **/
GetActualAlignment(GLuint align,bool is_array) const308 GLuint Type::GetActualAlignment(GLuint align, bool is_array) const
309 {
310 	const GLuint base_alignment = GetBaseAlignment(is_array);
311 
312 	return std::max(align, base_alignment);
313 }
314 
315 /** Align given ofset with specified alignment
316  *
317  * @param offset    Offset
318  * @param alignment Alignment
319  *
320  * @return Calculated value
321  **/
align(GLuint offset,GLuint alignment)322 GLuint align(GLuint offset, GLuint alignment)
323 {
324 	const GLuint rest = offset % alignment;
325 
326 	if (0 != rest)
327 	{
328 		GLuint missing = alignment - rest;
329 		offset += missing;
330 	}
331 
332 	return offset;
333 }
334 
335 /** Calculate "actual offset"
336  *
337  * @param start_offset     Requested offset
338  * @param actual_alignment Actual alignemnt
339  *
340  * @return Calculated value
341  **/
GetActualOffset(GLuint start_offset,GLuint actual_alignment)342 GLuint Type::GetActualOffset(GLuint start_offset, GLuint actual_alignment)
343 {
344 	GLuint offset = align(start_offset, actual_alignment);
345 
346 	return offset;
347 }
348 
349 /** Calculate "base alignment" for given type
350  *
351  * @param is_array Select if array or single instance should be considered
352  *
353  * @return Calculated value
354  **/
GetBaseAlignment(bool is_array) const355 GLuint Type::GetBaseAlignment(bool is_array) const
356 {
357 	GLuint elements = 1;
358 
359 	switch (m_n_rows)
360 	{
361 	case 2:
362 		elements = 2;
363 		break;
364 	case 3:
365 	case 4:
366 		elements = 4;
367 		break;
368 	default:
369 		break;
370 	}
371 
372 	GLuint N		 = GetTypeSize(m_basic_type);
373 	GLuint alignment = N * elements;
374 
375 	if ((true == is_array) || (1 != m_n_columns))
376 	{
377 		alignment = align(alignment, 16 /* vec4 alignment */);
378 	}
379 
380 	return alignment;
381 }
382 
383 /** Returns string representing GLSL constructor of type with arguments provided in data
384  *
385  * @param data Array of values that will be used as construcotr arguments.
386  *             It is interpreted as tightly packed array of type matching this type.
387  *
388  * @return String in form "Type(args)"
389  **/
GetGLSLConstructor(const GLvoid * data) const390 std::string Type::GetGLSLConstructor(const GLvoid* data) const
391 {
392 	const GLchar* type = GetGLSLTypeName();
393 
394 	std::stringstream stream;
395 
396 	stream << type << "(";
397 
398 	/* Scalar or vector */
399 	if (1 == m_n_columns)
400 	{
401 		for (GLuint row = 0; row < m_n_rows; ++row)
402 		{
403 			switch (m_basic_type)
404 			{
405 			case Double:
406 				stream << ((GLdouble*)data)[row];
407 				break;
408 			case Float:
409 				stream << ((GLfloat*)data)[row];
410 				break;
411 			case Int:
412 				stream << ((GLint*)data)[row];
413 				break;
414 			case Uint:
415 				stream << ((GLuint*)data)[row];
416 				break;
417 			}
418 
419 			if (row + 1 != m_n_rows)
420 			{
421 				stream << ", ";
422 			}
423 		}
424 	}
425 	else /* Matrix: mat(vec(), vec() .. ) */
426 	{
427 		const GLuint basic_size = GetTypeSize(m_basic_type);
428 		// Very indescoverable defect, the column stride should be calculated by rows, such as mat2x3, which is 2, columns 3 rows, its column stride should be 3 * sizeof(float)
429 		const GLuint column_stride = m_n_rows * basic_size;
430 		const Type   column_type   = GetType(m_basic_type, 1, m_n_rows);
431 
432 		for (GLuint column = 0; column < m_n_columns; ++column)
433 		{
434 			const GLuint  column_offset = column * column_stride;
435 			const GLvoid* column_data   = (GLubyte*)data + column_offset;
436 
437 			stream << column_type.GetGLSLConstructor(column_data);
438 
439 			if (column + 1 != m_n_columns)
440 			{
441 				stream << ", ";
442 			}
443 		}
444 	}
445 
446 	stream << ")";
447 
448 	return stream.str();
449 }
450 
451 /** Get glsl name of the type
452  *
453  * @return Name of glsl type
454  **/
GetGLSLTypeName() const455 const glw::GLchar* Type::GetGLSLTypeName() const
456 {
457 	static const GLchar* float_lut[4][4] = {
458 		{ "float", "vec2", "vec3", "vec4" },
459 		{ 0, "mat2", "mat2x3", "mat2x4" },
460 		{ 0, "mat3x2", "mat3", "mat3x4" },
461 		{ 0, "mat4x2", "mat4x3", "mat4" },
462 	};
463 
464 	static const GLchar* double_lut[4][4] = {
465 		{ "double", "dvec2", "dvec3", "dvec4" },
466 		{ 0, "dmat2", "dmat2x3", "dmat2x4" },
467 		{ 0, "dmat3x2", "dmat3", "dmat3x4" },
468 		{ 0, "dmat4x2", "dmat4x3", "dmat4" },
469 	};
470 
471 	static const GLchar* int_lut[4] = { "int", "ivec2", "ivec3", "ivec4" };
472 
473 	static const GLchar* uint_lut[4] = { "uint", "uvec2", "uvec3", "uvec4" };
474 
475 	const GLchar* result = 0;
476 
477 	if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
478 	{
479 		return 0;
480 	}
481 
482 	switch (m_basic_type)
483 	{
484 	case Float:
485 		result = float_lut[m_n_columns - 1][m_n_rows - 1];
486 		break;
487 	case Double:
488 		result = double_lut[m_n_columns - 1][m_n_rows - 1];
489 		break;
490 	case Int:
491 		result = int_lut[m_n_rows - 1];
492 		break;
493 	case Uint:
494 		result = uint_lut[m_n_rows - 1];
495 		break;
496 	default:
497 		TCU_FAIL("Invalid enum");
498 	}
499 
500 	return result;
501 }
502 
503 /** Get number of locations required for the type
504  *
505  * @return Number of columns times:
506  *          - 2 when type is double with 3 or 4 rows,
507  *          - 1 otherwise or if it's a vertex shader input.
508  **/
GetLocations(bool is_vs_input) const509 GLuint Type::GetLocations(bool is_vs_input) const
510 {
511 	GLuint n_loc_per_column;
512 
513 	/* 1 or 2 doubles any for rest */
514 	if ((2 >= m_n_rows) || (Double != m_basic_type) || is_vs_input)
515 	{
516 		n_loc_per_column = 1;
517 	}
518 	else
519 	{
520 		/* 3 and 4 doubles */
521 		n_loc_per_column = 2;
522 	}
523 
524 	return n_loc_per_column * m_n_columns;
525 }
526 
527 /** Get size of the type in bytes.
528  * Note that this routine doesn't consider arrays and assumes
529  * column_major matrices.
530  *
531  * @return Formula:
532  *          - If std140 packaging and matrix; number of columns * base alignment
533  *          - Otherwise; number of elements * sizeof(base_type)
534  **/
GetSize(const bool is_std140) const535 GLuint Type::GetSize(const bool is_std140) const
536 {
537 	const GLuint basic_type_size = GetTypeSize(m_basic_type);
538 	const GLuint n_elements		 = m_n_columns * m_n_rows;
539 
540 	if (is_std140 && m_n_columns > 1)
541 	{
542 		return m_n_columns * GetBaseAlignment(false);
543 	}
544 
545 	return basic_type_size * n_elements;
546 }
547 
548 /** Get GLenum representing the type
549  *
550  * @return GLenum
551  **/
GetTypeGLenum() const552 GLenum Type::GetTypeGLenum() const
553 {
554 	static const GLenum float_lut[4][4] = {
555 		{ GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 },
556 		{ 0, GL_FLOAT_MAT2, GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4 },
557 		{ 0, GL_FLOAT_MAT3x2, GL_FLOAT_MAT3, GL_FLOAT_MAT3x4 },
558 		{ 0, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3, GL_FLOAT_MAT4 },
559 	};
560 
561 	static const GLenum double_lut[4][4] = {
562 		{ GL_DOUBLE, GL_DOUBLE_VEC2, GL_DOUBLE_VEC3, GL_DOUBLE_VEC4 },
563 		{ 0, GL_DOUBLE_MAT2, GL_DOUBLE_MAT2x3, GL_DOUBLE_MAT2x4 },
564 		{ 0, GL_DOUBLE_MAT3x2, GL_DOUBLE_MAT3, GL_DOUBLE_MAT3x4 },
565 		{ 0, GL_DOUBLE_MAT4x2, GL_DOUBLE_MAT4x3, GL_DOUBLE_MAT4 },
566 	};
567 
568 	static const GLenum int_lut[4] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
569 
570 	static const GLenum uint_lut[4] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
571 										GL_UNSIGNED_INT_VEC4 };
572 
573 	GLenum result = 0;
574 
575 	if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
576 	{
577 		return 0;
578 	}
579 
580 	switch (m_basic_type)
581 	{
582 	case Float:
583 		result = float_lut[m_n_columns - 1][m_n_rows - 1];
584 		break;
585 	case Double:
586 		result = double_lut[m_n_columns - 1][m_n_rows - 1];
587 		break;
588 	case Int:
589 		result = int_lut[m_n_rows - 1];
590 		break;
591 	case Uint:
592 		result = uint_lut[m_n_rows - 1];
593 		break;
594 	default:
595 		TCU_FAIL("Invalid enum");
596 	}
597 
598 	return result;
599 }
600 
601 /** Calculate the number of components consumed by a type
602  *   according to 11.1.2.1 Output Variables
603  *
604  * @return Calculated number of components for the type
605  **/
GetNumComponents() const606 GLuint Type::GetNumComponents() const
607 {
608 	// Rule 3 of Section 7.6.2.2
609 	// If the member is a three-component vector with components consuming N
610 	// basic machine units, the base alignment is 4N.
611 	GLuint num_components = (m_n_rows == 3 ? 4 : m_n_rows) * m_n_columns;
612 
613 	if (m_basic_type == Double)
614 	{
615 		num_components *= 2;
616 	}
617 
618 	return num_components;
619 }
620 
621 /** Calculate the valid values to use with the component qualifier
622  *
623  * @return Vector with the valid values, in growing order, or empty if
624  *         the component qualifier is not allowed
625  **/
GetValidComponents() const626 std::vector<GLuint> Type::GetValidComponents() const
627 {
628 	const GLuint		component_size			  = Utils::Type::Double == m_basic_type ? 2 : 1;
629 	const GLuint		n_components_per_location = Utils::Type::Double == m_basic_type ? 2 : 4;
630 	const GLuint		n_req_components		  = m_n_rows;
631 	const GLint			max_valid_component		  = (GLint)n_components_per_location - (GLint)n_req_components;
632 	std::vector<GLuint> data;
633 
634 	/* The component qualifier cannot be used for matrices */
635 	if (1 != m_n_columns)
636 	{
637 		return data;
638 	}
639 
640 	/* The component qualifier cannot be used for dvec3/dvec4 */
641 	if (max_valid_component < 0)
642 	{
643 		return data;
644 	}
645 
646 	for (GLuint i = 0; i <= (GLuint)max_valid_component; ++i)
647 	{
648 		data.push_back(i * component_size);
649 	}
650 
651 	return data;
652 }
653 
654 /** Calculate stride for the type according to std140 rules
655  *
656  * @param alignment        Alignment of type
657  * @param n_columns        Number of columns
658  * @param n_array_elements Number of elements in array
659  *
660  * @return Calculated value
661  **/
CalculateStd140Stride(GLuint alignment,GLuint n_columns,GLuint n_array_elements)662 GLuint Type::CalculateStd140Stride(GLuint alignment, GLuint n_columns, GLuint n_array_elements)
663 {
664 	GLuint stride = alignment * n_columns;
665 	if (0 != n_array_elements)
666 	{
667 		stride *= n_array_elements;
668 	}
669 
670 	return stride;
671 }
672 
673 /** Check if glsl support matrices for specific basic type
674  *
675  * @param type Basic type
676  *
677  * @return true if matrices of <type> are supported, false otherwise
678  **/
DoesTypeSupportMatrix(TYPES type)679 bool Type::DoesTypeSupportMatrix(TYPES type)
680 {
681 	bool result = false;
682 
683 	switch (type)
684 	{
685 	case Float:
686 	case Double:
687 		result = true;
688 		break;
689 	case Int:
690 	case Uint:
691 		result = false;
692 		break;
693 	default:
694 		TCU_FAIL("Invalid enum");
695 	}
696 
697 	return result;
698 }
699 
700 /** Creates instance of Type
701  *
702  * @param basic_type Select basic type of instance
703  * @param n_columns  Number of columns
704  * @param n_rows     Number of rows
705  *
706  * @return Type instance
707  **/
GetType(TYPES basic_type,glw::GLuint n_columns,glw::GLuint n_rows)708 Type Type::GetType(TYPES basic_type, glw::GLuint n_columns, glw::GLuint n_rows)
709 {
710 	Type type = { basic_type, n_columns, n_rows };
711 
712 	return type;
713 }
714 
715 /** Get Size of given type in bytes
716  *
717  * @param type
718  *
719  * @return Size of type
720  **/
GetTypeSize(TYPES type)721 GLuint Type::GetTypeSize(TYPES type)
722 {
723 	GLuint result = 0;
724 
725 	switch (type)
726 	{
727 	case Float:
728 		result = sizeof(GLfloat);
729 		break;
730 	case Double:
731 		result = sizeof(GLdouble);
732 		break;
733 	case Int:
734 		result = sizeof(GLint);
735 		break;
736 	case Uint:
737 		result = sizeof(GLuint);
738 		break;
739 	default:
740 		TCU_FAIL("Invalid enum");
741 	}
742 
743 	return result;
744 }
745 
746 /** Get GLenum representing given type
747  *
748  * @param type
749  *
750  * @return GLenum value
751  **/
GetTypeGLenum(TYPES type)752 GLenum Type::GetTypeGLenum(TYPES type)
753 {
754 	GLenum result = 0;
755 
756 	switch (type)
757 	{
758 	case Float:
759 		result = GL_FLOAT;
760 		break;
761 	case Double:
762 		result = GL_DOUBLE;
763 		break;
764 	case Int:
765 		result = GL_INT;
766 		break;
767 	case Uint:
768 		result = GL_UNSIGNED_INT;
769 		break;
770 	default:
771 		TCU_FAIL("Invalid enum");
772 	}
773 
774 	return result;
775 }
776 
777 /** Check if two types can share the same location, based on the underlying numerical type and bit width
778  *
779  * @param first   First type to compare
780  * @param second  Second type to compare
781  *
782  * @return true if the types can share the same location
783  **/
CanTypesShareLocation(TYPES first,TYPES second)784 bool Type::CanTypesShareLocation(TYPES first, TYPES second)
785 {
786 	if (first == second)
787 	{
788 		return true;
789 	}
790 
791 	if (Float == first || Float == second || Double == first || Double == second)
792 	{
793 		return false;
794 	}
795 
796 	return true;
797 }
798 
799 /** Get proper glUniformNdv routine for vectors with specified number of rows
800  *
801  * @param gl     GL functions
802  * @param n_rows Number of rows
803  *
804  * @return Function address
805  **/
getUniformNdv(const glw::Functions & gl,glw::GLuint n_rows)806 uniformNdv getUniformNdv(const glw::Functions& gl, glw::GLuint n_rows)
807 {
808 	uniformNdv result = 0;
809 
810 	switch (n_rows)
811 	{
812 	case 1:
813 		result = gl.uniform1dv;
814 		break;
815 	case 2:
816 		result = gl.uniform2dv;
817 		break;
818 	case 3:
819 		result = gl.uniform3dv;
820 		break;
821 	case 4:
822 		result = gl.uniform4dv;
823 		break;
824 	default:
825 		TCU_FAIL("Invalid number of rows");
826 	}
827 
828 	return result;
829 }
830 
831 /** Get proper glUniformNfv routine for vectors with specified number of rows
832  *
833  * @param gl     GL functions
834  * @param n_rows Number of rows
835  *
836  * @return Function address
837  **/
getUniformNfv(const glw::Functions & gl,glw::GLuint n_rows)838 uniformNfv getUniformNfv(const glw::Functions& gl, glw::GLuint n_rows)
839 {
840 	uniformNfv result = 0;
841 
842 	switch (n_rows)
843 	{
844 	case 1:
845 		result = gl.uniform1fv;
846 		break;
847 	case 2:
848 		result = gl.uniform2fv;
849 		break;
850 	case 3:
851 		result = gl.uniform3fv;
852 		break;
853 	case 4:
854 		result = gl.uniform4fv;
855 		break;
856 	default:
857 		TCU_FAIL("Invalid number of rows");
858 	}
859 
860 	return result;
861 }
862 
863 /** Get proper glUniformNiv routine for vectors with specified number of rows
864  *
865  * @param gl     GL functions
866  * @param n_rows Number of rows
867  *
868  * @return Function address
869  **/
getUniformNiv(const glw::Functions & gl,glw::GLuint n_rows)870 uniformNiv getUniformNiv(const glw::Functions& gl, glw::GLuint n_rows)
871 {
872 	uniformNiv result = 0;
873 
874 	switch (n_rows)
875 	{
876 	case 1:
877 		result = gl.uniform1iv;
878 		break;
879 	case 2:
880 		result = gl.uniform2iv;
881 		break;
882 	case 3:
883 		result = gl.uniform3iv;
884 		break;
885 	case 4:
886 		result = gl.uniform4iv;
887 		break;
888 	default:
889 		TCU_FAIL("Invalid number of rows");
890 	}
891 
892 	return result;
893 }
894 
895 /** Get proper glUniformNuiv routine for vectors with specified number of rows
896  *
897  * @param gl     GL functions
898  * @param n_rows Number of rows
899  *
900  * @return Function address
901  **/
getUniformNuiv(const glw::Functions & gl,glw::GLuint n_rows)902 uniformNuiv getUniformNuiv(const glw::Functions& gl, glw::GLuint n_rows)
903 {
904 	uniformNuiv result = 0;
905 
906 	switch (n_rows)
907 	{
908 	case 1:
909 		result = gl.uniform1uiv;
910 		break;
911 	case 2:
912 		result = gl.uniform2uiv;
913 		break;
914 	case 3:
915 		result = gl.uniform3uiv;
916 		break;
917 	case 4:
918 		result = gl.uniform4uiv;
919 		break;
920 	default:
921 		TCU_FAIL("Invalid number of rows");
922 	}
923 
924 	return result;
925 }
926 
927 /** Get proper glUniformMatrixNdv routine for matrix with specified number of columns and rows
928  *
929  * @param gl     GL functions
930  * @param n_rows Number of rows
931  *
932  * @return Function address
933  **/
getUniformMatrixNdv(const glw::Functions & gl,glw::GLuint n_columns,glw::GLuint n_rows)934 uniformMatrixNdv getUniformMatrixNdv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
935 {
936 	uniformMatrixNdv result = 0;
937 
938 	switch (n_columns)
939 	{
940 	case 2:
941 		switch (n_rows)
942 		{
943 		case 2:
944 			result = gl.uniformMatrix2dv;
945 			break;
946 		case 3:
947 			result = gl.uniformMatrix2x3dv;
948 			break;
949 		case 4:
950 			result = gl.uniformMatrix2x4dv;
951 			break;
952 		default:
953 			TCU_FAIL("Invalid number of rows");
954 		}
955 		break;
956 	case 3:
957 		switch (n_rows)
958 		{
959 		case 2:
960 			result = gl.uniformMatrix3x2dv;
961 			break;
962 		case 3:
963 			result = gl.uniformMatrix3dv;
964 			break;
965 		case 4:
966 			result = gl.uniformMatrix3x4dv;
967 			break;
968 		default:
969 			TCU_FAIL("Invalid number of rows");
970 		}
971 		break;
972 	case 4:
973 		switch (n_rows)
974 		{
975 		case 2:
976 			result = gl.uniformMatrix4x2dv;
977 			break;
978 		case 3:
979 			result = gl.uniformMatrix4x3dv;
980 			break;
981 		case 4:
982 			result = gl.uniformMatrix4dv;
983 			break;
984 		default:
985 			TCU_FAIL("Invalid number of rows");
986 		}
987 		break;
988 	default:
989 		TCU_FAIL("Invalid number of columns");
990 	}
991 
992 	return result;
993 }
994 
995 /** Get proper glUniformMatrixNfv routine for vectors with specified number of columns and rows
996  *
997  * @param gl     GL functions
998  * @param n_rows Number of rows
999  *
1000  * @return Function address
1001  **/
getUniformMatrixNfv(const glw::Functions & gl,glw::GLuint n_columns,glw::GLuint n_rows)1002 uniformMatrixNfv getUniformMatrixNfv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
1003 {
1004 	uniformMatrixNfv result = 0;
1005 
1006 	switch (n_columns)
1007 	{
1008 	case 2:
1009 		switch (n_rows)
1010 		{
1011 		case 2:
1012 			result = gl.uniformMatrix2fv;
1013 			break;
1014 		case 3:
1015 			result = gl.uniformMatrix2x3fv;
1016 			break;
1017 		case 4:
1018 			result = gl.uniformMatrix2x4fv;
1019 			break;
1020 		default:
1021 			TCU_FAIL("Invalid number of rows");
1022 		}
1023 		break;
1024 	case 3:
1025 		switch (n_rows)
1026 		{
1027 		case 2:
1028 			result = gl.uniformMatrix3x2fv;
1029 			break;
1030 		case 3:
1031 			result = gl.uniformMatrix3fv;
1032 			break;
1033 		case 4:
1034 			result = gl.uniformMatrix3x4fv;
1035 			break;
1036 		default:
1037 			TCU_FAIL("Invalid number of rows");
1038 		}
1039 		break;
1040 	case 4:
1041 		switch (n_rows)
1042 		{
1043 		case 2:
1044 			result = gl.uniformMatrix4x2fv;
1045 			break;
1046 		case 3:
1047 			result = gl.uniformMatrix4x3fv;
1048 			break;
1049 		case 4:
1050 			result = gl.uniformMatrix4fv;
1051 			break;
1052 		default:
1053 			TCU_FAIL("Invalid number of rows");
1054 		}
1055 		break;
1056 	default:
1057 		TCU_FAIL("Invalid number of columns");
1058 	}
1059 
1060 	return result;
1061 }
1062 
verifyVarying(Program & program,const std::string & parent_name,const Variable::Descriptor & desc,std::stringstream & stream,bool is_input)1063 bool verifyVarying(Program& program, const std::string& parent_name, const Variable::Descriptor& desc,
1064 				   std::stringstream& stream, bool is_input)
1065 {
1066 	GLint  component = 0;
1067 	GLuint index	 = 0;
1068 	GLenum interface = GL_PROGRAM_INPUT;
1069 	GLint  location  = 0;
1070 
1071 	if (false == is_input)
1072 	{
1073 		interface = GL_PROGRAM_OUTPUT;
1074 	}
1075 
1076 	const std::string& name = Utils::Variable::GetReference(parent_name, desc, Utils::Variable::BASIC, 0);
1077 
1078 	try
1079 	{
1080 		index = program.GetResourceIndex(name, interface);
1081 
1082 		program.GetResource(interface, index, GL_LOCATION, 1 /* size */, &location);
1083 		program.GetResource(interface, index, GL_LOCATION_COMPONENT, 1 /* size */, &component);
1084 	}
1085 	catch (std::exception& exc)
1086 	{
1087 		stream << "Failed to query program for varying: " << desc.m_name << ". Reason: " << exc.what() << "\n";
1088 
1089 		return false;
1090 	}
1091 
1092 	bool result = true;
1093 
1094 	if (location != desc.m_expected_location)
1095 	{
1096 		stream << "Attribute: " << desc.m_name << " - invalid location: " << location
1097 			   << " expected: " << desc.m_expected_location << std::endl;
1098 		result = false;
1099 	}
1100 	if (component != desc.m_expected_component)
1101 	{
1102 		stream << "Attribute: " << desc.m_name << " - invalid component: " << component
1103 			   << " expected: " << desc.m_expected_component << std::endl;
1104 		result = false;
1105 	}
1106 
1107 	return result;
1108 }
1109 
1110 /** Query program resource for given variable and verify that everything is as expected
1111  *
1112  * @param program  Program object
1113  * @param variable Variable object
1114  * @param stream   Stream that will be used to log any error
1115  * @param is_input Selects if varying is input or output
1116  *
1117  * @return true if verification is positive, false otherwise
1118  **/
checkVarying(Program & program,Shader::STAGES stage,const Variable & variable,std::stringstream & stream,bool is_input)1119 bool checkVarying(Program& program, Shader::STAGES stage, const Variable& variable, std::stringstream& stream, bool is_input)
1120 {
1121 	bool result = true;
1122 
1123 	if (variable.IsBlock())
1124 	{
1125 		Utils::Interface* interface = variable.m_descriptor.m_interface;
1126 		const size_t	  n_members = interface->m_members.size();
1127 
1128 		for (size_t i = 0; i < n_members; ++i)
1129 		{
1130 			const Variable::Descriptor& member = interface->m_members[i];
1131 			bool member_result				   = verifyVarying(program, interface->m_name, member, stream, is_input);
1132 
1133 			if (false == member_result)
1134 			{
1135 				result = false;
1136 			}
1137 		}
1138 	}
1139 	/*
1140 	 To query the the location of struct member by glGetProgramResource, we need pass the variable name "gs_fs_output[0].single",
1141 	 but in original implementation, the test pass the name "Data.single", which can't get any valid result.
1142 	 struct Data {
1143 	 dmat2 single;
1144 	 dmat2 array[1];
1145 	 };
1146 	 layout (location = 0) in Data gs_fs_output[1];
1147 	 */
1148 	else if (variable.IsStruct())
1149 	{
1150 		Utils::Interface* interface		 = variable.m_descriptor.m_interface;
1151 		const size_t	  n_members		 = interface->m_members.size();
1152 		std::string		  structVariable = variable.m_descriptor.m_name;
1153 
1154 		switch (Variable::GetFlavour(stage, is_input ? Variable::INPUT : Variable::OUTPUT))
1155 		{
1156 		case Variable::ARRAY:
1157 		case Variable::INDEXED_BY_INVOCATION_ID:
1158 			structVariable.append("[0]");
1159 			break;
1160 		default:
1161 			break;
1162 		}
1163 
1164 		// If struct variable is an array
1165 		if (0 != variable.m_descriptor.m_n_array_elements)
1166 		{
1167 			for (GLuint i = 0; i < variable.m_descriptor.m_n_array_elements; i++)
1168 			{
1169 				GLchar buffer[16];
1170 				sprintf(buffer, "%d", i);
1171 				structVariable.append("[");
1172 				structVariable.append(buffer);
1173 				structVariable.append("]");
1174 				for (size_t j = 0; j < n_members; ++j)
1175 				{
1176 					const Variable::Descriptor& member = interface->m_members[j];
1177 					bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1178 
1179 					if (false == member_result)
1180 					{
1181 						result = false;
1182 					}
1183 				}
1184 			}
1185 		}
1186 		else
1187 		{
1188 			for (GLuint i = 0; i < n_members; ++i)
1189 			{
1190 				const Variable::Descriptor& member = interface->m_members[i];
1191 				bool member_result				   = verifyVarying(program, structVariable, member, stream, is_input);
1192 
1193 				if (false == member_result)
1194 				{
1195 					result = false;
1196 				}
1197 			}
1198 		}
1199 	}
1200 	else
1201 	{
1202 		result = verifyVarying(program, "", variable.m_descriptor, stream, is_input);
1203 	}
1204 	return result;
1205 }
1206 
1207 /** Query program resource for given variable and verify that everything is as expected
1208  *
1209  * @param program  Program object
1210  * @param variable Variable object
1211  * @param stream   Stream that will be used to log any error
1212  *
1213  * @return true if verification is positive, false otherwise
1214  **/
checkUniform(Program & program,const Utils::Variable & variable,std::stringstream & stream)1215 bool checkUniform(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1216 {
1217 	bool result = true;
1218 
1219 	if (false == variable.IsBlock())
1220 	{
1221 		TCU_FAIL("Not implemented");
1222 	}
1223 	else
1224 	{
1225 		Utils::Interface* interface = variable.m_descriptor.m_interface;
1226 
1227 		size_t size = interface->m_members.size();
1228 
1229 		std::vector<GLuint>		 indices;
1230 		std::vector<const char*> names;
1231 		std::vector<std::string> names_str;
1232 		std::vector<GLint>		 offsets;
1233 
1234 		indices.resize(size);
1235 		names.resize(size);
1236 		names_str.resize(size);
1237 		offsets.resize(size);
1238 
1239 		for (size_t i = 0; i < size; ++i)
1240 		{
1241 			indices[i] = 0;
1242 			offsets[i] = 0;
1243 
1244 			const std::string& name =
1245 				Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1246 
1247 			if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1248 			{
1249 				const std::string& member_name = Utils::Variable::GetReference(
1250 					name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1251 
1252 				names_str[i] = member_name;
1253 			}
1254 			else
1255 			{
1256 				names_str[i] = name;
1257 			}
1258 
1259 			names[i] = names_str[i].c_str();
1260 		}
1261 
1262 		try
1263 		{
1264 			program.GetUniformIndices(static_cast<glw::GLsizei>(size), &names[0], &indices[0]);
1265 			program.GetActiveUniformsiv(static_cast<glw::GLsizei>(size), &indices[0], GL_UNIFORM_OFFSET, &offsets[0]);
1266 		}
1267 		catch (std::exception& exc)
1268 		{
1269 			stream << "Failed to query program for uniforms in block: " << variable.m_descriptor.m_name
1270 				   << ". Reason: " << exc.what() << "\n";
1271 
1272 			return false;
1273 		}
1274 
1275 		for (size_t i = 0; i < size; ++i)
1276 		{
1277 			Utils::Variable::Descriptor& desc = interface->m_members[i];
1278 
1279 			if (offsets[i] != (GLint)desc.m_offset)
1280 			{
1281 				stream << "Uniform: " << desc.m_name << " - invalid offset: " << offsets[i]
1282 					   << " expected: " << desc.m_offset << std::endl;
1283 				result = false;
1284 			}
1285 		}
1286 	}
1287 
1288 	return result;
1289 }
1290 
1291 /** Query program resource for given variable and verify that everything is as expected
1292  *
1293  * @param program  Program object
1294  * @param variable Variable object
1295  * @param stream   Stream that will be used to log any error
1296  *
1297  * @return true if verification is positive, false otherwise
1298  **/
checkSSB(Program & program,const Utils::Variable & variable,std::stringstream & stream)1299 bool checkSSB(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1300 {
1301 	bool result = true;
1302 
1303 	if (false == variable.IsBlock())
1304 	{
1305 		TCU_FAIL("Not implemented");
1306 	}
1307 	else
1308 	{
1309 		Utils::Interface* interface = variable.m_descriptor.m_interface;
1310 
1311 		size_t size = interface->m_members.size();
1312 
1313 		for (size_t i = 0; i < size; ++i)
1314 		{
1315 			GLuint		index	= 0;
1316 			std::string name_str = "";
1317 			GLint		offset   = 0;
1318 
1319 			const std::string& name =
1320 				Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1321 
1322 			if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1323 			{
1324 				const std::string& member_name = Utils::Variable::GetReference(
1325 					name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1326 
1327 				name_str = member_name;
1328 			}
1329 			else
1330 			{
1331 				name_str = name;
1332 			}
1333 
1334 			try
1335 			{
1336 				index = program.GetResourceIndex(name_str, GL_BUFFER_VARIABLE);
1337 
1338 				program.GetResource(GL_BUFFER_VARIABLE, index, GL_OFFSET, 1, &offset);
1339 			}
1340 			catch (std::exception& exc)
1341 			{
1342 				stream << "Failed to query program for buffer variable: " << variable.m_descriptor.m_name
1343 					   << ". Reason: " << exc.what() << "\n";
1344 
1345 				return false;
1346 			}
1347 
1348 			Utils::Variable::Descriptor& desc = interface->m_members[i];
1349 
1350 			if (offset != (GLint)desc.m_offset)
1351 			{
1352 				stream << "Uniform: " << desc.m_name << " - invalid offset: " << offset
1353 					   << " expected: " << desc.m_offset << std::endl;
1354 				result = false;
1355 			}
1356 		}
1357 	}
1358 
1359 	return result;
1360 }
1361 
1362 /** Query program resources at given stage and verifies results
1363  *
1364  * @param program           Program object
1365  * @param program_interface Definition of program interface
1366  * @param stage             Stage to be verified
1367  * @param check_inputs      Select if inputs should be verified
1368  * @param check_outputs     Select if output should be verified
1369  * @param check_uniforms    Select if uniforms should be verified
1370  * @param check_ssbs        Select if buffers should be verified
1371  * @param stream            Stream that will be used to log any error
1372  *
1373  * @return true if verification is positive, false otherwise
1374  **/
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)1375 bool checkProgramStage(Program& program, const ProgramInterface& program_interface, Utils::Shader::STAGES stage,
1376 					   bool check_inputs, bool check_outputs, bool check_uniforms, bool check_ssbs,
1377 					   std::stringstream& stream)
1378 {
1379 	typedef Variable::PtrVector::const_iterator const_iterator;
1380 
1381 	const ShaderInterface& interface = program_interface.GetShaderInterface(stage);
1382 
1383 	bool result = true;
1384 
1385 	/* Inputs */
1386 	if (true == check_inputs)
1387 	{
1388 		const Variable::PtrVector& inputs = interface.m_inputs;
1389 
1390 		for (const_iterator it = inputs.begin(); it != inputs.end(); ++it)
1391 		{
1392 			if (false == checkVarying(program, stage, **it, stream, true))
1393 			{
1394 				result = false;
1395 			}
1396 		}
1397 	}
1398 
1399 	/* Outputs */
1400 	if (true == check_outputs)
1401 	{
1402 		const Variable::PtrVector& outputs = interface.m_outputs;
1403 
1404 		for (const_iterator it = outputs.begin(); it != outputs.end(); ++it)
1405 		{
1406 			if (false == checkVarying(program, stage, **it, stream, false))
1407 			{
1408 				result = false;
1409 			}
1410 		}
1411 	}
1412 
1413 	/* Uniforms */
1414 	if (true == check_uniforms)
1415 	{
1416 		const Variable::PtrVector& uniforms = interface.m_uniforms;
1417 
1418 		for (const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
1419 		{
1420 			if (false == checkUniform(program, **it, stream))
1421 			{
1422 				result = false;
1423 			}
1424 		}
1425 	}
1426 
1427 	/* SSBs */
1428 	if (true == check_ssbs)
1429 	{
1430 		const Variable::PtrVector& ssbs = interface.m_ssb_blocks;
1431 
1432 		for (const_iterator it = ssbs.begin(); it != ssbs.end(); ++it)
1433 		{
1434 			if (false == checkSSB(program, **it, stream))
1435 			{
1436 				result = false;
1437 			}
1438 		}
1439 	}
1440 
1441 	return result;
1442 }
1443 
1444 /** Query resources of monolithic compute program and verifies results
1445  *
1446  * @param program           Program object
1447  * @param program_interface Definition of program interface
1448  * @param stream            Stream that will be used to log any error
1449  *
1450  * @return true if verification is positive, false otherwise
1451  **/
checkMonolithicComputeProgramInterface(Program & program,const ProgramInterface & program_interface,std::stringstream & stream)1452 bool checkMonolithicComputeProgramInterface(Program& program, const ProgramInterface& program_interface,
1453 											std::stringstream& stream)
1454 {
1455 	bool result = true;
1456 
1457 	if (false == checkProgramStage(program, program_interface, Shader::COMPUTE, false, false, true, true, stream))
1458 	{
1459 		result = false;
1460 	}
1461 
1462 	/* Done */
1463 	return result;
1464 }
1465 
1466 /** Query resources of monolithic draw program and verifies results
1467  *
1468  * @param program           Program object
1469  * @param program_interface Definition of program interface
1470  * @param stream            Stream that will be used to log any error
1471  *
1472  * @return true if verification is positive, false otherwise
1473  **/
checkMonolithicDrawProgramInterface(Program & program,const ProgramInterface & program_interface,std::stringstream & stream)1474 bool checkMonolithicDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1475 										 std::stringstream& stream)
1476 {
1477 	bool result = true;
1478 
1479 	if (false == checkProgramStage(program, program_interface, Shader::VERTEX, true, false, true, true, stream))
1480 	{
1481 		result = false;
1482 	}
1483 
1484 	/* Done */
1485 	return result;
1486 }
1487 
1488 /** Query resources of separable draw program and verifies results
1489  *
1490  * @param program           Program object
1491  * @param program_interface Definition of program interface
1492  * @param stream            Stream that will be used to log any error
1493  *
1494  * @return true if verification is positive, false otherwise
1495  **/
checkSeparableDrawProgramInterface(Program & program,const ProgramInterface & program_interface,Utils::Shader::STAGES stage,std::stringstream & stream)1496 bool checkSeparableDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1497 										Utils::Shader::STAGES stage, std::stringstream& stream)
1498 {
1499 	bool result = true;
1500 
1501 	if (false == checkProgramStage(program, program_interface, stage, true, true, true, true, stream))
1502 	{
1503 		result = false;
1504 	}
1505 
1506 	/* Done */
1507 	return result;
1508 }
1509 
1510 /** Check if extension is supported
1511  *
1512  * @param context        Test context
1513  * @param extension_name Name of extension
1514  *
1515  * @return true if extension is supported, false otherwise
1516  **/
isExtensionSupported(deqp::Context & context,const GLchar * extension_name)1517 bool isExtensionSupported(deqp::Context& context, const GLchar* extension_name)
1518 {
1519 	const std::vector<std::string>& extensions = context.getContextInfo().getExtensions();
1520 
1521 	if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end())
1522 	{
1523 		return false;
1524 	}
1525 
1526 	return true;
1527 }
1528 
1529 /** Check if GL context meets version requirements
1530  *
1531  * @param gl             Functions
1532  * @param required_major Minimum required MAJOR_VERSION
1533  * @param required_minor Minimum required MINOR_VERSION
1534  *
1535  * @return true if GL context version is at least as requested, false otherwise
1536  **/
isGLVersionAtLeast(const Functions & gl,GLint required_major,GLint required_minor)1537 bool isGLVersionAtLeast(const Functions& gl, GLint required_major, GLint required_minor)
1538 {
1539 	glw::GLint major = 0;
1540 	glw::GLint minor = 0;
1541 
1542 	gl.getIntegerv(GL_MAJOR_VERSION, &major);
1543 	gl.getIntegerv(GL_MINOR_VERSION, &minor);
1544 
1545 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1546 
1547 	if (major > required_major)
1548 	{
1549 		/* Major is higher than required one */
1550 		return true;
1551 	}
1552 	else if (major == required_major)
1553 	{
1554 		if (minor >= required_minor)
1555 		{
1556 			/* Major is equal to required one */
1557 			/* Minor is higher than or equal to required one */
1558 			return true;
1559 		}
1560 		else
1561 		{
1562 			/* Major is equal to required one */
1563 			/* Minor is lower than required one */
1564 			return false;
1565 		}
1566 	}
1567 	else
1568 	{
1569 		/* Major is lower than required one */
1570 		return false;
1571 	}
1572 }
1573 
1574 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
1575  *
1576  * @param token           Token string
1577  * @param search_position Position at which find will start, it is updated to position at which replaced text ends
1578  * @param text            String that will be used as replacement for <token>
1579  * @param string          String to work on
1580  **/
replaceToken(const GLchar * token,size_t & search_position,const GLchar * text,std::string & string)1581 void replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string)
1582 {
1583 	const size_t text_length	= strlen(text);
1584 	const size_t token_length   = strlen(token);
1585 	const size_t token_position = string.find(token, search_position);
1586 
1587 #if DEBUG_REPLACE_TOKEN
1588 	if (std::string::npos == token_position)
1589 	{
1590 		string.append("\n\nInvalid token: ");
1591 		string.append(token);
1592 
1593 		TCU_FAIL(string.c_str());
1594 	}
1595 #endif /* DEBUG_REPLACE_TOKEN */
1596 
1597 	string.replace(token_position, token_length, text, text_length);
1598 
1599 	search_position = token_position + text_length;
1600 }
1601 
1602 /** Replace all occurances of <token> with <text> in <string>
1603  *
1604  * @param token           Token string
1605  * @param text            String that will be used as replacement for <token>
1606  * @param string          String to work on
1607  **/
replaceAllTokens(const GLchar * token,const GLchar * text,std::string & string)1608 void replaceAllTokens(const GLchar* token, const GLchar* text, std::string& string)
1609 {
1610 	const size_t text_length  = strlen(text);
1611 	const size_t token_length = strlen(token);
1612 
1613 	size_t search_position = 0;
1614 
1615 	while (1)
1616 	{
1617 		const size_t token_position = string.find(token, search_position);
1618 
1619 		if (std::string::npos == token_position)
1620 		{
1621 			break;
1622 		}
1623 
1624 		search_position = token_position + text_length;
1625 
1626 		string.replace(token_position, token_length, text, text_length);
1627 	}
1628 }
1629 
1630 /** Rounds up the value to the next power of 2.
1631  * This routine does not work for 0, see the url for explanations.
1632  *
1633  * @param value Starting point
1634  *
1635  * @return Calculated value
1636  **/
roundUpToPowerOf2(glw::GLuint value)1637 glw::GLuint roundUpToPowerOf2(glw::GLuint value)
1638 {
1639 	/* Taken from: graphics.stanford.edu/~seander/bithacks.html */
1640 	--value;
1641 
1642 	value |= value >> 1;
1643 	value |= value >> 2;
1644 	value |= value >> 4;
1645 	value |= value >> 8;
1646 	value |= value >> 16;
1647 
1648 	++value;
1649 
1650 	return value;
1651 }
1652 
1653 /** Insert elements of list into string.
1654  * List in string is represented either by token "LIST" or "SEPARATORLIST".
1655  * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>.
1656  * LIST is replaced with <element>SEPARATORLIST
1657  *
1658  * @param element         Element to be inserted
1659  * @param separator       Separator inserted between elements
1660  * @param search_position Position in string, where search for list should start
1661  * @param string          String
1662  **/
insertElementOfList(const GLchar * element,const GLchar * separator,size_t & search_position,std::string & string)1663 void insertElementOfList(const GLchar* element, const GLchar* separator, size_t& search_position, std::string& string)
1664 {
1665 	static const char* list		= g_list;
1666 	static const char* sep_list = "SEPARATORLIST";
1667 
1668 	/* Try to get "list" positions */
1669 	const size_t list_position	 = string.find(list, search_position);
1670 	const size_t sep_list_position = string.find(sep_list, search_position);
1671 
1672 	/* There is no list in string */
1673 	if (std::string::npos == list_position)
1674 	{
1675 		return;
1676 	}
1677 
1678 	if (9 /* strlen(SEPARATOR) */ == list_position - sep_list_position)
1679 	{
1680 		replaceToken("SEPARATOR", search_position, separator, string);
1681 	}
1682 
1683 	/* Save search_position */
1684 	const size_t start_position = search_position;
1685 
1686 	/* Prepare new element */
1687 	replaceToken("LIST", search_position, "ELEMENTSEPARATORLIST", string);
1688 
1689 	/* Restore search_position */
1690 	search_position = start_position;
1691 
1692 	/* Replace element and separator */
1693 	replaceToken("ELEMENT", search_position, element, string);
1694 }
1695 
1696 /** Close list in string.
1697  * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>
1698  * LIST is replaced with ""
1699  *
1700  * @param separator       Separator inserted between elements
1701  * @param search_position Position in string, where search for list should start
1702  * @param string          String
1703  **/
endList(const glw::GLchar * separator,size_t & search_position,std::string & string)1704 void endList(const glw::GLchar* separator, size_t& search_position, std::string& string)
1705 {
1706 	const size_t sep_position = string.find("SEPARATOR", search_position);
1707 	if (std::string::npos != sep_position)
1708 	{
1709 		replaceToken("SEPARATOR", search_position, separator, string);
1710 	}
1711 
1712 	replaceToken("LIST", search_position, "", string);
1713 }
1714 
1715 /* Buffer constants */
1716 const GLuint Buffer::m_invalid_id = -1;
1717 
1718 /** Constructor.
1719  *
1720  * @param context CTS context.
1721  **/
Buffer(deqp::Context & context)1722 Buffer::Buffer(deqp::Context& context) : m_id(m_invalid_id), m_buffer(Array), m_context(context)
1723 {
1724 }
1725 
1726 /** Destructor
1727  *
1728  **/
~Buffer()1729 Buffer::~Buffer()
1730 {
1731 	Release();
1732 }
1733 
1734 /** Initialize buffer instance
1735  *
1736  * @param buffer Buffer type
1737  * @param usage  Buffer usage enum
1738  * @param size   <size> parameter
1739  * @param data   <data> parameter
1740  **/
Init(BUFFERS buffer,USAGE usage,GLsizeiptr size,GLvoid * data)1741 void Buffer::Init(BUFFERS buffer, USAGE usage, GLsizeiptr size, GLvoid* data)
1742 {
1743 	/* Delete previous buffer instance */
1744 	Release();
1745 
1746 	m_buffer = buffer;
1747 
1748 	const Functions& gl = m_context.getRenderContext().getFunctions();
1749 
1750 	Generate(gl, m_id);
1751 	Bind(gl, m_id, m_buffer);
1752 	Data(gl, m_buffer, usage, size, data);
1753 }
1754 
1755 /** Release buffer instance
1756  *
1757  **/
Release()1758 void Buffer::Release()
1759 {
1760 	if (m_invalid_id != m_id)
1761 	{
1762 		const Functions& gl = m_context.getRenderContext().getFunctions();
1763 
1764 		gl.deleteBuffers(1, &m_id);
1765 		m_id = m_invalid_id;
1766 	}
1767 }
1768 
1769 /** Binds buffer to its target
1770  *
1771  **/
Bind() const1772 void Buffer::Bind() const
1773 {
1774 	const Functions& gl = m_context.getRenderContext().getFunctions();
1775 
1776 	Bind(gl, m_id, m_buffer);
1777 }
1778 
1779 /** Binds indexed buffer
1780  *
1781  * @param index <index> parameter
1782  **/
BindBase(GLuint index) const1783 void Buffer::BindBase(GLuint index) const
1784 {
1785 	const Functions& gl = m_context.getRenderContext().getFunctions();
1786 
1787 	BindBase(gl, m_id, m_buffer, index);
1788 }
1789 
1790 /** Binds range of buffer
1791  *
1792  * @param index  <index> parameter
1793  * @param offset <offset> parameter
1794  * @param size   <size> parameter
1795  **/
BindRange(GLuint index,GLintptr offset,GLsizeiptr size) const1796 void Buffer::BindRange(GLuint index, GLintptr offset, GLsizeiptr size) const
1797 {
1798 	const Functions& gl = m_context.getRenderContext().getFunctions();
1799 
1800 	BindRange(gl, m_id, m_buffer, index, offset, size);
1801 }
1802 
1803 /** Allocate memory for buffer and sends initial content
1804  *
1805  * @param usage  Buffer usage enum
1806  * @param size   <size> parameter
1807  * @param data   <data> parameter
1808  **/
Data(USAGE usage,glw::GLsizeiptr size,glw::GLvoid * data)1809 void Buffer::Data(USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1810 {
1811 	const Functions& gl = m_context.getRenderContext().getFunctions();
1812 
1813 	Data(gl, m_buffer, usage, size, data);
1814 }
1815 
1816 /** Maps contents of buffer into CPU space
1817  *
1818  * @param access Requested access
1819  *
1820  * @return Pointer to memory region available for CPU
1821  **/
Map(ACCESS access)1822 GLvoid* Buffer::Map(ACCESS access)
1823 {
1824 	const Functions& gl = m_context.getRenderContext().getFunctions();
1825 
1826 	return Map(gl, m_buffer, access);
1827 }
1828 
1829 /** Allocate memory for buffer and sends initial content
1830  *
1831  * @param offset Offset in buffer
1832  * @param size   <size> parameter
1833  * @param data   <data> parameter
1834  **/
SubData(glw::GLintptr offset,glw::GLsizeiptr size,glw::GLvoid * data)1835 void Buffer::SubData(glw::GLintptr offset, glw::GLsizeiptr size, glw::GLvoid* data)
1836 {
1837 	const Functions& gl = m_context.getRenderContext().getFunctions();
1838 
1839 	SubData(gl, m_buffer, offset, size, data);
1840 }
1841 
1842 /** Maps contents of buffer into CPU space
1843  **/
UnMap()1844 void Buffer::UnMap()
1845 {
1846 	const Functions& gl = m_context.getRenderContext().getFunctions();
1847 
1848 	return UnMap(gl, m_buffer);
1849 }
1850 
1851 /** Bind buffer to given target
1852  *
1853  * @param gl     GL functions
1854  * @param id     Id of buffer
1855  * @param buffer Buffer enum
1856  **/
Bind(const Functions & gl,GLuint id,BUFFERS buffer)1857 void Buffer::Bind(const Functions& gl, GLuint id, BUFFERS buffer)
1858 {
1859 	GLenum target = GetBufferGLenum(buffer);
1860 
1861 	gl.bindBuffer(target, id);
1862 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
1863 }
1864 
1865 /** Binds indexed buffer
1866  *
1867  * @param gl     GL functions
1868  * @param id     Id of buffer
1869  * @param buffer Buffer enum
1870  * @param index  <index> parameter
1871  **/
BindBase(const Functions & gl,GLuint id,BUFFERS buffer,GLuint index)1872 void Buffer::BindBase(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index)
1873 {
1874 	GLenum target = GetBufferGLenum(buffer);
1875 
1876 	gl.bindBufferBase(target, index, id);
1877 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
1878 }
1879 
1880 /** Binds buffer range
1881  *
1882  * @param gl     GL functions
1883  * @param id     Id of buffer
1884  * @param buffer Buffer enum
1885  * @param index  <index> parameter
1886  * @param offset <offset> parameter
1887  * @param size   <size> parameter
1888  **/
BindRange(const Functions & gl,GLuint id,BUFFERS buffer,GLuint index,GLintptr offset,GLsizeiptr size)1889 void Buffer::BindRange(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1890 {
1891 	GLenum target = GetBufferGLenum(buffer);
1892 
1893 	gl.bindBufferRange(target, index, id, offset, size);
1894 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
1895 }
1896 
1897 /** Allocate memory for buffer and sends initial content
1898  *
1899  * @param gl     GL functions
1900  * @param buffer Buffer enum
1901  * @param usage  Buffer usage enum
1902  * @param size   <size> parameter
1903  * @param data   <data> parameter
1904  **/
Data(const glw::Functions & gl,BUFFERS buffer,USAGE usage,glw::GLsizeiptr size,glw::GLvoid * data)1905 void Buffer::Data(const glw::Functions& gl, BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1906 {
1907 	GLenum target   = GetBufferGLenum(buffer);
1908 	GLenum gl_usage = GetUsageGLenum(usage);
1909 
1910 	gl.bufferData(target, size, data, gl_usage);
1911 	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
1912 }
1913 
1914 /** Allocate memory for buffer and sends initial content
1915  *
1916  * @param gl     GL functions
1917  * @param buffer Buffer enum
1918  * @param offset Offset in buffer
1919  * @param size   <size> parameter
1920  * @param data   <data> parameter
1921  **/
SubData(const glw::Functions & gl,BUFFERS buffer,glw::GLintptr offset,glw::GLsizeiptr size,glw::GLvoid * data)1922 void Buffer::SubData(const glw::Functions& gl, BUFFERS buffer, glw::GLintptr offset, glw::GLsizeiptr size,
1923 					 glw::GLvoid* data)
1924 {
1925 	GLenum target = GetBufferGLenum(buffer);
1926 
1927 	gl.bufferSubData(target, offset, size, data);
1928 	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData");
1929 }
1930 
1931 /** Generate buffer
1932  *
1933  * @param gl     GL functions
1934  * @param out_id Id of buffer
1935  **/
Generate(const Functions & gl,GLuint & out_id)1936 void Buffer::Generate(const Functions& gl, GLuint& out_id)
1937 {
1938 	GLuint id = m_invalid_id;
1939 
1940 	gl.genBuffers(1, &id);
1941 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
1942 
1943 	if (m_invalid_id == id)
1944 	{
1945 		TCU_FAIL("Got invalid id");
1946 	}
1947 
1948 	out_id = id;
1949 }
1950 
1951 /** Maps buffer content
1952  *
1953  * @param gl     GL functions
1954  * @param buffer Buffer enum
1955  * @param access Access rights for mapped region
1956  *
1957  * @return Mapped memory
1958  **/
Map(const Functions & gl,BUFFERS buffer,ACCESS access)1959 void* Buffer::Map(const Functions& gl, BUFFERS buffer, ACCESS access)
1960 {
1961 	GLenum target	= GetBufferGLenum(buffer);
1962 	GLenum gl_access = GetAccessGLenum(access);
1963 
1964 	void* result = gl.mapBuffer(target, gl_access);
1965 	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
1966 
1967 	return result;
1968 }
1969 
1970 /** Unmaps buffer
1971  *
1972  **/
UnMap(const Functions & gl,BUFFERS buffer)1973 void Buffer::UnMap(const Functions& gl, BUFFERS buffer)
1974 {
1975 	GLenum target = GetBufferGLenum(buffer);
1976 
1977 	gl.unmapBuffer(target);
1978 	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
1979 }
1980 
1981 /** Return GLenum representation of requested access
1982  *
1983  * @param access Requested access
1984  *
1985  * @return GLenum value
1986  **/
GetAccessGLenum(ACCESS access)1987 GLenum Buffer::GetAccessGLenum(ACCESS access)
1988 {
1989 	GLenum result = 0;
1990 
1991 	switch (access)
1992 	{
1993 	case ReadOnly:
1994 		result = GL_READ_ONLY;
1995 		break;
1996 	case WriteOnly:
1997 		result = GL_WRITE_ONLY;
1998 		break;
1999 	case ReadWrite:
2000 		result = GL_READ_WRITE;
2001 		break;
2002 	default:
2003 		TCU_FAIL("Invalid enum");
2004 	}
2005 
2006 	return result;
2007 }
2008 
2009 /** Return GLenum representation of requested buffer type
2010  *
2011  * @param buffer Requested buffer type
2012  *
2013  * @return GLenum value
2014  **/
GetBufferGLenum(BUFFERS buffer)2015 GLenum Buffer::GetBufferGLenum(BUFFERS buffer)
2016 {
2017 	GLenum result = 0;
2018 
2019 	switch (buffer)
2020 	{
2021 	case Array:
2022 		result = GL_ARRAY_BUFFER;
2023 		break;
2024 	case Element:
2025 		result = GL_ELEMENT_ARRAY_BUFFER;
2026 		break;
2027 	case Shader_Storage:
2028 		result = GL_SHADER_STORAGE_BUFFER;
2029 		break;
2030 	case Texture:
2031 		result = GL_TEXTURE_BUFFER;
2032 		break;
2033 	case Transform_feedback:
2034 		result = GL_TRANSFORM_FEEDBACK_BUFFER;
2035 		break;
2036 	case Uniform:
2037 		result = GL_UNIFORM_BUFFER;
2038 		break;
2039 	default:
2040 		TCU_FAIL("Invalid enum");
2041 	}
2042 
2043 	return result;
2044 }
2045 
2046 /** Return GLenum representation of requested usage
2047  *
2048  * @param usage Requested usage
2049  *
2050  * @return GLenum value
2051  **/
GetUsageGLenum(USAGE usage)2052 GLenum Buffer::GetUsageGLenum(USAGE usage)
2053 {
2054 	GLenum result = 0;
2055 
2056 	switch (usage)
2057 	{
2058 	case DynamicCopy:
2059 		result = GL_DYNAMIC_COPY;
2060 		break;
2061 	case DynamicDraw:
2062 		result = GL_DYNAMIC_DRAW;
2063 		break;
2064 	case DynamicRead:
2065 		result = GL_DYNAMIC_READ;
2066 		break;
2067 	case StaticCopy:
2068 		result = GL_STATIC_COPY;
2069 		break;
2070 	case StaticDraw:
2071 		result = GL_STATIC_DRAW;
2072 		break;
2073 	case StaticRead:
2074 		result = GL_STATIC_READ;
2075 		break;
2076 	case StreamCopy:
2077 		result = GL_STREAM_COPY;
2078 		break;
2079 	case StreamDraw:
2080 		result = GL_STREAM_DRAW;
2081 		break;
2082 	case StreamRead:
2083 		result = GL_STREAM_READ;
2084 		break;
2085 	default:
2086 		TCU_FAIL("Invalid enum");
2087 	}
2088 
2089 	return result;
2090 }
2091 
2092 /** Returns name of buffer target
2093  *
2094  * @param buffer Target enum
2095  *
2096  * @return Name of target
2097  **/
GetBufferName(BUFFERS buffer)2098 const GLchar* Buffer::GetBufferName(BUFFERS buffer)
2099 {
2100 	const GLchar* name = 0;
2101 
2102 	switch (buffer)
2103 	{
2104 	case Array:
2105 		name = "Array";
2106 		break;
2107 	case Element:
2108 		name = "Element";
2109 		break;
2110 	case Shader_Storage:
2111 		name = "Shader_Storage";
2112 		break;
2113 	case Texture:
2114 		name = "Texture";
2115 		break;
2116 	case Transform_feedback:
2117 		name = "Transform_feedback";
2118 		break;
2119 	case Uniform:
2120 		name = "Uniform";
2121 		break;
2122 	default:
2123 		TCU_FAIL("Invalid enum");
2124 	}
2125 
2126 	return name;
2127 }
2128 
2129 /* Framebuffer constants */
2130 const GLuint Framebuffer::m_invalid_id = -1;
2131 
2132 /** Constructor
2133  *
2134  * @param context CTS context
2135  **/
Framebuffer(deqp::Context & context)2136 Framebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2137 {
2138 	/* Nothing to be done here */
2139 }
2140 
2141 /** Destructor
2142  *
2143  **/
~Framebuffer()2144 Framebuffer::~Framebuffer()
2145 {
2146 	Release();
2147 }
2148 
2149 /** Initialize framebuffer instance
2150  *
2151  **/
Init()2152 void Framebuffer::Init()
2153 {
2154 	/* Delete previous instance */
2155 	Release();
2156 
2157 	const Functions& gl = m_context.getRenderContext().getFunctions();
2158 
2159 	Generate(gl, m_id);
2160 }
2161 
2162 /** Release framebuffer instance
2163  *
2164  **/
Release()2165 void Framebuffer::Release()
2166 {
2167 	if (m_invalid_id != m_id)
2168 	{
2169 		const Functions& gl = m_context.getRenderContext().getFunctions();
2170 
2171 		gl.deleteFramebuffers(1, &m_id);
2172 		m_id = m_invalid_id;
2173 	}
2174 }
2175 
2176 /** Attach texture to specified attachment
2177  *
2178  * @param attachment Attachment
2179  * @param texture_id Texture id
2180  * @param width      Texture width
2181  * @param height     Texture height
2182  **/
AttachTexture(GLenum attachment,GLuint texture_id,GLuint width,GLuint height)2183 void Framebuffer::AttachTexture(GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2184 {
2185 	const Functions& gl = m_context.getRenderContext().getFunctions();
2186 
2187 	AttachTexture(gl, attachment, texture_id, width, height);
2188 }
2189 
2190 /** Binds framebuffer to DRAW_FRAMEBUFFER
2191  *
2192  **/
Bind()2193 void Framebuffer::Bind()
2194 {
2195 	const Functions& gl = m_context.getRenderContext().getFunctions();
2196 
2197 	Bind(gl, m_id);
2198 }
2199 
2200 /** Clear framebuffer
2201  *
2202  * @param mask <mask> parameter of glClear. Decides which shall be cleared
2203  **/
Clear(GLenum mask)2204 void Framebuffer::Clear(GLenum mask)
2205 {
2206 	const Functions& gl = m_context.getRenderContext().getFunctions();
2207 
2208 	Clear(gl, mask);
2209 }
2210 
2211 /** Specifies clear color
2212  *
2213  * @param red   Red channel
2214  * @param green Green channel
2215  * @param blue  Blue channel
2216  * @param alpha Alpha channel
2217  **/
ClearColor(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)2218 void Framebuffer::ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2219 {
2220 	const Functions& gl = m_context.getRenderContext().getFunctions();
2221 
2222 	ClearColor(gl, red, green, blue, alpha);
2223 }
2224 
2225 /** Attach texture to specified attachment
2226  *
2227  * @param gl         GL functions
2228  * @param attachment Attachment
2229  * @param texture_id Texture id
2230  * @param width      Texture width
2231  * @param height     Texture height
2232  **/
AttachTexture(const Functions & gl,GLenum attachment,GLuint texture_id,GLuint width,GLuint height)2233 void Framebuffer::AttachTexture(const Functions& gl, GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2234 {
2235 	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
2236 	GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
2237 
2238 	gl.viewport(0 /* x */, 0 /* y */, width, height);
2239 	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2240 }
2241 
2242 /** Binds framebuffer to DRAW_FRAMEBUFFER
2243  *
2244  * @param gl GL functions
2245  * @param id ID of framebuffer
2246  **/
Bind(const Functions & gl,GLuint id)2247 void Framebuffer::Bind(const Functions& gl, GLuint id)
2248 {
2249 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
2250 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2251 }
2252 
2253 /** Clear framebuffer
2254  *
2255  * @param gl   GL functions
2256  * @param mask <mask> parameter of glClear. Decides which shall be cleared
2257  **/
Clear(const Functions & gl,GLenum mask)2258 void Framebuffer::Clear(const Functions& gl, GLenum mask)
2259 {
2260 	gl.clear(mask);
2261 	GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2262 }
2263 
2264 /** Specifies clear color
2265  *
2266  * @param gl    GL functions
2267  * @param red   Red channel
2268  * @param green Green channel
2269  * @param blue  Blue channel
2270  * @param alpha Alpha channel
2271  **/
ClearColor(const Functions & gl,GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)2272 void Framebuffer::ClearColor(const Functions& gl, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2273 {
2274 	gl.clearColor(red, green, blue, alpha);
2275 	GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
2276 }
2277 
2278 /** Generate framebuffer
2279  *
2280  **/
Generate(const Functions & gl,GLuint & out_id)2281 void Framebuffer::Generate(const Functions& gl, GLuint& out_id)
2282 {
2283 	GLuint id = m_invalid_id;
2284 
2285 	gl.genFramebuffers(1, &id);
2286 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
2287 
2288 	if (m_invalid_id == id)
2289 	{
2290 		TCU_FAIL("Invalid id");
2291 	}
2292 
2293 	out_id = id;
2294 }
2295 
2296 /* Shader's constants */
2297 const GLuint Shader::m_invalid_id = 0;
2298 
2299 /** Constructor.
2300  *
2301  * @param context CTS context.
2302  **/
Shader(deqp::Context & context)2303 Shader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2304 {
2305 	/* Nothing to be done here */
2306 }
2307 
2308 /** Destructor
2309  *
2310  **/
~Shader()2311 Shader::~Shader()
2312 {
2313 	Release();
2314 }
2315 
2316 /** Initialize shader instance
2317  *
2318  * @param stage  Shader stage
2319  * @param source Source code
2320  **/
Init(STAGES stage,const std::string & source)2321 void Shader::Init(STAGES stage, const std::string& source)
2322 {
2323 	if (true == source.empty())
2324 	{
2325 		/* No source == no shader */
2326 		return;
2327 	}
2328 
2329 	/* Delete any previous shader */
2330 	Release();
2331 
2332 	/* Create, set source and compile */
2333 	const Functions& gl = m_context.getRenderContext().getFunctions();
2334 
2335 	Create(gl, stage, m_id);
2336 	Source(gl, m_id, source);
2337 
2338 	try
2339 	{
2340 		Compile(gl, m_id);
2341 	}
2342 	catch (const CompilationException& exc)
2343 	{
2344 		throw InvalidSourceException(exc.what(), source, stage);
2345 	}
2346 }
2347 
2348 /** Release shader instance
2349  *
2350  **/
Release()2351 void Shader::Release()
2352 {
2353 	if (m_invalid_id != m_id)
2354 	{
2355 		const Functions& gl = m_context.getRenderContext().getFunctions();
2356 
2357 		gl.deleteShader(m_id);
2358 		m_id = m_invalid_id;
2359 	}
2360 }
2361 
2362 /** Compile shader
2363  *
2364  * @param gl GL functions
2365  * @param id Shader id
2366  **/
Compile(const Functions & gl,GLuint id)2367 void Shader::Compile(const Functions& gl, GLuint id)
2368 {
2369 	GLint status = GL_FALSE;
2370 
2371 	/* Compile */
2372 	gl.compileShader(id);
2373 	GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2374 
2375 	/* Get compilation status */
2376 	gl.getShaderiv(id, GL_COMPILE_STATUS, &status);
2377 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2378 
2379 	/* Log compilation error */
2380 	if (GL_TRUE != status)
2381 	{
2382 		glw::GLint  length = 0;
2383 		std::string message;
2384 
2385 		/* Error log length */
2386 		gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length);
2387 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2388 
2389 		/* Prepare storage */
2390 		message.resize(length, 0);
2391 
2392 		/* Get error log */
2393 		gl.getShaderInfoLog(id, length, 0, &message[0]);
2394 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2395 
2396 		throw CompilationException(message.c_str());
2397 	}
2398 }
2399 
2400 /** Create shader
2401  *
2402  * @param gl     GL functions
2403  * @param stage  Shader stage
2404  * @param out_id Shader id
2405  **/
Create(const Functions & gl,STAGES stage,GLuint & out_id)2406 void Shader::Create(const Functions& gl, STAGES stage, GLuint& out_id)
2407 {
2408 	const GLenum shaderType = GetShaderStageGLenum(stage);
2409 	const GLuint id			= gl.createShader(shaderType);
2410 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2411 
2412 	if (m_invalid_id == id)
2413 	{
2414 		TCU_FAIL("Failed to create shader");
2415 	}
2416 
2417 	out_id = id;
2418 }
2419 
2420 /** Set shader's source code
2421  *
2422  * @param gl     GL functions
2423  * @param id     Shader id
2424  * @param source Shader source code
2425  **/
Source(const Functions & gl,GLuint id,const std::string & source)2426 void Shader::Source(const Functions& gl, GLuint id, const std::string& source)
2427 {
2428 	const GLchar* code = source.c_str();
2429 
2430 	gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */);
2431 	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2432 }
2433 
2434 /** Get GLenum repesenting shader stage
2435  *
2436  * @param stage Shader stage
2437  *
2438  * @return GLenum
2439  **/
GetShaderStageGLenum(STAGES stage)2440 GLenum Shader::GetShaderStageGLenum(STAGES stage)
2441 {
2442 	GLenum result = 0;
2443 
2444 	switch (stage)
2445 	{
2446 	case COMPUTE:
2447 		result = GL_COMPUTE_SHADER;
2448 		break;
2449 	case FRAGMENT:
2450 		result = GL_FRAGMENT_SHADER;
2451 		break;
2452 	case GEOMETRY:
2453 		result = GL_GEOMETRY_SHADER;
2454 		break;
2455 	case TESS_CTRL:
2456 		result = GL_TESS_CONTROL_SHADER;
2457 		break;
2458 	case TESS_EVAL:
2459 		result = GL_TESS_EVALUATION_SHADER;
2460 		break;
2461 	case VERTEX:
2462 		result = GL_VERTEX_SHADER;
2463 		break;
2464 	default:
2465 		TCU_FAIL("Invalid enum");
2466 	}
2467 
2468 	return result;
2469 }
2470 
2471 /** Get string representing name of shader stage
2472  *
2473  * @param stage Shader stage
2474  *
2475  * @return String with name of shader stage
2476  **/
GetStageName(STAGES stage)2477 const glw::GLchar* Shader::GetStageName(STAGES stage)
2478 {
2479 	const GLchar* result = 0;
2480 
2481 	switch (stage)
2482 	{
2483 	case COMPUTE:
2484 		result = "compute";
2485 		break;
2486 	case VERTEX:
2487 		result = "vertex";
2488 		break;
2489 	case TESS_CTRL:
2490 		result = "tessellation control";
2491 		break;
2492 	case TESS_EVAL:
2493 		result = "tessellation evaluation";
2494 		break;
2495 	case GEOMETRY:
2496 		result = "geometry";
2497 		break;
2498 	case FRAGMENT:
2499 		result = "fragment";
2500 		break;
2501 	default:
2502 		TCU_FAIL("Invalid enum");
2503 	}
2504 
2505 	return result;
2506 }
2507 
2508 /** Logs shader source
2509  *
2510  * @param context CTS context
2511  * @param source  Source of shader
2512  * @param stage   Shader stage
2513  **/
LogSource(deqp::Context & context,const std::string & source,STAGES stage)2514 void Shader::LogSource(deqp::Context& context, const std::string& source, STAGES stage)
2515 {
2516 	/* Skip empty shaders */
2517 	if (true == source.empty())
2518 	{
2519 		return;
2520 	}
2521 
2522 	context.getTestContext().getLog() << tcu::TestLog::Message
2523 									  << "Shader source. Stage: " << Shader::GetStageName(stage)
2524 									  << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(source);
2525 }
2526 
2527 /** Constructor
2528  *
2529  * @param message Compilation error message
2530  **/
CompilationException(const GLchar * message)2531 Shader::CompilationException::CompilationException(const GLchar* message)
2532 {
2533 	m_message = message;
2534 }
2535 
2536 /** Returns error messages
2537  *
2538  * @return Compilation error message
2539  **/
what() const2540 const char* Shader::CompilationException::what() const throw()
2541 {
2542 	return m_message.c_str();
2543 }
2544 
2545 /** Constructor
2546  *
2547  * @param message Compilation error message
2548  **/
InvalidSourceException(const GLchar * error_message,const std::string & source,STAGES stage)2549 Shader::InvalidSourceException::InvalidSourceException(const GLchar* error_message, const std::string& source,
2550 													   STAGES stage)
2551 	: m_message(error_message), m_source(source), m_stage(stage)
2552 {
2553 }
2554 
2555 /** Returns error messages
2556  *
2557  * @return Compilation error message
2558  **/
what() const2559 const char* Shader::InvalidSourceException::what() const throw()
2560 {
2561 	return "Compilation error";
2562 }
2563 
2564 /** Logs error message and shader sources **/
log(deqp::Context & context) const2565 void Shader::InvalidSourceException::log(deqp::Context& context) const
2566 {
2567 	context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader: " << m_message.c_str()
2568 									  << tcu::TestLog::EndMessage;
2569 
2570 	LogSource(context, m_source, m_stage);
2571 }
2572 
2573 /* Program constants */
2574 const GLuint Pipeline::m_invalid_id = 0;
2575 
2576 /** Constructor.
2577  *
2578  * @param context CTS context.
2579  **/
Pipeline(deqp::Context & context)2580 Pipeline::Pipeline(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2581 {
2582 	/* Nothing to be done here */
2583 }
2584 
2585 /** Destructor
2586  *
2587  **/
~Pipeline()2588 Pipeline::~Pipeline()
2589 {
2590 	Release();
2591 }
2592 
2593 /** Initialize pipline object
2594  *
2595  **/
Init()2596 void Pipeline::Init()
2597 {
2598 	Release();
2599 
2600 	const Functions& gl = m_context.getRenderContext().getFunctions();
2601 
2602 	/* Generate */
2603 	gl.genProgramPipelines(1, &m_id);
2604 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines");
2605 }
2606 
2607 /** Release pipeline object
2608  *
2609  **/
Release()2610 void Pipeline::Release()
2611 {
2612 	if (m_invalid_id != m_id)
2613 	{
2614 		const Functions& gl = m_context.getRenderContext().getFunctions();
2615 
2616 		/* Generate */
2617 		gl.deleteProgramPipelines(1, &m_id);
2618 		GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteProgramPipelines");
2619 
2620 		m_id = m_invalid_id;
2621 	}
2622 }
2623 
2624 /** Bind pipeline
2625  *
2626  **/
Bind()2627 void Pipeline::Bind()
2628 {
2629 	const Functions& gl = m_context.getRenderContext().getFunctions();
2630 
2631 	Bind(gl, m_id);
2632 }
2633 
2634 /** Set which stages should be active
2635  *
2636  * @param program_id Id of program
2637  * @param stages     Logical combination of enums representing stages
2638  **/
UseProgramStages(GLuint program_id,GLenum stages)2639 void Pipeline::UseProgramStages(GLuint program_id, GLenum stages)
2640 {
2641 	const Functions& gl = m_context.getRenderContext().getFunctions();
2642 
2643 	UseProgramStages(gl, m_id, program_id, stages);
2644 }
2645 
2646 /** Bind pipeline
2647  *
2648  * @param gl Functiions
2649  * @param id Pipeline id
2650  **/
Bind(const Functions & gl,GLuint id)2651 void Pipeline::Bind(const Functions& gl, GLuint id)
2652 {
2653 	gl.bindProgramPipeline(id);
2654 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline");
2655 }
2656 
2657 /** Set which stages should be active
2658  *
2659  * @param gl         Functiions
2660  * @param id         Pipeline id
2661  * @param program_id Id of program
2662  * @param stages     Logical combination of enums representing stages
2663  **/
UseProgramStages(const Functions & gl,GLuint id,GLuint program_id,GLenum stages)2664 void Pipeline::UseProgramStages(const Functions& gl, GLuint id, GLuint program_id, GLenum stages)
2665 {
2666 	gl.useProgramStages(id, stages, program_id);
2667 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
2668 }
2669 
2670 /* Program constants */
2671 const GLuint Program::m_invalid_id = 0;
2672 
2673 /** Constructor.
2674  *
2675  * @param context CTS context.
2676  **/
Program(deqp::Context & context)2677 Program::Program(deqp::Context& context)
2678 	: m_id(m_invalid_id)
2679 	, m_compute(context)
2680 	, m_fragment(context)
2681 	, m_geometry(context)
2682 	, m_tess_ctrl(context)
2683 	, m_tess_eval(context)
2684 	, m_vertex(context)
2685 	, m_context(context)
2686 {
2687 	/* Nothing to be done here */
2688 }
2689 
2690 /** Destructor
2691  *
2692  **/
~Program()2693 Program::~Program()
2694 {
2695 	Release();
2696 }
2697 
2698 /** Initialize program instance
2699  *
2700  * @param compute_shader                    Compute shader source code
2701  * @param fragment_shader                   Fragment shader source code
2702  * @param geometry_shader                   Geometry shader source code
2703  * @param tessellation_control_shader       Tessellation control shader source code
2704  * @param tessellation_evaluation_shader    Tessellation evaluation shader source code
2705  * @param vertex_shader                     Vertex shader source code
2706  * @param captured_varyings                 Vector of variables to be captured with transfrom feedback
2707  * @param capture_interleaved               Select mode of transform feedback (separate or interleaved)
2708  * @param is_separable                      Selects if monolithic or separable program should be built. Defaults to false
2709  **/
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)2710 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2711 				   const std::string& geometry_shader, const std::string& tessellation_control_shader,
2712 				   const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2713 				   const NameVector& captured_varyings, bool capture_interleaved, bool is_separable)
2714 {
2715 	/* Delete previous program */
2716 	Release();
2717 
2718 	/* GL entry points */
2719 	const Functions& gl = m_context.getRenderContext().getFunctions();
2720 
2721 	/* Initialize shaders */
2722 	m_compute.Init(Shader::COMPUTE, compute_shader);
2723 	m_fragment.Init(Shader::FRAGMENT, fragment_shader);
2724 	m_geometry.Init(Shader::GEOMETRY, geometry_shader);
2725 	m_tess_ctrl.Init(Shader::TESS_CTRL, tessellation_control_shader);
2726 	m_tess_eval.Init(Shader::TESS_EVAL, tessellation_evaluation_shader);
2727 	m_vertex.Init(Shader::VERTEX, vertex_shader);
2728 
2729 	/* Create program, set up transform feedback and attach shaders */
2730 	Create(gl, m_id);
2731 	Capture(gl, m_id, captured_varyings, capture_interleaved);
2732 	Attach(gl, m_id, m_compute.m_id);
2733 	Attach(gl, m_id, m_fragment.m_id);
2734 	Attach(gl, m_id, m_geometry.m_id);
2735 	Attach(gl, m_id, m_tess_ctrl.m_id);
2736 	Attach(gl, m_id, m_tess_eval.m_id);
2737 	Attach(gl, m_id, m_vertex.m_id);
2738 
2739 	/* Set separable parameter */
2740 	if (true == is_separable)
2741 	{
2742 		gl.programParameteri(m_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2743 		GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri");
2744 	}
2745 
2746 	try
2747 	{
2748 		/* Link program */
2749 		Link(gl, m_id);
2750 	}
2751 	catch (const LinkageException& exc)
2752 	{
2753 		throw BuildException(exc.what(), compute_shader, fragment_shader, geometry_shader, tessellation_control_shader,
2754 							 tessellation_evaluation_shader, vertex_shader);
2755 	}
2756 }
2757 
2758 /** Initialize program instance
2759  *
2760  * @param compute_shader                    Compute shader source code
2761  * @param fragment_shader                   Fragment shader source code
2762  * @param geometry_shader                   Geometry shader source code
2763  * @param tessellation_control_shader       Tessellation control shader source code
2764  * @param tessellation_evaluation_shader    Tessellation evaluation shader source code
2765  * @param vertex_shader                     Vertex shader source code
2766  * @param is_separable                      Selects if monolithic or separable program should be built. Defaults to false
2767  **/
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)2768 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2769 				   const std::string& geometry_shader, const std::string& tessellation_control_shader,
2770 				   const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2771 				   bool is_separable)
2772 {
2773 	NameVector captured_varying;
2774 
2775 	Init(compute_shader, fragment_shader, geometry_shader, tessellation_control_shader, tessellation_evaluation_shader,
2776 		 vertex_shader, captured_varying, true, is_separable);
2777 }
2778 
2779 /** Release program instance
2780  *
2781  **/
Release()2782 void Program::Release()
2783 {
2784 	const Functions& gl = m_context.getRenderContext().getFunctions();
2785 
2786 	if (m_invalid_id != m_id)
2787 	{
2788 		Use(gl, m_invalid_id);
2789 
2790 		gl.deleteProgram(m_id);
2791 		m_id = m_invalid_id;
2792 	}
2793 
2794 	m_compute.Release();
2795 	m_fragment.Release();
2796 	m_geometry.Release();
2797 	m_tess_ctrl.Release();
2798 	m_tess_eval.Release();
2799 	m_vertex.Release();
2800 }
2801 
2802 /** Get <pname> for a set of active uniforms
2803  *
2804  * @param count   Number of indices
2805  * @param indices Indices of uniforms
2806  * @param pname   Queired pname
2807  * @param params  Array that will be filled with values of parameters
2808  **/
GetActiveUniformsiv(GLsizei count,const GLuint * indices,GLenum pname,GLint * params) const2809 void Program::GetActiveUniformsiv(GLsizei count, const GLuint* indices, GLenum pname, GLint* params) const
2810 {
2811 	const Functions& gl = m_context.getRenderContext().getFunctions();
2812 
2813 	GetActiveUniformsiv(gl, m_id, count, indices, pname, params);
2814 }
2815 
2816 /** Get location of attribute
2817  *
2818  * @param name Name of attribute
2819  *
2820  * @return Result of query
2821  **/
GetAttribLocation(const std::string & name) const2822 glw::GLint Program::GetAttribLocation(const std::string& name) const
2823 {
2824 	const Functions& gl = m_context.getRenderContext().getFunctions();
2825 
2826 	return GetAttribLocation(gl, m_id, name);
2827 }
2828 
2829 /** Query resource
2830  *
2831  * @param interface Interface to be queried
2832  * @param index     Index of resource
2833  * @param property  Property to be queried
2834  * @param buf_size  Size of <params> buffer
2835  * @param params    Results of query
2836  **/
GetResource(GLenum interface,GLuint index,GLenum property,GLsizei buf_size,GLint * params) const2837 void Program::GetResource(GLenum interface, GLuint index, GLenum property, GLsizei buf_size, GLint* params) const
2838 {
2839 	const Functions& gl = m_context.getRenderContext().getFunctions();
2840 
2841 	GetResource(gl, m_id, interface, index, property, buf_size, params);
2842 }
2843 
2844 /** Query for index of resource
2845  *
2846  * @param name      Name of resource
2847  * @param interface Interface to be queried
2848  *
2849  * @return Result of query
2850  **/
GetResourceIndex(const std::string & name,GLenum interface) const2851 glw::GLuint Program::GetResourceIndex(const std::string& name, GLenum interface) const
2852 {
2853 	const Functions& gl = m_context.getRenderContext().getFunctions();
2854 
2855 	return GetResourceIndex(gl, m_id, name, interface);
2856 }
2857 
2858 /** Get indices for a set of uniforms
2859  *
2860  * @param count   Count number of uniforms
2861  * @param names   Names of uniforms
2862  * @param indices Buffer that will be filled with indices
2863  **/
GetUniformIndices(GLsizei count,const GLchar ** names,GLuint * indices) const2864 void Program::GetUniformIndices(GLsizei count, const GLchar** names, GLuint* indices) const
2865 {
2866 	const Functions& gl = m_context.getRenderContext().getFunctions();
2867 
2868 	GetUniformIndices(gl, m_id, count, names, indices);
2869 }
2870 
2871 /** Get uniform location
2872  *
2873  * @param name Name of uniform
2874  *
2875  * @return Results of query
2876  **/
GetUniformLocation(const std::string & name) const2877 glw::GLint Program::GetUniformLocation(const std::string& name) const
2878 {
2879 	const Functions& gl = m_context.getRenderContext().getFunctions();
2880 
2881 	return GetUniformLocation(gl, m_id, name);
2882 }
2883 
2884 /** Set program as active
2885  *
2886  **/
Use() const2887 void Program::Use() const
2888 {
2889 	const Functions& gl = m_context.getRenderContext().getFunctions();
2890 
2891 	Use(gl, m_id);
2892 }
2893 
2894 /** Attach shader to program
2895  *
2896  * @param gl         GL functions
2897  * @param program_id Id of program
2898  * @param shader_id  Id of shader
2899  **/
Attach(const Functions & gl,GLuint program_id,GLuint shader_id)2900 void Program::Attach(const Functions& gl, GLuint program_id, GLuint shader_id)
2901 {
2902 	/* Sanity checks */
2903 	if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id))
2904 	{
2905 		return;
2906 	}
2907 
2908 	gl.attachShader(program_id, shader_id);
2909 	GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2910 }
2911 
2912 /** Set up captured varyings
2913  *
2914  * @param gl                  GL functions
2915  * @param id                  Id of program
2916  * @param captured_varyings   Vector of varyings
2917  * @param capture_interleaved Selects if interleaved or separate mode should be used
2918  **/
Capture(const Functions & gl,GLuint id,const NameVector & captured_varyings,bool capture_interleaved)2919 void Program::Capture(const Functions& gl, GLuint id, const NameVector& captured_varyings, bool capture_interleaved)
2920 {
2921 	const size_t n_varyings = captured_varyings.size();
2922 
2923 	if (0 == n_varyings)
2924 	{
2925 		/* empty list, skip */
2926 		return;
2927 	}
2928 
2929 	std::vector<const GLchar*> varying_names;
2930 	varying_names.resize(n_varyings);
2931 
2932 	for (size_t i = 0; i < n_varyings; ++i)
2933 	{
2934 		varying_names[i] = captured_varyings[i].c_str();
2935 	}
2936 
2937 	GLenum mode = 0;
2938 	if (true == capture_interleaved)
2939 	{
2940 		mode = GL_INTERLEAVED_ATTRIBS;
2941 	}
2942 	else
2943 	{
2944 		mode = GL_SEPARATE_ATTRIBS;
2945 	}
2946 
2947 	gl.transformFeedbackVaryings(id, static_cast<GLsizei>(n_varyings), &varying_names[0], mode);
2948 	GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
2949 }
2950 
2951 /** Create program instance
2952  *
2953  * @param gl     GL functions
2954  * @param out_id Id of program
2955  **/
Create(const Functions & gl,GLuint & out_id)2956 void Program::Create(const Functions& gl, GLuint& out_id)
2957 {
2958 	const GLuint id = gl.createProgram();
2959 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2960 
2961 	if (m_invalid_id == id)
2962 	{
2963 		TCU_FAIL("Failed to create program");
2964 	}
2965 
2966 	out_id = id;
2967 }
2968 
2969 /** Get <pname> for a set of active uniforms
2970  *
2971  * @param gl         Functions
2972  * @param program_id Id of program
2973  * @param count      Number of indices
2974  * @param indices    Indices of uniforms
2975  * @param pname      Queired pname
2976  * @param params     Array that will be filled with values of parameters
2977  **/
GetActiveUniformsiv(const Functions & gl,GLuint program_id,GLsizei count,const GLuint * indices,GLenum pname,GLint * params)2978 void Program::GetActiveUniformsiv(const Functions& gl, GLuint program_id, GLsizei count, const GLuint* indices,
2979 								  GLenum pname, GLint* params)
2980 {
2981 	gl.getActiveUniformsiv(program_id, count, indices, pname, params);
2982 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
2983 }
2984 
2985 /** Get indices for a set of uniforms
2986  *
2987  * @param gl         Functions
2988  * @param program_id Id of program
2989  * @param count      Count number of uniforms
2990  * @param names      Names of uniforms
2991  * @param indices    Buffer that will be filled with indices
2992  **/
GetUniformIndices(const Functions & gl,GLuint program_id,GLsizei count,const GLchar ** names,GLuint * indices)2993 void Program::GetUniformIndices(const Functions& gl, GLuint program_id, GLsizei count, const GLchar** names,
2994 								GLuint* indices)
2995 {
2996 	gl.getUniformIndices(program_id, count, names, indices);
2997 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
2998 }
2999 
3000 /** Link program
3001  *
3002  * @param gl GL functions
3003  * @param id Id of program
3004  **/
Link(const Functions & gl,GLuint id)3005 void Program::Link(const Functions& gl, GLuint id)
3006 {
3007 	GLint status = GL_FALSE;
3008 
3009 	gl.linkProgram(id);
3010 	GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
3011 
3012 	/* Get link status */
3013 	gl.getProgramiv(id, GL_LINK_STATUS, &status);
3014 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
3015 
3016 	/* Log link error */
3017 	if (GL_TRUE != status)
3018 	{
3019 		glw::GLint  length = 0;
3020 		std::string message;
3021 
3022 		/* Get error log length */
3023 		gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length);
3024 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
3025 
3026 		message.resize(length, 0);
3027 
3028 		/* Get error log */
3029 		gl.getProgramInfoLog(id, length, 0, &message[0]);
3030 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
3031 
3032 		throw LinkageException(message.c_str());
3033 	}
3034 }
3035 
3036 /** Set generic uniform
3037  *
3038  * @param gl       Functions
3039  * @param type     Type of uniform
3040  * @param count    Length of array
3041  * @param location Location of uniform
3042  * @param data     Data that will be used
3043  **/
Uniform(const Functions & gl,const Type & type,GLsizei count,GLint location,const GLvoid * data)3044 void Program::Uniform(const Functions& gl, const Type& type, GLsizei count, GLint location, const GLvoid* data)
3045 {
3046 	if (-1 == location)
3047 	{
3048 		TCU_FAIL("Uniform is inactive");
3049 	}
3050 
3051 	switch (type.m_basic_type)
3052 	{
3053 	case Type::Double:
3054 		if (1 == type.m_n_columns)
3055 		{
3056 			getUniformNdv(gl, type.m_n_rows)(location, count, (const GLdouble*)data);
3057 			GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNdv");
3058 		}
3059 		else
3060 		{
3061 			getUniformMatrixNdv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLdouble*)data);
3062 			GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNdv");
3063 		}
3064 		break;
3065 	case Type::Float:
3066 		if (1 == type.m_n_columns)
3067 		{
3068 			getUniformNfv(gl, type.m_n_rows)(location, count, (const GLfloat*)data);
3069 			GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNfv");
3070 		}
3071 		else
3072 		{
3073 			getUniformMatrixNfv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLfloat*)data);
3074 			GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNfv");
3075 		}
3076 		break;
3077 	case Type::Int:
3078 		getUniformNiv(gl, type.m_n_rows)(location, count, (const GLint*)data);
3079 		GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNiv");
3080 		break;
3081 	case Type::Uint:
3082 		getUniformNuiv(gl, type.m_n_rows)(location, count, (const GLuint*)data);
3083 		GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNuiv");
3084 		break;
3085 	default:
3086 		TCU_FAIL("Invalid enum");
3087 	}
3088 }
3089 
3090 /** Use program
3091  *
3092  * @param gl GL functions
3093  * @param id Id of program
3094  **/
Use(const Functions & gl,GLuint id)3095 void Program::Use(const Functions& gl, GLuint id)
3096 {
3097 	gl.useProgram(id);
3098 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3099 }
3100 
3101 /** Get location of attribute
3102  *
3103  * @param gl   GL functions
3104  * @param id   Id of program
3105  * @param name Name of attribute
3106  *
3107  * @return Location of attribute
3108  **/
GetAttribLocation(const Functions & gl,GLuint id,const std::string & name)3109 GLint Program::GetAttribLocation(const Functions& gl, GLuint id, const std::string& name)
3110 {
3111 	GLint location = gl.getAttribLocation(id, name.c_str());
3112 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation");
3113 
3114 	return location;
3115 }
3116 
3117 /** Query resource
3118  *
3119  * @param gl        GL functions
3120  * @param id        Id of program
3121  * @param interface Interface to be queried
3122  * @param index     Index of resource
3123  * @param property  Property to be queried
3124  * @param buf_size  Size of <params> buffer
3125  * @param params    Results of query
3126  **/
GetResource(const Functions & gl,GLuint id,GLenum interface,GLuint index,GLenum property,GLsizei buf_size,GLint * params)3127 void Program::GetResource(const Functions& gl, GLuint id, GLenum interface, GLuint index, GLenum property,
3128 						  GLsizei buf_size, GLint* params)
3129 {
3130 	gl.getProgramResourceiv(id, interface, index, 1 /* propCount */, &property, buf_size /* bufSize */, 0 /* length */,
3131 							params);
3132 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv");
3133 }
3134 
3135 /** Get index of resource
3136  *
3137  * @param gl        GL functions
3138  * @param id        Id of program
3139  * @param name      Name of resource
3140  * @param interface Program interface to queried
3141  *
3142  * @return Location of attribute
3143  **/
GetResourceIndex(const Functions & gl,GLuint id,const std::string & name,GLenum interface)3144 GLuint Program::GetResourceIndex(const Functions& gl, GLuint id, const std::string& name, GLenum interface)
3145 {
3146 	GLuint index = gl.getProgramResourceIndex(id, interface, name.c_str());
3147 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex");
3148 
3149 	return index;
3150 }
3151 
3152 /** Get location of attribute
3153  *
3154  * @param gl   GL functions
3155  * @param id   Id of program
3156  * @param name Name of attribute
3157  *
3158  * @return Location of uniform
3159  **/
GetUniformLocation(const Functions & gl,GLuint id,const std::string & name)3160 GLint Program::GetUniformLocation(const Functions& gl, GLuint id, const std::string& name)
3161 {
3162 	GLint location = gl.getUniformLocation(id, name.c_str());
3163 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3164 
3165 	return location;
3166 }
3167 
3168 /** Constructor
3169  *
3170  * @param error_message    Error message
3171  * @param compute_shader   Source code for compute stage
3172  * @param fragment_shader  Source code for fragment stage
3173  * @param geometry_shader  Source code for geometry stage
3174  * @param tess_ctrl_shader Source code for tessellation control stage
3175  * @param tess_eval_shader Source code for tessellation evaluation stage
3176  * @param vertex_shader    Source code for vertex stage
3177  **/
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)3178 Program::BuildException::BuildException(const glw::GLchar* error_message, const std::string compute_shader,
3179 										const std::string fragment_shader, const std::string geometry_shader,
3180 										const std::string tess_ctrl_shader, const std::string tess_eval_shader,
3181 										const std::string vertex_shader)
3182 	: m_error_message(error_message)
3183 	, m_compute_shader(compute_shader)
3184 	, m_fragment_shader(fragment_shader)
3185 	, m_geometry_shader(geometry_shader)
3186 	, m_tess_ctrl_shader(tess_ctrl_shader)
3187 	, m_tess_eval_shader(tess_eval_shader)
3188 	, m_vertex_shader(vertex_shader)
3189 {
3190 }
3191 
3192 /** Overwrites std::exception::what method
3193  *
3194  * @return Message compossed from error message and shader sources
3195  **/
what() const3196 const char* Program::BuildException::what() const throw()
3197 {
3198 	return "Failed to link program";
3199 }
3200 
3201 /** Logs error message and shader sources **/
log(deqp::Context & context) const3202 void Program::BuildException::log(deqp::Context& context) const
3203 {
3204 	context.getTestContext().getLog() << tcu::TestLog::Message << "Link failure: " << m_error_message
3205 									  << tcu::TestLog::EndMessage;
3206 
3207 	Shader::LogSource(context, m_vertex_shader, Shader::VERTEX);
3208 	Shader::LogSource(context, m_tess_ctrl_shader, Shader::TESS_CTRL);
3209 	Shader::LogSource(context, m_tess_eval_shader, Shader::TESS_EVAL);
3210 	Shader::LogSource(context, m_geometry_shader, Shader::GEOMETRY);
3211 	Shader::LogSource(context, m_fragment_shader, Shader::FRAGMENT);
3212 	Shader::LogSource(context, m_compute_shader, Shader::COMPUTE);
3213 }
3214 
3215 /** Constructor
3216  *
3217  * @param message Linking error message
3218  **/
LinkageException(const glw::GLchar * message)3219 Program::LinkageException::LinkageException(const glw::GLchar* message) : m_error_message(message)
3220 {
3221 	/* Nothing to be done */
3222 }
3223 
3224 /** Returns error messages
3225  *
3226  * @return Linking error message
3227  **/
what() const3228 const char* Program::LinkageException::what() const throw()
3229 {
3230 	return m_error_message.c_str();
3231 }
3232 
3233 /* Texture constants */
3234 const GLuint Texture::m_invalid_id = -1;
3235 
3236 /** Constructor.
3237  *
3238  * @param context CTS context.
3239  **/
Texture(deqp::Context & context)3240 Texture::Texture(deqp::Context& context) : m_id(m_invalid_id), m_context(context), m_type(TEX_2D)
3241 {
3242 	/* Nothing to done here */
3243 }
3244 
3245 /** Destructor
3246  *
3247  **/
~Texture()3248 Texture::~Texture()
3249 {
3250 	Release();
3251 }
3252 
3253 /** Initialize texture instance
3254  *
3255  * @param tex_type        Type of texture
3256  * @param width           Width of texture
3257  * @param height          Height of texture
3258  * @param depth           Depth of texture
3259  * @param internal_format Internal format of texture
3260  * @param format          Format of texture data
3261  * @param type            Type of texture data
3262  * @param data            Texture data
3263  **/
Init(TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum internal_format,GLenum format,GLenum type,GLvoid * data)3264 void Texture::Init(TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum internal_format, GLenum format,
3265 				   GLenum type, GLvoid* data)
3266 {
3267 	const Functions& gl = m_context.getRenderContext().getFunctions();
3268 
3269 	/* Delete previous texture */
3270 	Release();
3271 
3272 	m_type = tex_type;
3273 
3274 	/* Generate, bind, allocate storage and upload data */
3275 	Generate(gl, m_id);
3276 	Bind(gl, m_id, tex_type);
3277 	Storage(gl, tex_type, width, height, depth, internal_format);
3278 	Update(gl, tex_type, width, height, depth, format, type, data);
3279 }
3280 
3281 /** Initialize buffer texture
3282  *
3283  * @param internal_format Internal format of texture
3284  * @param buffer_id       Id of buffer that will be used as data source
3285  **/
Init(GLenum internal_format,GLuint buffer_id)3286 void Texture::Init(GLenum internal_format, GLuint buffer_id)
3287 {
3288 	const Functions& gl = m_context.getRenderContext().getFunctions();
3289 
3290 	/* Delete previous texture */
3291 	Release();
3292 
3293 	m_type = TEX_BUFFER;
3294 
3295 	/* Generate, bind and attach buffer */
3296 	Generate(gl, m_id);
3297 	Bind(gl, m_id, TEX_BUFFER);
3298 	TexBuffer(gl, buffer_id, internal_format);
3299 }
3300 
3301 /** Release texture instance
3302  *
3303  **/
Release()3304 void Texture::Release()
3305 {
3306 	if (m_invalid_id != m_id)
3307 	{
3308 		const Functions& gl = m_context.getRenderContext().getFunctions();
3309 
3310 		gl.deleteTextures(1, &m_id);
3311 		m_id = m_invalid_id;
3312 	}
3313 }
3314 
3315 /** Bind texture to its target
3316  *
3317  **/
Bind() const3318 void Texture::Bind() const
3319 {
3320 	const Functions& gl = m_context.getRenderContext().getFunctions();
3321 
3322 	Bind(gl, m_id, m_type);
3323 }
3324 
3325 /** Get texture data
3326  *
3327  * @param format   Format of data
3328  * @param type     Type of data
3329  * @param out_data Buffer for data
3330  **/
Get(GLenum format,GLenum type,GLvoid * out_data) const3331 void Texture::Get(GLenum format, GLenum type, GLvoid* out_data) const
3332 {
3333 	const Functions& gl = m_context.getRenderContext().getFunctions();
3334 
3335 	Bind(gl, m_id, m_type);
3336 	Get(gl, m_type, format, type, out_data);
3337 }
3338 
3339 /** Bind texture to target
3340  *
3341  * @param gl       GL functions
3342  * @param id       Id of texture
3343  * @param tex_type Type of texture
3344  **/
Bind(const Functions & gl,GLuint id,TYPES tex_type)3345 void Texture::Bind(const Functions& gl, GLuint id, TYPES tex_type)
3346 {
3347 	GLenum target = GetTargetGLenum(tex_type);
3348 
3349 	gl.bindTexture(target, id);
3350 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3351 }
3352 
3353 /** Generate texture instance
3354  *
3355  * @param gl     GL functions
3356  * @param out_id Id of texture
3357  **/
Generate(const Functions & gl,GLuint & out_id)3358 void Texture::Generate(const Functions& gl, GLuint& out_id)
3359 {
3360 	GLuint id = m_invalid_id;
3361 
3362 	gl.genTextures(1, &id);
3363 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3364 
3365 	if (m_invalid_id == id)
3366 	{
3367 		TCU_FAIL("Invalid id");
3368 	}
3369 
3370 	out_id = id;
3371 }
3372 
3373 /** Get texture data
3374  *
3375  * @param gl       GL functions
3376  * @param format   Format of data
3377  * @param type     Type of data
3378  * @param out_data Buffer for data
3379  **/
Get(const Functions & gl,TYPES tex_type,GLenum format,GLenum type,GLvoid * out_data)3380 void Texture::Get(const Functions& gl, TYPES tex_type, GLenum format, GLenum type, GLvoid* out_data)
3381 {
3382 	GLenum target = GetTargetGLenum(tex_type);
3383 
3384 	if (TEX_CUBE != tex_type)
3385 	{
3386 		gl.getTexImage(target, 0 /* level */, format, type, out_data);
3387 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3388 	}
3389 	else
3390 	{
3391 		GLint width;
3392 		GLint height;
3393 
3394 		if ((GL_RGBA != format) && (GL_UNSIGNED_BYTE != type))
3395 		{
3396 			TCU_FAIL("Not implemented");
3397 		}
3398 
3399 		GLuint texel_size = 4;
3400 
3401 		gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_WIDTH, &width);
3402 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3403 
3404 		gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_HEIGHT, &height);
3405 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3406 
3407 		const GLuint image_size = width * height * texel_size;
3408 
3409 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, format, type,
3410 					   (GLvoid*)((GLchar*)out_data + (image_size * 0)));
3411 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0 /* level */, format, type,
3412 					   (GLvoid*)((GLchar*)out_data + (image_size * 1)));
3413 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0 /* level */, format, type,
3414 					   (GLvoid*)((GLchar*)out_data + (image_size * 2)));
3415 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0 /* level */, format, type,
3416 					   (GLvoid*)((GLchar*)out_data + (image_size * 3)));
3417 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0 /* level */, format, type,
3418 					   (GLvoid*)((GLchar*)out_data + (image_size * 4)));
3419 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0 /* level */, format, type,
3420 					   (GLvoid*)((GLchar*)out_data + (image_size * 5)));
3421 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3422 	}
3423 }
3424 
3425 /** Allocate storage for texture
3426  *
3427  * @param gl              GL functions
3428  * @param tex_type        Type of texture
3429  * @param width           Width of texture
3430  * @param height          Height of texture
3431  * @param depth           Depth of texture
3432  * @param internal_format Internal format of texture
3433  **/
Storage(const Functions & gl,TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum internal_format)3434 void Texture::Storage(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth,
3435 					  GLenum internal_format)
3436 {
3437 	static const GLuint levels = 1;
3438 
3439 	GLenum target = GetTargetGLenum(tex_type);
3440 
3441 	switch (tex_type)
3442 	{
3443 	case TEX_1D:
3444 		gl.texStorage1D(target, levels, internal_format, width);
3445 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3446 		break;
3447 	case TEX_2D:
3448 	case TEX_1D_ARRAY:
3449 	case TEX_2D_RECT:
3450 	case TEX_CUBE:
3451 		gl.texStorage2D(target, levels, internal_format, width, height);
3452 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3453 		break;
3454 	case TEX_3D:
3455 	case TEX_2D_ARRAY:
3456 		gl.texStorage3D(target, levels, internal_format, width, height, depth);
3457 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3458 		break;
3459 	default:
3460 		TCU_FAIL("Invalid enum");
3461 	}
3462 }
3463 
3464 /** Attach buffer as source of texture buffer data
3465  *
3466  * @param gl              GL functions
3467  * @param internal_format Internal format of texture
3468  * @param buffer_id       Id of buffer that will be used as data source
3469  **/
TexBuffer(const Functions & gl,GLenum internal_format,GLuint & buffer_id)3470 void Texture::TexBuffer(const Functions& gl, GLenum internal_format, GLuint& buffer_id)
3471 {
3472 	gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id);
3473 	GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer");
3474 }
3475 
3476 /** Update contents of texture
3477  *
3478  * @param gl       GL functions
3479  * @param tex_type Type of texture
3480  * @param width    Width of texture
3481  * @param height   Height of texture
3482  * @param format   Format of data
3483  * @param type     Type of data
3484  * @param data     Buffer with image data
3485  **/
Update(const Functions & gl,TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum format,GLenum type,GLvoid * data)3486 void Texture::Update(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum format,
3487 					 GLenum type, GLvoid* data)
3488 {
3489 	static const GLuint level = 0;
3490 
3491 	GLenum target = GetTargetGLenum(tex_type);
3492 
3493 	switch (tex_type)
3494 	{
3495 	case TEX_1D:
3496 		gl.texSubImage1D(target, level, 0 /* x */, width, format, type, data);
3497 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3498 		break;
3499 	case TEX_2D:
3500 	case TEX_1D_ARRAY:
3501 	case TEX_2D_RECT:
3502 		gl.texSubImage2D(target, level, 0 /* x */, 0 /* y */, width, height, format, type, data);
3503 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3504 		break;
3505 	case TEX_CUBE:
3506 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3507 						 data);
3508 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3509 						 data);
3510 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3511 						 data);
3512 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3513 						 data);
3514 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3515 						 data);
3516 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3517 						 data);
3518 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3519 		break;
3520 	case TEX_3D:
3521 	case TEX_2D_ARRAY:
3522 		gl.texSubImage3D(target, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format, type, data);
3523 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3524 		break;
3525 	default:
3526 		TCU_FAIL("Invalid enum");
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 	}
4074 
4075 	if (BUILTIN != m_type)
4076 	{
4077 		if (0 == m_interface)
4078 		{
4079 			TCU_FAIL("Nullptr");
4080 		}
4081 	}
4082 
4083 	/* Qualifiers */
4084 	if (true == m_qualifiers.empty())
4085 	{
4086 		replaceToken("QUALIFIERS ", position, "", definition);
4087 	}
4088 	else
4089 	{
4090 		replaceToken("QUALIFIERS", position, m_qualifiers.c_str(), definition);
4091 	}
4092 
4093 	// According to spec: int, uint, and double type must always be declared with flat qualifier
4094 	bool flat_qualifier = false;
4095 	if (m_type != BUILTIN && m_interface != NULL)
4096 	{
4097 		if (m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Int ||
4098 			m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Uint ||
4099 			m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Double)
4100 		{
4101 			flat_qualifier = true;
4102 		}
4103 	}
4104 	/* Storage */
4105 	switch (storage)
4106 	{
4107 	case VARYING_INPUT:
4108 		storage_str = flat_qualifier ? "flat in " : "in ";
4109 		break;
4110 	case VARYING_OUTPUT:
4111 		storage_str = "out ";
4112 		break;
4113 	case UNIFORM:
4114 		storage_str = "uniform ";
4115 		break;
4116 	case SSB:
4117 		storage_str = "buffer ";
4118 		break;
4119 	case MEMBER:
4120 		storage_str = "";
4121 		break;
4122 	default:
4123 		TCU_FAIL("Invalid enum");
4124 	}
4125 
4126 	replaceToken("STORAGE", position, storage_str, definition);
4127 
4128 	/* Type */
4129 	if (BUILTIN == m_type)
4130 	{
4131 		replaceToken("TYPE", position, m_builtin.GetGLSLTypeName(), definition);
4132 	}
4133 	else
4134 	{
4135 		if (Interface::STRUCT == m_interface->m_type)
4136 		{
4137 			replaceToken("TYPE", position, m_interface->m_name.c_str(), definition);
4138 		}
4139 		else
4140 		{
4141 			const std::string& block_definition = m_interface->GetDefinition();
4142 
4143 			replaceToken("TYPE", position, block_definition.c_str(), definition);
4144 		}
4145 	}
4146 
4147 	/* Name */
4148 	replaceToken("NAME", position, m_name.c_str(), definition);
4149 
4150 	/* Array size */
4151 	if (0 == m_n_array_elements)
4152 	{
4153 		replaceToken("ARRAY", position, "", definition);
4154 	}
4155 	else
4156 	{
4157 		char buffer[16];
4158 		sprintf(buffer, "[%d]", m_n_array_elements);
4159 
4160 		replaceToken("ARRAY", position, buffer, definition);
4161 	}
4162 
4163 	/* Done */
4164 	return definition;
4165 }
4166 
4167 /** Get definitions for variables collected in vector
4168  *
4169  * @param vector  Collection of variables
4170  * @param flavour Flavour of variables
4171  *
4172  * @return Code with definitions
4173  **/
GetDefinitions(const Variable::PtrVector & vector,Variable::FLAVOUR flavour)4174 std::string GetDefinitions(const Variable::PtrVector& vector, Variable::FLAVOUR flavour)
4175 {
4176 	std::string list	 = Utils::g_list;
4177 	size_t		position = 0;
4178 
4179 	for (GLuint i = 0; i < vector.size(); ++i)
4180 	{
4181 		Utils::insertElementOfList(vector[i]->GetDefinition(flavour).c_str(), "\n", position, list);
4182 	}
4183 
4184 	Utils::endList("", position, list);
4185 
4186 	return list;
4187 }
4188 
4189 /** Get definitions for interfaces collected in vector
4190  *
4191  * @param vector Collection of interfaces
4192  *
4193  * @return Code with definitions
4194  **/
GetDefinitions(const Interface::PtrVector & vector)4195 std::string GetDefinitions(const Interface::PtrVector& vector)
4196 {
4197 	std::string list	 = Utils::g_list;
4198 	size_t		position = 0;
4199 
4200 	for (GLuint i = 0; i < vector.size(); ++i)
4201 	{
4202 		Utils::insertElementOfList(vector[i]->GetDefinition().c_str(), "\n", position, list);
4203 	}
4204 
4205 	Utils::endList("", position, list);
4206 
4207 	return list;
4208 }
4209 
4210 /** Constructor
4211  *
4212  * @param name Name
4213  * @param type Type of interface
4214  **/
Interface(const GLchar * name,Interface::TYPE type)4215 Interface::Interface(const GLchar* name, Interface::TYPE type) : m_name(name), m_type(type)
4216 {
4217 }
4218 
4219 /** Adds member to interface
4220  *
4221  * @param member Descriptor of new member
4222  *
4223  * @return Pointer to just created member
4224  **/
AddMember(const Variable::Descriptor & member)4225 Variable::Descriptor* Interface::AddMember(const Variable::Descriptor& member)
4226 {
4227 	m_members.push_back(member);
4228 
4229 	return &m_members.back();
4230 }
4231 
4232 /** Get definition of interface
4233  *
4234  * @param Code with definition
4235  **/
GetDefinition() const4236 std::string Interface::GetDefinition() const
4237 {
4238 	std::string definition;
4239 	size_t		position = 0;
4240 
4241 	const GLchar* member_list = "    MEMBER_DEFINITION\nMEMBER_LIST";
4242 
4243 	if (STRUCT == m_type)
4244 	{
4245 		definition = "struct NAME {\nMEMBER_LIST};";
4246 	}
4247 	else
4248 	{
4249 		definition = "NAME {\nMEMBER_LIST}";
4250 	}
4251 
4252 	/* Name */
4253 	replaceToken("NAME", position, m_name.c_str(), definition);
4254 
4255 	/* Member list */
4256 	for (GLuint i = 0; i < m_members.size(); ++i)
4257 	{
4258 		const size_t	   start_position	= position;
4259 		const std::string& member_definition = m_members[i].GetDefinition(Variable::BASIC, Variable::MEMBER);
4260 
4261 		/* Member list */
4262 		replaceToken("MEMBER_LIST", position, member_list, definition);
4263 
4264 		/* Move back position */
4265 		position = start_position;
4266 
4267 		/* Member definition */
4268 		replaceToken("MEMBER_DEFINITION", position, member_definition.c_str(), definition);
4269 	}
4270 
4271 	/* Remove last member list */
4272 	replaceToken("MEMBER_LIST", position, "", definition);
4273 
4274 	/* Done */
4275 	return definition;
4276 }
4277 
4278 /** Adds member of built-in type to interface
4279  *
4280  * @param name                       Name
4281  * @param qualifiers                 Qualifiers
4282  * @param expected_component         Expected component of variable
4283  * @param expected_location          Expected location
4284  * @param type                       Type
4285  * @param normalized                 Selects if data should be normalized
4286  * @param n_array_elements           Length of array
4287  * @param expected_stride_of_element Expected stride of element
4288  * @param offset                     Offset
4289  *
4290  * @return Pointer to just created member
4291  **/
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)4292 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4293 										GLint expected_location, const Type& type, GLboolean normalized,
4294 										GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4295 {
4296 	return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, type, normalized,
4297 										  n_array_elements, expected_stride_of_element, offset));
4298 }
4299 
4300 /** Adds member of interface type to interface
4301  *
4302  * @param name                       Name
4303  * @param qualifiers                 Qualifiers
4304  * @param expected_component         Expected component of variable
4305  * @param expected_location          Expected location
4306  * @param type                       Type
4307  * @param normalized                 Selects if data should be normalized
4308  * @param n_array_elements           Length of array
4309  * @param expected_stride_of_element Expected stride of element
4310  * @param offset                     Offset
4311  *
4312  * @return Pointer to just created member
4313  **/
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)4314 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4315 										GLint expected_location, Interface* nterface, GLuint n_array_elements,
4316 										GLint expected_stride_of_element, GLuint offset)
4317 {
4318 	return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, nterface,
4319 										  n_array_elements, expected_stride_of_element, offset));
4320 }
4321 
4322 /** Clears contents of vector of pointers
4323  *
4324  * @tparam T Type of elements
4325  *
4326  * @param vector Collection to be cleared
4327  **/
4328 template <typename T>
clearPtrVector(std::vector<T * > & vector)4329 void clearPtrVector(std::vector<T*>& vector)
4330 {
4331 	for (size_t i = 0; i < vector.size(); ++i)
4332 	{
4333 		T* t = vector[i];
4334 
4335 		vector[i] = 0;
4336 
4337 		if (0 != t)
4338 		{
4339 			delete t;
4340 		}
4341 	}
4342 
4343 	vector.clear();
4344 }
4345 
4346 /** Constructor
4347  *
4348  * @param stage Stage described by that interface
4349  **/
ShaderInterface(Shader::STAGES stage)4350 ShaderInterface::ShaderInterface(Shader::STAGES stage) : m_stage(stage)
4351 {
4352 	/* Nothing to be done */
4353 }
4354 
4355 /** Get definitions of globals
4356  *
4357  * @return Code with definitions
4358  **/
GetDefinitionsGlobals() const4359 std::string ShaderInterface::GetDefinitionsGlobals() const
4360 {
4361 	return m_globals;
4362 }
4363 
4364 /** Get definitions of inputs
4365  *
4366  * @return Code with definitions
4367  **/
GetDefinitionsInputs() const4368 std::string ShaderInterface::GetDefinitionsInputs() const
4369 {
4370 	Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::INPUT);
4371 
4372 	return GetDefinitions(m_inputs, flavour);
4373 }
4374 
4375 /** Get definitions of outputs
4376  *
4377  * @return Code with definitions
4378  **/
GetDefinitionsOutputs() const4379 std::string ShaderInterface::GetDefinitionsOutputs() const
4380 {
4381 	Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::OUTPUT);
4382 
4383 	return GetDefinitions(m_outputs, flavour);
4384 }
4385 
4386 /** Get definitions of buffers
4387  *
4388  * @return Code with definitions
4389  **/
GetDefinitionsSSBs() const4390 std::string ShaderInterface::GetDefinitionsSSBs() const
4391 {
4392 	return GetDefinitions(m_ssb_blocks, Variable::BASIC);
4393 }
4394 
4395 /** Get definitions of uniforms
4396  *
4397  * @return Code with definitions
4398  **/
GetDefinitionsUniforms() const4399 std::string ShaderInterface::GetDefinitionsUniforms() const
4400 {
4401 	return GetDefinitions(m_uniforms, Variable::BASIC);
4402 }
4403 
4404 /** Constructor
4405  *
4406  * @param in  Input variable
4407  * @param out Output variable
4408  **/
VaryingConnection(Variable * in,Variable * out)4409 VaryingConnection::VaryingConnection(Variable* in, Variable* out) : m_in(in), m_out(out)
4410 {
4411 	/* NBothing to be done here */
4412 }
4413 
4414 /** Adds new varying connection to given stage
4415  *
4416  * @param stage Shader stage
4417  * @param in    In varying
4418  * @param out   Out varying
4419  **/
Add(Shader::STAGES stage,Variable * in,Variable * out)4420 void VaryingPassthrough::Add(Shader::STAGES stage, Variable* in, Variable* out)
4421 {
4422 	VaryingConnection::Vector& vector = Get(stage);
4423 
4424 	vector.push_back(VaryingConnection(in, out));
4425 }
4426 
4427 /** Get all passthrough connections for given stage
4428  *
4429  * @param stage Shader stage
4430  *
4431  * @return Vector of connections
4432  **/
Get(Shader::STAGES stage)4433 VaryingConnection::Vector& VaryingPassthrough::Get(Shader::STAGES stage)
4434 {
4435 	VaryingConnection::Vector* result = 0;
4436 
4437 	switch (stage)
4438 	{
4439 	case Shader::FRAGMENT:
4440 		result = &m_fragment;
4441 		break;
4442 	case Shader::GEOMETRY:
4443 		result = &m_geometry;
4444 		break;
4445 	case Shader::TESS_CTRL:
4446 		result = &m_tess_ctrl;
4447 		break;
4448 	case Shader::TESS_EVAL:
4449 		result = &m_tess_eval;
4450 		break;
4451 	case Shader::VERTEX:
4452 		result = &m_vertex;
4453 		break;
4454 	default:
4455 		TCU_FAIL("Invalid enum");
4456 	}
4457 
4458 	return *result;
4459 }
4460 
4461 /** Constructor
4462  *
4463  **/
ProgramInterface()4464 ProgramInterface::ProgramInterface()
4465 	: m_compute(Shader::COMPUTE)
4466 	, m_vertex(Shader::VERTEX)
4467 	, m_tess_ctrl(Shader::TESS_CTRL)
4468 	, m_tess_eval(Shader::TESS_EVAL)
4469 	, m_geometry(Shader::GEOMETRY)
4470 	, m_fragment(Shader::FRAGMENT)
4471 {
4472 }
4473 
4474 /** Destructor
4475  *
4476  **/
~ProgramInterface()4477 ProgramInterface::~ProgramInterface()
4478 {
4479 	clearPtrVector(m_blocks);
4480 	clearPtrVector(m_structures);
4481 }
4482 
4483 /** Adds new interface
4484  *
4485  * @param name
4486  * @param type
4487  *
4488  * @return Pointer to created interface
4489  **/
AddInterface(const GLchar * name,Interface::TYPE type)4490 Interface* ProgramInterface::AddInterface(const GLchar* name, Interface::TYPE type)
4491 {
4492 	Interface* interface = 0;
4493 
4494 	if (Interface::STRUCT == type)
4495 	{
4496 		interface = new Interface(name, type);
4497 
4498 		m_structures.push_back(interface);
4499 	}
4500 	else
4501 	{
4502 		interface = new Interface(name, type);
4503 
4504 		m_blocks.push_back(interface);
4505 	}
4506 
4507 	return interface;
4508 }
4509 
4510 /** Adds new block interface
4511  *
4512  * @param name
4513  *
4514  * @return Pointer to created interface
4515  **/
Block(const GLchar * name)4516 Interface* ProgramInterface::Block(const GLchar* name)
4517 {
4518 	return AddInterface(name, Interface::BLOCK);
4519 }
4520 
4521 /** Get interface of given shader stage
4522  *
4523  * @param stage Shader stage
4524  *
4525  * @return Reference to stage interface
4526  **/
GetShaderInterface(Shader::STAGES stage)4527 ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage)
4528 {
4529 	ShaderInterface* interface = 0;
4530 
4531 	switch (stage)
4532 	{
4533 	case Shader::COMPUTE:
4534 		interface = &m_compute;
4535 		break;
4536 	case Shader::FRAGMENT:
4537 		interface = &m_fragment;
4538 		break;
4539 	case Shader::GEOMETRY:
4540 		interface = &m_geometry;
4541 		break;
4542 	case Shader::TESS_CTRL:
4543 		interface = &m_tess_ctrl;
4544 		break;
4545 	case Shader::TESS_EVAL:
4546 		interface = &m_tess_eval;
4547 		break;
4548 	case Shader::VERTEX:
4549 		interface = &m_vertex;
4550 		break;
4551 	default:
4552 		TCU_FAIL("Invalid enum");
4553 	}
4554 
4555 	return *interface;
4556 }
4557 
4558 /** Get interface of given shader stage
4559  *
4560  * @param stage Shader stage
4561  *
4562  * @return Reference to stage interface
4563  **/
GetShaderInterface(Shader::STAGES stage) const4564 const ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage) const
4565 {
4566 	const ShaderInterface* interface = 0;
4567 
4568 	switch (stage)
4569 	{
4570 	case Shader::COMPUTE:
4571 		interface = &m_compute;
4572 		break;
4573 	case Shader::FRAGMENT:
4574 		interface = &m_fragment;
4575 		break;
4576 	case Shader::GEOMETRY:
4577 		interface = &m_geometry;
4578 		break;
4579 	case Shader::TESS_CTRL:
4580 		interface = &m_tess_ctrl;
4581 		break;
4582 	case Shader::TESS_EVAL:
4583 		interface = &m_tess_eval;
4584 		break;
4585 	case Shader::VERTEX:
4586 		interface = &m_vertex;
4587 		break;
4588 	default:
4589 		TCU_FAIL("Invalid enum");
4590 	}
4591 
4592 	return *interface;
4593 }
4594 
4595 /** Clone interface of Vertex shader stage to other stages
4596  * It creates matching inputs, outputs, uniforms and buffers in other stages.
4597  * There are no additional outputs for FRAGMENT shader generated.
4598  *
4599  * @param varying_passthrough Collection of varyings connections
4600  **/
CloneVertexInterface(VaryingPassthrough & varying_passthrough)4601 void ProgramInterface::CloneVertexInterface(VaryingPassthrough& varying_passthrough)
4602 {
4603 	/* VS outputs >> TCS inputs >> TCS outputs >> ..  >> FS inputs */
4604 	for (size_t i = 0; i < m_vertex.m_outputs.size(); ++i)
4605 	{
4606 		const Variable& vs_var = *m_vertex.m_outputs[i];
4607 		const GLchar*   prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4608 
4609 		cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4610 		cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4611 		cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4612 		cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4613 	}
4614 
4615 	/* Copy uniforms from VS to other stages */
4616 	for (size_t i = 0; i < m_vertex.m_uniforms.size(); ++i)
4617 	{
4618 		Variable&	 vs_var = *m_vertex.m_uniforms[i];
4619 		const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4620 
4621 		cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4622 		cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4623 		cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4624 		cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4625 		cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4626 
4627 		/* Uniform blocks needs unique binding */
4628 		if (true == vs_var.IsBlock())
4629 		{
4630 			replaceBinding(vs_var, Shader::VERTEX);
4631 		}
4632 	}
4633 
4634 	/* Copy SSBs from VS to other stages */
4635 	for (size_t i = 0; i < m_vertex.m_ssb_blocks.size(); ++i)
4636 	{
4637 		Variable&	 vs_var = *m_vertex.m_ssb_blocks[i];
4638 		const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4639 
4640 		cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4641 		cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4642 		cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4643 		cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4644 		cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4645 
4646 		/* SSBs blocks needs unique binding */
4647 		if (true == vs_var.IsBlock())
4648 		{
4649 			replaceBinding(vs_var, Shader::VERTEX);
4650 		}
4651 	}
4652 
4653 	m_compute.m_globals   = m_vertex.m_globals;
4654 	m_fragment.m_globals  = m_vertex.m_globals;
4655 	m_geometry.m_globals  = m_vertex.m_globals;
4656 	m_tess_ctrl.m_globals = m_vertex.m_globals;
4657 	m_tess_eval.m_globals = m_vertex.m_globals;
4658 }
4659 
4660 /** Clone variable for specific stage
4661  *
4662  * @param variable            Variable
4663  * @param stage               Requested stage
4664  * @param prefix              Prefix used in variable name that is specific for original stage
4665  * @param varying_passthrough Collection of varyings connections
4666  **/
cloneVariableForStage(const Variable & variable,Shader::STAGES stage,const GLchar * prefix,VaryingPassthrough & varying_passthrough)4667 void ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage, const GLchar* prefix,
4668 											 VaryingPassthrough& varying_passthrough)
4669 {
4670 	switch (variable.m_storage)
4671 	{
4672 	case Variable::VARYING_OUTPUT:
4673 	{
4674 		Variable* in = cloneVariableForStage(variable, stage, Variable::VARYING_INPUT, prefix);
4675 
4676 		if (Shader::FRAGMENT != stage)
4677 		{
4678 			Variable* out = cloneVariableForStage(variable, stage, Variable::VARYING_OUTPUT, prefix);
4679 			varying_passthrough.Add(stage, in, out);
4680 		}
4681 	}
4682 	break;
4683 	case Variable::UNIFORM:
4684 	case Variable::SSB:
4685 		cloneVariableForStage(variable, stage, variable.m_storage, prefix);
4686 		break;
4687 	default:
4688 		TCU_FAIL("Invalid enum");
4689 	}
4690 }
4691 
4692 /** Clone variable for specific stage
4693  *
4694  * @param variable Variable
4695  * @param stage    Requested stage
4696  * @param storage  Storage used by variable
4697  * @param prefix   Prefix used in variable name that is specific for original stage
4698  *
4699  * @return New variable
4700  **/
cloneVariableForStage(const Variable & variable,Shader::STAGES stage,Variable::STORAGE storage,const GLchar * prefix)4701 Variable* ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage,
4702 												  Variable::STORAGE storage, const GLchar* prefix)
4703 {
4704 	/* Initialize with original variable */
4705 	Variable* var = new Variable(variable);
4706 	if (0 == var)
4707 	{
4708 		TCU_FAIL("Memory allocation");
4709 	}
4710 
4711 	/* Set up storage */
4712 	var->m_storage = storage;
4713 
4714 	/* Get name */
4715 	std::string name = variable.m_descriptor.m_name;
4716 
4717 	/* Prefix name with stage ID, empty means default block */
4718 	if (false == name.empty())
4719 	{
4720 		size_t		  position	 = 0;
4721 		const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4722 		Utils::replaceToken(prefix, position, stage_prefix, name);
4723 	}
4724 	var->m_descriptor.m_name = name;
4725 
4726 	/* Clone block */
4727 	const bool is_block = variable.IsBlock();
4728 	if (true == is_block)
4729 	{
4730 		const Interface* interface = variable.m_descriptor.m_interface;
4731 
4732 		Interface* block = CloneBlockForStage(*interface, stage, storage, prefix);
4733 
4734 		var->m_descriptor.m_interface = block;
4735 	}
4736 
4737 	/* Store variable */
4738 	ShaderInterface& si		= GetShaderInterface(stage);
4739 	Variable*		 result = 0;
4740 
4741 	switch (storage)
4742 	{
4743 	case Variable::VARYING_INPUT:
4744 		si.m_inputs.push_back(var);
4745 		result = si.m_inputs.back();
4746 		break;
4747 	case Variable::VARYING_OUTPUT:
4748 		si.m_outputs.push_back(var);
4749 		result = si.m_outputs.back();
4750 		break;
4751 	case Variable::UNIFORM:
4752 		/* Uniform blocks needs unique binding */
4753 		if (true == is_block)
4754 		{
4755 			replaceBinding(*var, stage);
4756 		}
4757 
4758 		si.m_uniforms.push_back(var);
4759 		result = si.m_uniforms.back();
4760 		break;
4761 	case Variable::SSB:
4762 		/* SSBs needs unique binding */
4763 		if (true == is_block)
4764 		{
4765 			replaceBinding(*var, stage);
4766 		}
4767 
4768 		si.m_ssb_blocks.push_back(var);
4769 		result = si.m_ssb_blocks.back();
4770 		break;
4771 	default:
4772 		TCU_FAIL("Invalid enum");
4773 	}
4774 
4775 	return result;
4776 }
4777 
4778 /** clone block to specific stage
4779  *
4780  * @param block   Block to be copied
4781  * @param stage   Specific stage
4782  * @param storage Storage used by block
4783  * @param prefix  Prefix used in block name
4784  *
4785  * @return New interface
4786  **/
CloneBlockForStage(const Interface & block,Shader::STAGES stage,Variable::STORAGE storage,const GLchar * prefix)4787 Interface* ProgramInterface::CloneBlockForStage(const Interface& block, Shader::STAGES stage, Variable::STORAGE storage,
4788 												const GLchar* prefix)
4789 {
4790 	/* Get name */
4791 	std::string name = block.m_name;
4792 
4793 	/* Prefix name with stage ID */
4794 	size_t		  position	 = 0;
4795 	const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4796 	Utils::replaceToken(prefix, position, stage_prefix, name);
4797 
4798 	Interface* ptr = GetBlock(name.c_str());
4799 
4800 	if (0 == ptr)
4801 	{
4802 		ptr = AddInterface(name.c_str(), Interface::BLOCK);
4803 	}
4804 
4805 	ptr->m_members = block.m_members;
4806 
4807 	return ptr;
4808 }
4809 
4810 /** Get stage specific prefix used in names
4811  *
4812  * @param stage   Stage
4813  * @param storage Storage class
4814  *
4815  * @return String
4816  **/
GetStagePrefix(Shader::STAGES stage,Variable::STORAGE storage)4817 const GLchar* ProgramInterface::GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage)
4818 {
4819 	static const GLchar* lut[Shader::STAGE_MAX][Variable::STORAGE_MAX] = {
4820 		/*          IN          OUT         UNIFORM     SSB        MEMBER	*/
4821 		/* CS  */ { 0, 0, "cs_uni_", "cs_buf_", "" },
4822 		/* VS  */ { "in_vs_", "vs_tcs_", "vs_uni_", "vs_buf_", "" },
4823 		/* TCS */ { "vs_tcs_", "tcs_tes_", "tcs_uni_", "tcs_buf_", "" },
4824 		/* TES */ { "tcs_tes_", "tes_gs_", "tes_uni_", "tes_buf_", "" },
4825 		/* GS  */ { "tes_gs_", "gs_fs_", "gs_uni_", "gs_buf_", "" },
4826 		/* FS  */ { "gs_fs_", "fs_out_", "fs_uni_", "fs_buf_", "" },
4827 	};
4828 
4829 	const GLchar* result = 0;
4830 
4831 	result = lut[stage][storage];
4832 
4833 	return result;
4834 }
4835 
4836 /** Get definitions of all structures used in program interface
4837  *
4838  * @return String with code
4839  **/
GetDefinitionsStructures() const4840 std::string ProgramInterface::GetDefinitionsStructures() const
4841 {
4842 	return GetDefinitions(m_structures);
4843 }
4844 
4845 /** Get interface code for stage
4846  *
4847  * @param stage Specific stage
4848  *
4849  * @return String with code
4850  **/
GetInterfaceForStage(Shader::STAGES stage) const4851 std::string ProgramInterface::GetInterfaceForStage(Shader::STAGES stage) const
4852 {
4853 	size_t		position  = 0;
4854 	std::string interface = "/* Globals */\n"
4855 							"GLOBALS\n"
4856 							"\n"
4857 							"/* Structures */\n"
4858 							"STRUCTURES\n"
4859 							"\n"
4860 							"/* Uniforms */\n"
4861 							"UNIFORMS\n"
4862 							"\n"
4863 							"/* Inputs */\n"
4864 							"INPUTS\n"
4865 							"\n"
4866 							"/* Outputs */\n"
4867 							"OUTPUTS\n"
4868 							"\n"
4869 							"/* Storage */\n"
4870 							"STORAGE\n";
4871 
4872 	const ShaderInterface& si = GetShaderInterface(stage);
4873 
4874 	const std::string& structures = GetDefinitionsStructures();
4875 
4876 	const std::string& globals  = si.GetDefinitionsGlobals();
4877 	const std::string& inputs   = si.GetDefinitionsInputs();
4878 	const std::string& outputs  = si.GetDefinitionsOutputs();
4879 	const std::string& uniforms = si.GetDefinitionsUniforms();
4880 	const std::string& ssbs		= si.GetDefinitionsSSBs();
4881 
4882 	replaceToken("GLOBALS", position, globals.c_str(), interface);
4883 	replaceToken("STRUCTURES", position, structures.c_str(), interface);
4884 	replaceToken("UNIFORMS", position, uniforms.c_str(), interface);
4885 	replaceToken("INPUTS", position, inputs.c_str(), interface);
4886 	replaceToken("OUTPUTS", position, outputs.c_str(), interface);
4887 	replaceToken("STORAGE", position, ssbs.c_str(), interface);
4888 
4889 	return interface;
4890 }
4891 
4892 /** Functional object used in find_if algorithm, in search for interface of given name
4893  *
4894  **/
4895 struct matchInterfaceName
4896 {
matchInterfaceNamegl4cts::EnhancedLayouts::Utils::matchInterfaceName4897 	matchInterfaceName(const GLchar* name) : m_name(name)
4898 	{
4899 	}
4900 
operator ()gl4cts::EnhancedLayouts::Utils::matchInterfaceName4901 	bool operator()(const Interface* interface)
4902 	{
4903 		return 0 == interface->m_name.compare(m_name);
4904 	}
4905 
4906 	const GLchar* m_name;
4907 };
4908 
4909 /** Finds interface of given name in given vector of interfaces
4910  *
4911  * @param vector Collection of interfaces
4912  * @param name   Requested name
4913  *
4914  * @return Pointer to interface if available, 0 otherwise
4915  **/
findInterfaceByName(Interface::PtrVector & vector,const GLchar * name)4916 static Interface* findInterfaceByName(Interface::PtrVector& vector, const GLchar* name)
4917 {
4918 	Interface::PtrVector::iterator it = std::find_if(vector.begin(), vector.end(), matchInterfaceName(name));
4919 
4920 	if (vector.end() != it)
4921 	{
4922 		return *it;
4923 	}
4924 	else
4925 	{
4926 		return 0;
4927 	}
4928 }
4929 
4930 /** Search for block of given name
4931  *
4932  * @param name Name of block
4933  *
4934  * @return Pointer to block or 0
4935  **/
GetBlock(const GLchar * name)4936 Interface* ProgramInterface::GetBlock(const GLchar* name)
4937 {
4938 	return findInterfaceByName(m_blocks, name);
4939 }
4940 
4941 /** Search for structure of given name
4942  *
4943  * @param name Name of structure
4944  *
4945  * @return Pointer to structure or 0
4946  **/
GetStructure(const GLchar * name)4947 Interface* ProgramInterface::GetStructure(const GLchar* name)
4948 {
4949 	return findInterfaceByName(m_structures, name);
4950 }
4951 
4952 /** Adds new sturcture to interface
4953  *
4954  * @param name Name of structure
4955  *
4956  * @return Created structure
4957  **/
Structure(const GLchar * name)4958 Interface* ProgramInterface::Structure(const GLchar* name)
4959 {
4960 	return AddInterface(name, Interface::STRUCT);
4961 }
4962 
4963 /** Replace "BINDING" token in qualifiers string to value specific for given stage
4964  *
4965  * @param variable Variable to modify
4966  * @param stage    Requested stage
4967  **/
replaceBinding(Variable & variable,Shader::STAGES stage)4968 void ProgramInterface::replaceBinding(Variable& variable, Shader::STAGES stage)
4969 {
4970 	GLchar binding[16];
4971 	sprintf(binding, "%d", stage);
4972 	replaceAllTokens("BINDING", binding, variable.m_descriptor.m_qualifiers);
4973 }
4974 } /* Utils namespace */
4975 
4976 /** Debuging procedure. Logs parameters.
4977  *
4978  * @param source   As specified in GL spec.
4979  * @param type     As specified in GL spec.
4980  * @param id       As specified in GL spec.
4981  * @param severity As specified in GL spec.
4982  * @param ignored
4983  * @param message  As specified in GL spec.
4984  * @param info     Pointer to instance of Context used by test.
4985  */
debug_proc(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei,const GLchar * message,void * info)4986 void GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */,
4987 							 const GLchar* message, void* info)
4988 {
4989 	deqp::Context* ctx = (deqp::Context*)info;
4990 
4991 	const GLchar* source_str   = "Unknown";
4992 	const GLchar* type_str	 = "Unknown";
4993 	const GLchar* severity_str = "Unknown";
4994 
4995 	switch (source)
4996 	{
4997 	case GL_DEBUG_SOURCE_API:
4998 		source_str = "API";
4999 		break;
5000 	case GL_DEBUG_SOURCE_APPLICATION:
5001 		source_str = "APP";
5002 		break;
5003 	case GL_DEBUG_SOURCE_OTHER:
5004 		source_str = "OTR";
5005 		break;
5006 	case GL_DEBUG_SOURCE_SHADER_COMPILER:
5007 		source_str = "COM";
5008 		break;
5009 	case GL_DEBUG_SOURCE_THIRD_PARTY:
5010 		source_str = "3RD";
5011 		break;
5012 	case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
5013 		source_str = "WS";
5014 		break;
5015 	default:
5016 		break;
5017 	}
5018 
5019 	switch (type)
5020 	{
5021 	case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
5022 		type_str = "DEPRECATED_BEHAVIOR";
5023 		break;
5024 	case GL_DEBUG_TYPE_ERROR:
5025 		type_str = "ERROR";
5026 		break;
5027 	case GL_DEBUG_TYPE_MARKER:
5028 		type_str = "MARKER";
5029 		break;
5030 	case GL_DEBUG_TYPE_OTHER:
5031 		type_str = "OTHER";
5032 		break;
5033 	case GL_DEBUG_TYPE_PERFORMANCE:
5034 		type_str = "PERFORMANCE";
5035 		break;
5036 	case GL_DEBUG_TYPE_POP_GROUP:
5037 		type_str = "POP_GROUP";
5038 		break;
5039 	case GL_DEBUG_TYPE_PORTABILITY:
5040 		type_str = "PORTABILITY";
5041 		break;
5042 	case GL_DEBUG_TYPE_PUSH_GROUP:
5043 		type_str = "PUSH_GROUP";
5044 		break;
5045 	case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
5046 		type_str = "UNDEFINED_BEHAVIOR";
5047 		break;
5048 	default:
5049 		break;
5050 	}
5051 
5052 	switch (severity)
5053 	{
5054 	case GL_DEBUG_SEVERITY_HIGH:
5055 		severity_str = "H";
5056 		break;
5057 	case GL_DEBUG_SEVERITY_LOW:
5058 		severity_str = "L";
5059 		break;
5060 	case GL_DEBUG_SEVERITY_MEDIUM:
5061 		severity_str = "M";
5062 		break;
5063 	case GL_DEBUG_SEVERITY_NOTIFICATION:
5064 		severity_str = "N";
5065 		break;
5066 	default:
5067 		break;
5068 	}
5069 
5070 	ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
5071 								   << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
5072 								   << ": " << message << tcu::TestLog::EndMessage;
5073 }
5074 
5075 /** Constructor
5076  *
5077  * @param context          Test context
5078  * @param test_name        Test name
5079  * @param test_description Test description
5080  **/
TestBase(deqp::Context & context,const GLchar * test_name,const GLchar * test_description)5081 TestBase::TestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5082 	: TestCase(context, test_name, test_description)
5083 {
5084 	/* Nothing to be done here */
5085 }
5086 
5087 /** Execute test
5088  *
5089  * @return tcu::TestNode::STOP otherwise
5090  **/
iterate()5091 tcu::TestNode::IterateResult TestBase::iterate()
5092 {
5093 	bool test_result;
5094 
5095 #if DEBUG_ENBALE_MESSAGE_CALLBACK
5096 	const Functions& gl = m_context.getRenderContext().getFunctions();
5097 
5098 	gl.debugMessageCallback(debug_proc, &m_context);
5099 	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
5100 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
5101 
5102 	try
5103 	{
5104 		/* Execute test */
5105 		test_result = test();
5106 	}
5107 	catch (std::exception& exc)
5108 	{
5109 		TCU_FAIL(exc.what());
5110 	}
5111 
5112 	/* Set result */
5113 	if (true == test_result)
5114 	{
5115 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
5116 	}
5117 	else
5118 	{
5119 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5120 	}
5121 
5122 	/* Done */
5123 	return tcu::TestNode::STOP;
5124 }
5125 
5126 /** Get last input location available for given type at specific stage
5127  *
5128  * @param stage        Shader stage
5129  * @param type         Input type
5130  * @param array_length Length of input array
5131  *
5132  * @return Last location index
5133  **/
getLastInputLocation(Utils::Shader::STAGES stage,const Utils::Type & type,GLuint array_length,bool ignore_prev_stage)5134 GLint TestBase::getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length, bool ignore_prev_stage)
5135 {
5136 	GLint  divide		= 4; /* 4 components per location */
5137 	GLint  param		= 0;
5138 	GLenum pname		= 0;
5139 	GLint  paramPrev	= 0;
5140 	GLenum pnamePrev	= 0;
5141 
5142 	/* Select pnmae */
5143 	switch (stage)
5144 	{
5145 	case Utils::Shader::FRAGMENT:
5146 		pname = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5147 		pnamePrev = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5148 		break;
5149 	case Utils::Shader::GEOMETRY:
5150 		pname = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5151 		pnamePrev = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5152 		break;
5153 	case Utils::Shader::TESS_CTRL:
5154 		pname = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5155 		pnamePrev = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5156 		break;
5157 	case Utils::Shader::TESS_EVAL:
5158 		pname = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5159 		pnamePrev = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5160 		break;
5161 	case Utils::Shader::VERTEX:
5162 		pname  = GL_MAX_VERTEX_ATTRIBS;
5163 		divide = 1;
5164 		break;
5165 	default:
5166 		TCU_FAIL("Invalid enum");
5167 	}
5168 
5169 	/* Zero means no array, but 1 slot is required */
5170 	if (0 == array_length)
5171 	{
5172 		array_length += 1;
5173 	}
5174 
5175 	/* Get MAX */
5176 	const Functions& gl = m_context.getRenderContext().getFunctions();
5177 
5178 	gl.getIntegerv(pname, &param);
5179 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5180 
5181 	if (pnamePrev && !ignore_prev_stage) {
5182 		gl.getIntegerv(pnamePrev, &paramPrev);
5183 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5184 
5185 		/* Don't read from a location that doesn't exist in the previous stage */
5186 		param = de::min(param, paramPrev);
5187 	}
5188 
5189 /* Calculate */
5190 #if WRKARD_VARYINGLOCATIONSTEST
5191 
5192 	const GLint n_avl_locations = 16;
5193 
5194 #else
5195 
5196 	const GLint n_avl_locations = param / divide;
5197 
5198 #endif
5199 
5200 	const GLuint n_req_location = type.GetLocations(stage == Utils::Shader::VERTEX) * array_length;
5201 
5202 	return n_avl_locations - n_req_location; /* last is max - 1 */
5203 }
5204 
5205 /** Get last output location available for given type at specific stage
5206  *
5207  * @param stage        Shader stage
5208  * @param type         Input type
5209  * @param array_length Length of input array
5210  *
5211  * @return Last location index
5212  **/
getLastOutputLocation(Utils::Shader::STAGES stage,const Utils::Type & type,GLuint array_length,bool ignore_next_stage)5213 GLint TestBase::getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length, bool ignore_next_stage)
5214 {
5215 	GLint  param		= 0;
5216 	GLenum pname		= 0;
5217 	GLint  paramNext	= 0;
5218 	GLenum pnameNext	= 0;
5219 
5220 	/* Select pname */
5221 	switch (stage)
5222 	{
5223 	case Utils::Shader::GEOMETRY:
5224 		pname = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5225 		pnameNext = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5226 		break;
5227 	case Utils::Shader::TESS_CTRL:
5228 		pname = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5229 		pnameNext = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5230 		break;
5231 	case Utils::Shader::TESS_EVAL:
5232 		pname = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5233 		pnameNext = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5234 		break;
5235 	case Utils::Shader::VERTEX:
5236 		pname = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5237 		pnameNext = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5238 		break;
5239 	default:
5240 		TCU_FAIL("Invalid enum");
5241 	}
5242 
5243 	/* Zero means no array, but 1 slot is required */
5244 	if (0 == array_length)
5245 	{
5246 		array_length += 1;
5247 	}
5248 
5249 	/* Get MAX */
5250 	const Functions& gl = m_context.getRenderContext().getFunctions();
5251 
5252 	gl.getIntegerv(pname, &param);
5253 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5254 
5255 /* Calculate */
5256 #if WRKARD_VARYINGLOCATIONSTEST
5257 
5258 	const GLint n_avl_locations = 16;
5259 
5260 #else
5261 
5262 	/* Don't write to a location that doesn't exist in the next stage */
5263 	if (!ignore_next_stage)
5264 	{
5265 		gl.getIntegerv(pnameNext, &paramNext);
5266 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5267 
5268 		param = de::min(param, paramNext);
5269 	}
5270 
5271 	const GLint n_avl_locations = param / 4; /* 4 components per location */
5272 
5273 #endif
5274 
5275 	const GLuint n_req_location = type.GetLocations() * array_length;
5276 
5277 	return n_avl_locations - n_req_location; /* last is max - 1 */
5278 }
5279 
5280 /** Basic implementation
5281  *
5282  * @param ignored
5283  *
5284  * @return Empty string
5285  **/
getTestCaseName(GLuint)5286 std::string TestBase::getTestCaseName(GLuint /* test_case_index */)
5287 {
5288 	std::string result;
5289 
5290 	return result;
5291 }
5292 
5293 /** Basic implementation
5294  *
5295  * @return 1
5296  **/
getTestCaseNumber()5297 GLuint TestBase::getTestCaseNumber()
5298 {
5299 	return 1;
5300 }
5301 
5302 /** Check if flat qualifier is required for given type, stage and storage
5303  *
5304  * @param stage        Shader stage
5305  * @param type         Input type
5306  * @param storage      Storage of variable
5307  *
5308  * @return Last location index
5309  **/
isFlatRequired(Utils::Shader::STAGES stage,const Utils::Type & type,Utils::Variable::STORAGE storage,const bool coherent) const5310 bool TestBase::isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type& type, Utils::Variable::STORAGE storage,
5311 							  const bool coherent) const
5312 {
5313 	/* Float types do not need flat at all */
5314 	if (Utils::Type::Float == type.m_basic_type)
5315 	{
5316 		return false;
5317 	}
5318 
5319 	/* Inputs to fragment shader */
5320 	if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_INPUT == storage))
5321 	{
5322 		return true;
5323 	}
5324 
5325 	/* Outputs from geometry shader
5326 	 *
5327 	 * This is not strictly needed since fragment shader input
5328 	 * interpolation qualifiers will override whatever comes from the
5329 	 * previous stage. However, if we want to have a coherent
5330 	 * interface, let's better do it.
5331 	 */
5332 	if ((Utils::Shader::GEOMETRY == stage) && (Utils::Variable::VARYING_OUTPUT == storage) && coherent)
5333 	{
5334 		return true;
5335 	}
5336 
5337 	return false;
5338 }
5339 
5340 /** Basic implementation of testInit method
5341  *
5342  **/
testInit()5343 void TestBase::testInit()
5344 {
5345 }
5346 
5347 /** Calculate stride for interface
5348  *
5349  * @param interface Interface
5350  *
5351  * @return Calculated value
5352  **/
calculateStride(const Utils::Interface & interface) const5353 GLuint TestBase::calculateStride(const Utils::Interface& interface) const
5354 {
5355 	const size_t n_members = interface.m_members.size();
5356 
5357 	GLuint stride = 0;
5358 
5359 	for (size_t i = 0; i < n_members; ++i)
5360 	{
5361 		const Utils::Variable::Descriptor& member		  = interface.m_members[i];
5362 		const GLuint					   member_offset  = member.m_offset;
5363 		const GLuint					   member_stride  = member.m_expected_stride_of_element;
5364 		const GLuint					   member_ends_at = member_offset + member_stride;
5365 
5366 		stride = std::max(stride, member_ends_at);
5367 	}
5368 
5369 	return stride;
5370 }
5371 
5372 /** Generate data for interface. This routine is recursive
5373  *
5374  * @param interface Interface
5375  * @param offset    Offset in out_data
5376  * @param out_data  Buffer to be filled
5377  **/
generateData(const Utils::Interface & interface,GLuint offset,std::vector<GLubyte> & out_data) const5378 void TestBase::generateData(const Utils::Interface& interface, GLuint offset, std::vector<GLubyte>& out_data) const
5379 {
5380 	const size_t n_members = interface.m_members.size();
5381 	GLubyte*	 ptr	   = &out_data[offset];
5382 
5383 	for (size_t i = 0; i < n_members; ++i)
5384 	{
5385 		const Utils::Variable::Descriptor& member		 = interface.m_members[i];
5386 		const GLuint					   member_offset = member.m_offset;
5387 		const GLuint n_elements = (0 == member.m_n_array_elements) ? 1 : member.m_n_array_elements;
5388 
5389 		for (GLuint element = 0; element < n_elements; ++element)
5390 		{
5391 			const GLuint element_offset = element * member.m_expected_stride_of_element;
5392 			const GLuint data_offfset   = member_offset + element_offset;
5393 
5394 			if (Utils::Variable::BUILTIN == member.m_type)
5395 			{
5396 				const std::vector<GLubyte>& data = member.m_builtin.GenerateData();
5397 
5398 				memcpy(ptr + data_offfset, &data[0], data.size());
5399 			}
5400 			else
5401 			{
5402 				generateData(*member.m_interface, offset + data_offfset, out_data);
5403 			}
5404 		}
5405 	}
5406 }
5407 
5408 /** Get type at index
5409  *
5410  * @param index Index of requested type
5411  *
5412  * @return Type
5413  **/
getType(GLuint index) const5414 Utils::Type TestBase::getType(GLuint index) const
5415 {
5416 	Utils::Type type;
5417 
5418 	switch (index)
5419 	{
5420 	case 0:
5421 		type = Utils::Type::_double;
5422 		break;
5423 	case 1:
5424 		type = Utils::Type::dmat2;
5425 		break;
5426 	case 2:
5427 		type = Utils::Type::dmat2x3;
5428 		break;
5429 	case 3:
5430 		type = Utils::Type::dmat2x4;
5431 		break;
5432 	case 4:
5433 		type = Utils::Type::dmat3;
5434 		break;
5435 	case 5:
5436 		type = Utils::Type::dmat3x2;
5437 		break;
5438 	case 6:
5439 		type = Utils::Type::dmat3x4;
5440 		break;
5441 	case 7:
5442 		type = Utils::Type::dmat4;
5443 		break;
5444 	case 8:
5445 		type = Utils::Type::dmat4x2;
5446 		break;
5447 	case 9:
5448 		type = Utils::Type::dmat4x3;
5449 		break;
5450 	case 10:
5451 		type = Utils::Type::dvec2;
5452 		break;
5453 	case 11:
5454 		type = Utils::Type::dvec3;
5455 		break;
5456 	case 12:
5457 		type = Utils::Type::dvec4;
5458 		break;
5459 	case 13:
5460 		type = Utils::Type::_float;
5461 		break;
5462 	case 14:
5463 		type = Utils::Type::mat2;
5464 		break;
5465 	case 15:
5466 		type = Utils::Type::mat2x3;
5467 		break;
5468 	case 16:
5469 		type = Utils::Type::mat2x4;
5470 		break;
5471 	case 17:
5472 		type = Utils::Type::mat3;
5473 		break;
5474 	case 18:
5475 		type = Utils::Type::mat3x2;
5476 		break;
5477 	case 19:
5478 		type = Utils::Type::mat3x4;
5479 		break;
5480 	case 20:
5481 		type = Utils::Type::mat4;
5482 		break;
5483 	case 21:
5484 		type = Utils::Type::mat4x2;
5485 		break;
5486 	case 22:
5487 		type = Utils::Type::mat4x3;
5488 		break;
5489 	case 23:
5490 		type = Utils::Type::vec2;
5491 		break;
5492 	case 24:
5493 		type = Utils::Type::vec3;
5494 		break;
5495 	case 25:
5496 		type = Utils::Type::vec4;
5497 		break;
5498 	case 26:
5499 		type = Utils::Type::_int;
5500 		break;
5501 	case 27:
5502 		type = Utils::Type::ivec2;
5503 		break;
5504 	case 28:
5505 		type = Utils::Type::ivec3;
5506 		break;
5507 	case 29:
5508 		type = Utils::Type::ivec4;
5509 		break;
5510 	case 30:
5511 		type = Utils::Type::uint;
5512 		break;
5513 	case 31:
5514 		type = Utils::Type::uvec2;
5515 		break;
5516 	case 32:
5517 		type = Utils::Type::uvec3;
5518 		break;
5519 	case 33:
5520 		type = Utils::Type::uvec4;
5521 		break;
5522 	default:
5523 		TCU_FAIL("invalid enum");
5524 	}
5525 
5526 	return type;
5527 }
5528 
5529 /** Get name of type at index
5530  *
5531  * @param index Index of type
5532  *
5533  * @return Name
5534  **/
getTypeName(GLuint index) const5535 std::string TestBase::getTypeName(GLuint index) const
5536 {
5537 	std::string name = getType(index).GetGLSLTypeName();
5538 
5539 	return name;
5540 }
5541 
5542 /** Get number of types
5543  *
5544  * @return 34
5545  **/
getTypesNumber() const5546 glw::GLuint TestBase::getTypesNumber() const
5547 {
5548 	return 34;
5549 }
5550 
5551 /** Execute test
5552  *
5553  * @return true if test pass, false otherwise
5554  **/
test()5555 bool TestBase::test()
5556 {
5557 	bool   result		= true;
5558 	GLuint n_test_cases = 0;
5559 
5560 	/* Prepare test */
5561 	testInit();
5562 
5563 	/* GL entry points */
5564 	const Functions& gl = m_context.getRenderContext().getFunctions();
5565 
5566 	/* Tessellation patch set up */
5567 	gl.patchParameteri(GL_PATCH_VERTICES, 1);
5568 	GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
5569 
5570 	/* Get number of test cases */
5571 	n_test_cases = getTestCaseNumber();
5572 
5573 #if DEBUG_REPEAT_TEST_CASE
5574 
5575 	while (1)
5576 	{
5577 		GLuint test_case = DEBUG_REPEATED_TEST_CASE;
5578 
5579 #else /* DEBUG_REPEAT_TEST_CASE */
5580 
5581 	for (GLuint test_case = 0; test_case < n_test_cases; ++test_case)
5582 	{
5583 #endif /* DEBUG_REPEAT_TEST_CASE */
5584 
5585 		/* Execute case */
5586 		if (!testCase(test_case))
5587 		{
5588 			const std::string& test_case_name = getTestCaseName(test_case);
5589 
5590 			if (false == test_case_name.empty())
5591 			{
5592 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case_name
5593 													<< ") failed." << tcu::TestLog::EndMessage;
5594 			}
5595 			else
5596 			{
5597 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case
5598 													<< ") failed." << tcu::TestLog::EndMessage;
5599 			}
5600 
5601 			result = false;
5602 		}
5603 	}
5604 
5605 	/* Done */
5606 	return result;
5607 }
5608 
5609 /* Constants used by BufferTestBase */
5610 const GLuint BufferTestBase::bufferDescriptor::m_non_indexed = -1;
5611 
5612 /** Constructor
5613  *
5614  * @param context          Test context
5615  * @param test_name        Name of test
5616  * @param test_description Description of test
5617  **/
5618 BufferTestBase::BufferTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5619 	: TestBase(context, test_name, test_description)
5620 {
5621 }
5622 
5623 /** Execute drawArrays for single vertex
5624  *
5625  * @param ignored
5626  *
5627  * @return true
5628  **/
5629 bool BufferTestBase::executeDrawCall(bool tesEnabled, GLuint /* test_case_index */)
5630 {
5631 	const Functions& gl = m_context.getRenderContext().getFunctions();
5632 
5633 	gl.disable(GL_RASTERIZER_DISCARD);
5634 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
5635 
5636 	gl.beginTransformFeedback(GL_POINTS);
5637 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
5638 
5639 	// Only TES is existed, glDrawArray can use the parameter GL_PATCHES
5640 	if (tesEnabled == false)
5641 	{
5642 		gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
5643 	}
5644 	else
5645 	{
5646 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
5647 	}
5648 
5649 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
5650 
5651 	gl.endTransformFeedback();
5652 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
5653 
5654 	return true;
5655 }
5656 
5657 /** Get descriptors of buffers necessary for test
5658  *
5659  * @param ignored
5660  * @param ignored
5661  **/
5662 void BufferTestBase::getBufferDescriptors(glw::GLuint /* test_case_index */,
5663 										  bufferDescriptor::Vector& /* out_descriptors */)
5664 {
5665 	/* Nothhing to be done */
5666 }
5667 
5668 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
5669  *
5670  * @param ignored
5671  * @param ignored
5672  **/
5673 void BufferTestBase::getCapturedVaryings(glw::GLuint /* test_case_index */,
5674 										 Utils::Program::NameVector& /* captured_varyings */,
5675 										 GLint* /* xfb_components */)
5676 {
5677 	/* Nothing to be done */
5678 }
5679 
5680 /** Get body of main function for given shader stage
5681  *
5682  * @param ignored
5683  * @param ignored
5684  * @param out_assignments  Set to empty
5685  * @param out_calculations Set to empty
5686  **/
5687 void BufferTestBase::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5688 								   std::string& out_assignments, std::string& out_calculations)
5689 {
5690 	out_assignments  = "";
5691 	out_calculations = "";
5692 }
5693 
5694 /** Get interface of shader
5695  *
5696  * @param ignored
5697  * @param ignored
5698  * @param out_interface Set to ""
5699  **/
5700 void BufferTestBase::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5701 										std::string& out_interface)
5702 {
5703 	out_interface = "";
5704 }
5705 
5706 /** Get source code of shader
5707  *
5708  * @param test_case_index Index of test case
5709  * @param stage           Shader stage
5710  *
5711  * @return Source
5712  **/
5713 std::string BufferTestBase::getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage)
5714 {
5715 	std::string assignments;
5716 	std::string calculations;
5717 	std::string interface;
5718 
5719 	/* */
5720 	getShaderBody(test_case_index, stage, assignments, calculations);
5721 	getShaderInterface(test_case_index, stage, interface);
5722 
5723 	/* */
5724 	std::string source = getShaderTemplate(stage);
5725 
5726 	/* */
5727 	size_t position = 0;
5728 	Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
5729 	Utils::replaceToken("CALCULATIONS", position, calculations.c_str(), source);
5730 	Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
5731 
5732 	/* */
5733 	return source;
5734 }
5735 
5736 /** Inspects program to check if all resources are as expected
5737  *
5738  * @param ignored
5739  * @param ignored
5740  * @param ignored
5741  *
5742  * @return true
5743  **/
5744 bool BufferTestBase::inspectProgram(GLuint /* test_case_index */, Utils::Program& /* program */,
5745 									std::stringstream& /* out_stream */)
5746 {
5747 	return true;
5748 }
5749 
5750 /** Runs test case
5751  *
5752  * @param test_case_index Id of test case
5753  *
5754  * @return true if test case pass, false otherwise
5755  **/
5756 bool BufferTestBase::testCase(GLuint test_case_index)
5757 {
5758 	try
5759 	{
5760 		bufferCollection		   buffers;
5761 		Utils::Program::NameVector captured_varyings;
5762 		bufferDescriptor::Vector   descriptors;
5763 		Utils::Program			   program(m_context);
5764 		Utils::VertexArray		   vao(m_context);
5765 
5766 		/* Get captured varyings */
5767 		GLint xfb_components;
5768 		getCapturedVaryings(test_case_index, captured_varyings, &xfb_components);
5769 
5770 		/* Don't generate shaders that try to capture more XFB components than the implementation's limit */
5771 		if (captured_varyings.size() > 0)
5772 		{
5773 			const Functions& gl	= m_context.getRenderContext().getFunctions();
5774 
5775 			GLint max_xfb_components;
5776 			gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_components);
5777 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5778 
5779 			if (xfb_components > max_xfb_components)
5780 				return true;
5781 		}
5782 
5783 		/* Get shader sources */
5784 		const std::string& fragment_shader  = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
5785 		const std::string& geometry_shader  = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
5786 		const std::string& tess_ctrl_shader = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
5787 		const std::string& tess_eval_shader = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
5788 		const std::string& vertex_shader	= getShaderSource(test_case_index, Utils::Shader::VERTEX);
5789 
5790 		/* Set up program */
5791 		program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
5792 					 vertex_shader, captured_varyings, true, false /* is_separable */);
5793 
5794 		/* Inspection */
5795 		{
5796 			std::stringstream stream;
5797 			if (false == inspectProgram(test_case_index, program, stream))
5798 			{
5799 				m_context.getTestContext().getLog()
5800 					<< tcu::TestLog::Message
5801 					<< "Program inspection failed. Test case: " << getTestCaseName(test_case_index)
5802 					<< ". Reason: " << stream.str() << tcu::TestLog::EndMessage
5803 					<< tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5804 					<< tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5805 					<< tcu::TestLog::KernelSource(fragment_shader);
5806 
5807 				return false;
5808 			}
5809 		}
5810 
5811 		program.Use();
5812 
5813 		/* Set up buffers */
5814 		getBufferDescriptors(test_case_index, descriptors);
5815 		cleanBuffers();
5816 		prepareBuffers(descriptors, buffers);
5817 
5818 		/* Set up vao */
5819 		vao.Init();
5820 		vao.Bind();
5821 
5822 		/* Draw */
5823 		bool result = executeDrawCall((program.m_tess_eval.m_id != 0), test_case_index);
5824 
5825 #if USE_NSIGHT
5826 		m_context.getRenderContext().postIterate();
5827 #endif
5828 
5829 		if (false == result)
5830 		{
5831 			m_context.getTestContext().getLog()
5832 				<< tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5833 				<< tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5834 				<< tcu::TestLog::KernelSource(fragment_shader);
5835 
5836 			return false;
5837 		}
5838 
5839 		/* Verify result */
5840 		if (false == verifyBuffers(buffers))
5841 		{
5842 			m_context.getTestContext().getLog()
5843 				<< tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5844 				<< tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5845 				<< tcu::TestLog::KernelSource(fragment_shader);
5846 
5847 			return false;
5848 		}
5849 	}
5850 	catch (Utils::Shader::InvalidSourceException& exc)
5851 	{
5852 		exc.log(m_context);
5853 		TCU_FAIL(exc.what());
5854 	}
5855 	catch (Utils::Program::BuildException& exc)
5856 	{
5857 		exc.log(m_context);
5858 		TCU_FAIL(exc.what());
5859 	}
5860 
5861 	/* Done */
5862 	return true;
5863 }
5864 
5865 /** Verify contents of buffers
5866  *
5867  * @param buffers Collection of buffers to be verified
5868  *
5869  * @return true if everything is as expected, false otherwise
5870  **/
5871 bool BufferTestBase::verifyBuffers(bufferCollection& buffers)
5872 {
5873 	bool result = true;
5874 
5875 	for (bufferCollection::Vector::iterator it = buffers.m_vector.begin(), end = buffers.m_vector.end(); end != it;
5876 		 ++it)
5877 	{
5878 		bufferCollection::pair& pair	   = *it;
5879 		Utils::Buffer*			buffer	 = pair.m_buffer;
5880 		bufferDescriptor*		descriptor = pair.m_descriptor;
5881 		size_t					size	   = descriptor->m_expected_data.size();
5882 
5883 		/* Skip buffers that have no expected data */
5884 		if (0 == size)
5885 		{
5886 			continue;
5887 		}
5888 
5889 		/* Get pointer to contents of buffer */
5890 		buffer->Bind();
5891 		GLvoid* buffer_data = buffer->Map(Utils::Buffer::ReadOnly);
5892 
5893 		/* Get pointer to expected data */
5894 		GLvoid* expected_data = &descriptor->m_expected_data[0];
5895 
5896 		/* Compare */
5897 		int res = memcmp(buffer_data, expected_data, size);
5898 
5899 		if (0 != res)
5900 		{
5901 			m_context.getTestContext().getLog()
5902 				<< tcu::TestLog::Message
5903 				<< "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
5904 				<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
5905 
5906 			result = false;
5907 		}
5908 
5909 		/* Release buffer mapping */
5910 		buffer->UnMap();
5911 	}
5912 
5913 	return result;
5914 }
5915 
5916 /** Unbinds all uniforms and xfb
5917  *
5918  **/
5919 void BufferTestBase::cleanBuffers()
5920 {
5921 	const Functions& gl = m_context.getRenderContext().getFunctions();
5922 
5923 	GLint max_uni = 0;
5924 	GLint max_xfb = 0;
5925 
5926 	gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uni);
5927 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
5928 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5929 
5930 	for (GLint i = 0; i < max_uni; ++i)
5931 	{
5932 		Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Uniform, i);
5933 	}
5934 
5935 	for (GLint i = 0; i < max_xfb; ++i)
5936 	{
5937 		Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Transform_feedback, i);
5938 	}
5939 }
5940 
5941 /** Get template of shader for given stage
5942  *
5943  * @param stage Stage
5944  *
5945  * @return Template of shader source
5946  **/
5947 std::string BufferTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
5948 {
5949 	static const GLchar* compute_shader_template = "#version 430 core\n"
5950 												   "#extension GL_ARB_enhanced_layouts : require\n"
5951 												   "\n"
5952 												   "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
5953 												   "\n"
5954 												   "writeonly uniform uimage2D uni_image;\n"
5955 												   "\n"
5956 												   "INTERFACE"
5957 												   "\n"
5958 												   "void main()\n"
5959 												   "{\n"
5960 												   "CALCULATIONS"
5961 												   "\n"
5962 												   "ASSIGNMENTS"
5963 												   "}\n"
5964 												   "\n";
5965 
5966 	static const GLchar* fragment_shader_template = "#version 430 core\n"
5967 													"#extension GL_ARB_enhanced_layouts : require\n"
5968 													"\n"
5969 													"INTERFACE"
5970 													"\n"
5971 													"void main()\n"
5972 													"{\n"
5973 													"CALCULATIONS"
5974 													"\n"
5975 													"ASSIGNMENTS"
5976 													"}\n"
5977 													"\n";
5978 
5979 	// max_vertices is set to 3 for the test case "xfb_vertex_streams" declares 3 streams in geometry shader,
5980 	// according to spec, max_vertices should be no less than 3 if there are 3 streams in GS.
5981 	static const GLchar* geometry_shader_template = "#version 430 core\n"
5982 													"#extension GL_ARB_enhanced_layouts : require\n"
5983 													"\n"
5984 													"layout(points)                   in;\n"
5985 													"layout(points, max_vertices = 3) out;\n"
5986 													"\n"
5987 													"INTERFACE"
5988 													"\n"
5989 													"void main()\n"
5990 													"{\n"
5991 													"CALCULATIONS"
5992 													"\n"
5993 													"\n"
5994 													"ASSIGNMENTS"
5995 													"    gl_Position  = vec4(0, 0, 0, 1);\n"
5996 													"    EmitVertex();\n"
5997 													"}\n"
5998 													"\n";
5999 
6000 	static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
6001 													 "#extension GL_ARB_enhanced_layouts : require\n"
6002 													 "\n"
6003 													 "layout(vertices = 1) out;\n"
6004 													 "\n"
6005 													 "INTERFACE"
6006 													 "\n"
6007 													 "void main()\n"
6008 													 "{\n"
6009 													 "CALCULATIONS"
6010 													 "\n"
6011 													 "ASSIGNMENTS"
6012 													 "\n"
6013 													 "    gl_TessLevelOuter[0] = 1.0;\n"
6014 													 "    gl_TessLevelOuter[1] = 1.0;\n"
6015 													 "    gl_TessLevelOuter[2] = 1.0;\n"
6016 													 "    gl_TessLevelOuter[3] = 1.0;\n"
6017 													 "    gl_TessLevelInner[0] = 1.0;\n"
6018 													 "    gl_TessLevelInner[1] = 1.0;\n"
6019 													 "}\n"
6020 													 "\n";
6021 
6022 	static const GLchar* tess_eval_shader_template = "#version 430 core\n"
6023 													 "#extension GL_ARB_enhanced_layouts : require\n"
6024 													 "\n"
6025 													 "layout(isolines, point_mode) in;\n"
6026 													 "\n"
6027 													 "INTERFACE"
6028 													 "\n"
6029 													 "void main()\n"
6030 													 "{\n"
6031 													 "CALCULATIONS"
6032 													 "\n"
6033 													 "ASSIGNMENTS"
6034 													 "}\n"
6035 													 "\n";
6036 
6037 	static const GLchar* vertex_shader_template = "#version 430 core\n"
6038 												  "#extension GL_ARB_enhanced_layouts : require\n"
6039 												  "\n"
6040 												  "INTERFACE"
6041 												  "\n"
6042 												  "void main()\n"
6043 												  "{\n"
6044 												  "CALCULATIONS"
6045 												  "\n"
6046 												  "ASSIGNMENTS"
6047 												  "}\n"
6048 												  "\n";
6049 
6050 	const GLchar* result = 0;
6051 
6052 	switch (stage)
6053 	{
6054 	case Utils::Shader::COMPUTE:
6055 		result = compute_shader_template;
6056 		break;
6057 	case Utils::Shader::FRAGMENT:
6058 		result = fragment_shader_template;
6059 		break;
6060 	case Utils::Shader::GEOMETRY:
6061 		result = geometry_shader_template;
6062 		break;
6063 	case Utils::Shader::TESS_CTRL:
6064 		result = tess_ctrl_shader_template;
6065 		break;
6066 	case Utils::Shader::TESS_EVAL:
6067 		result = tess_eval_shader_template;
6068 		break;
6069 	case Utils::Shader::VERTEX:
6070 		result = vertex_shader_template;
6071 		break;
6072 	default:
6073 		TCU_FAIL("Invalid enum");
6074 	}
6075 
6076 	return result;
6077 }
6078 
6079 /** Prepare buffer according to descriptor
6080  *
6081  * @param buffer Buffer to prepare
6082  * @param desc   Descriptor
6083  **/
6084 void BufferTestBase::prepareBuffer(Utils::Buffer& buffer, bufferDescriptor& desc)
6085 {
6086 	GLsizeiptr size = 0;
6087 	GLvoid*	data = 0;
6088 
6089 	if (false == desc.m_initial_data.empty())
6090 	{
6091 		size = desc.m_initial_data.size();
6092 		data = &desc.m_initial_data[0];
6093 	}
6094 	else if (false == desc.m_expected_data.empty())
6095 	{
6096 		size = desc.m_expected_data.size();
6097 	}
6098 
6099 	buffer.Init(desc.m_target, Utils::Buffer::StaticDraw, size, data);
6100 
6101 	if (bufferDescriptor::m_non_indexed != desc.m_index)
6102 	{
6103 		buffer.BindBase(desc.m_index);
6104 	}
6105 	else
6106 	{
6107 		buffer.Bind();
6108 	}
6109 }
6110 
6111 /** Prepare collection of buffer
6112  *
6113  * @param descriptors Collection of descriptors
6114  * @param out_buffers Collection of buffers
6115  **/
6116 void BufferTestBase::prepareBuffers(bufferDescriptor::Vector& descriptors, bufferCollection& out_buffers)
6117 {
6118 	for (bufferDescriptor::Vector::iterator it = descriptors.begin(), end = descriptors.end(); end != it; ++it)
6119 	{
6120 		bufferCollection::pair pair;
6121 
6122 		pair.m_buffer = new Utils::Buffer(m_context);
6123 		if (0 == pair.m_buffer)
6124 		{
6125 			TCU_FAIL("Memory allocation failed");
6126 		}
6127 
6128 		pair.m_descriptor = &(*it);
6129 
6130 		prepareBuffer(*pair.m_buffer, *pair.m_descriptor);
6131 
6132 		out_buffers.m_vector.push_back(pair);
6133 	}
6134 }
6135 
6136 /** Destructor
6137  *
6138  **/
6139 BufferTestBase::bufferCollection::~bufferCollection()
6140 {
6141 	for (Vector::iterator it = m_vector.begin(), end = m_vector.end(); end != it; ++it)
6142 	{
6143 		if (0 != it->m_buffer)
6144 		{
6145 			delete it->m_buffer;
6146 			it->m_buffer = 0;
6147 		}
6148 	}
6149 }
6150 
6151 /** Constructor
6152  *
6153  * @param context          Test context
6154  * @param test_name        Name of test
6155  * @param test_description Description of test
6156  **/
6157 NegativeTestBase::NegativeTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6158 	: TestBase(context, test_name, test_description)
6159 {
6160 }
6161 
6162 /** Selects if "compute" stage is relevant for test
6163  *
6164  * @param ignored
6165  *
6166  * @return true
6167  **/
6168 bool NegativeTestBase::isComputeRelevant(GLuint /* test_case_index */)
6169 {
6170 	return true;
6171 }
6172 
6173 /** Selects if compilation failure is expected result
6174  *
6175  * @param ignored
6176  *
6177  * @return true
6178  **/
6179 bool NegativeTestBase::isFailureExpected(GLuint /* test_case_index */)
6180 {
6181 	return true;
6182 }
6183 
6184 /** Selects if the test case should use a separable program
6185  *
6186  * @param ignored
6187  *
6188  * @return false
6189  **/
6190 bool NegativeTestBase::isSeparable(const GLuint /* test_case_index */)
6191 {
6192 	return false;
6193 }
6194 
6195 /** Runs test case
6196  *
6197  * @param test_case_index Id of test case
6198  *
6199  * @return true if test case pass, false otherwise
6200  **/
6201 bool NegativeTestBase::testCase(GLuint test_case_index)
6202 {
6203 	bool test_case_result = true;
6204 
6205 	/* Compute */
6206 	if (true == isComputeRelevant(test_case_index))
6207 	{
6208 		const std::string& cs_source		   = getShaderSource(test_case_index, Utils::Shader::COMPUTE);
6209 		bool			   is_build_error	  = false;
6210 		const bool		   is_failure_expected = isFailureExpected(test_case_index);
6211 		Utils::Program	 program(m_context);
6212 
6213 		try
6214 		{
6215 			program.Init(cs_source, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */,
6216 						 false /* separable */);
6217 		}
6218 		catch (Utils::Shader::InvalidSourceException& exc)
6219 		{
6220 			if (false == is_failure_expected)
6221 			{
6222 				m_context.getTestContext().getLog()
6223 					<< tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6224 				exc.log(m_context);
6225 			}
6226 
6227 #if DEBUG_NEG_LOG_ERROR
6228 
6229 			else
6230 			{
6231 				m_context.getTestContext().getLog()
6232 					<< tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6233 					<< tcu::TestLog::EndMessage;
6234 				exc.log(m_context);
6235 			}
6236 
6237 #endif /* DEBUG_NEG_LOG_ERROR */
6238 
6239 			is_build_error = true;
6240 		}
6241 		catch (Utils::Program::BuildException& exc)
6242 		{
6243 			if (false == is_failure_expected)
6244 			{
6245 				m_context.getTestContext().getLog()
6246 					<< tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6247 				exc.log(m_context);
6248 			}
6249 
6250 #if DEBUG_NEG_LOG_ERROR
6251 
6252 			else
6253 			{
6254 				m_context.getTestContext().getLog()
6255 					<< tcu::TestLog::Message
6256 					<< "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6257 				exc.log(m_context);
6258 			}
6259 
6260 #endif /* DEBUG_NEG_LOG_ERROR */
6261 
6262 			is_build_error = true;
6263 		}
6264 
6265 		if (is_build_error != is_failure_expected)
6266 		{
6267 			if (!is_build_error)
6268 			{
6269 				m_context.getTestContext().getLog()
6270 					<< tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6271 				Utils::Shader::LogSource(m_context, cs_source, Utils::Shader::COMPUTE);
6272 			}
6273 			test_case_result = false;
6274 		}
6275 	}
6276 	else /* Draw */
6277 	{
6278 		const std::string& fs_source		   = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
6279 		const std::string& gs_source		   = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
6280 		bool			   is_build_error	  = false;
6281 		const bool		   is_failure_expected = isFailureExpected(test_case_index);
6282 		Utils::Program	 program(m_context);
6283 		const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
6284 		const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
6285 		const std::string& vs_source  = getShaderSource(test_case_index, Utils::Shader::VERTEX);
6286 
6287 		try
6288 		{
6289 			if (isSeparable(test_case_index))
6290 			{
6291 				program.Init("" /*cs*/, fs_source, "" /*gs_source*/, "" /*tcs_source*/, "" /*tes_source*/,
6292 							 "" /*vs_source*/, true /* separable */);
6293 				program.Init("" /*cs*/, "" /*fs_source*/, gs_source, "" /*tcs_source*/, "" /*tes_source*/,
6294 							 "" /*vs_source*/, true /* separable */);
6295 				program.Init("" /*cs*/, "" /*fs_source*/, "" /*gs_source*/, tcs_source, "" /*tes_source*/,
6296 							 "" /*vs_source*/, true /* separable */);
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 			}
6302 			else
6303 			{
6304 				program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source,
6305 							 false /* separable */);
6306 			}
6307 		}
6308 		catch (Utils::Shader::InvalidSourceException& exc)
6309 		{
6310 			if (false == is_failure_expected)
6311 			{
6312 				m_context.getTestContext().getLog()
6313 					<< tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6314 				exc.log(m_context);
6315 			}
6316 
6317 #if DEBUG_NEG_LOG_ERROR
6318 
6319 			else
6320 			{
6321 				m_context.getTestContext().getLog()
6322 					<< tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6323 					<< tcu::TestLog::EndMessage;
6324 				exc.log(m_context);
6325 			}
6326 
6327 #endif /* DEBUG_NEG_LOG_ERROR */
6328 
6329 			is_build_error = true;
6330 		}
6331 		catch (Utils::Program::BuildException& exc)
6332 		{
6333 			if (false == is_failure_expected)
6334 			{
6335 				m_context.getTestContext().getLog()
6336 					<< tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6337 				exc.log(m_context);
6338 			}
6339 
6340 #if DEBUG_NEG_LOG_ERROR
6341 
6342 			else
6343 			{
6344 				m_context.getTestContext().getLog()
6345 					<< tcu::TestLog::Message
6346 					<< "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6347 				exc.log(m_context);
6348 			}
6349 
6350 #endif /* DEBUG_NEG_LOG_ERROR */
6351 
6352 			is_build_error = true;
6353 		}
6354 
6355 		if (is_build_error != is_failure_expected)
6356 		{
6357 			if (!is_build_error)
6358 			{
6359 				m_context.getTestContext().getLog()
6360 					<< tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6361 				Utils::Shader::LogSource(m_context, vs_source, Utils::Shader::VERTEX);
6362 				Utils::Shader::LogSource(m_context, tcs_source, Utils::Shader::TESS_CTRL);
6363 				Utils::Shader::LogSource(m_context, tes_source, Utils::Shader::TESS_EVAL);
6364 				Utils::Shader::LogSource(m_context, gs_source, Utils::Shader::GEOMETRY);
6365 				Utils::Shader::LogSource(m_context, fs_source, Utils::Shader::FRAGMENT);
6366 			}
6367 			test_case_result = false;
6368 		}
6369 	}
6370 
6371 	return test_case_result;
6372 }
6373 
6374 /* Constants used by TextureTestBase */
6375 const glw::GLuint TextureTestBase::m_width  = 16;
6376 const glw::GLuint TextureTestBase::m_height = 16;
6377 
6378 /** Constructor
6379  *
6380  * @param context          Test context
6381  * @param test_name        Name of test
6382  * @param test_description Description of test
6383  **/
6384 TextureTestBase::TextureTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6385 	: TestBase(context, test_name, test_description)
6386 {
6387 }
6388 
6389 /** Get locations for all inputs with automatic_location
6390  *
6391  * @param program           Program object
6392  * @param program_interface Interface of program
6393  **/
6394 void TextureTestBase::prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface)
6395 {
6396 	Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6397 
6398 	Utils::Variable::PtrVector& inputs = si.m_inputs;
6399 
6400 	for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it)
6401 	{
6402 		/* Test does not specify location, query value and set */
6403 		if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6404 		{
6405 			GLuint index	= program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT);
6406 			GLint  location = 0;
6407 
6408 			program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location);
6409 
6410 			(*it)->m_descriptor.m_expected_location = location;
6411 		}
6412 	}
6413 }
6414 
6415 /** Verifies contents of drawn image
6416  *
6417  * @param ignored
6418  * @param color_0 Verified image
6419  *
6420  * @return true if image is filled with 1, false otherwise
6421  **/
6422 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& color_0)
6423 {
6424 	static const GLuint size		   = m_width * m_height;
6425 	static const GLuint expected_color = 1;
6426 
6427 	std::vector<GLuint> data;
6428 	data.resize(size);
6429 
6430 	color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]);
6431 
6432 	for (GLuint i = 0; i < size; ++i)
6433 	{
6434 		const GLuint color = data[i];
6435 
6436 		if (expected_color != color)
6437 		{
6438 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "R32UI[" << i << "]:" << color
6439 												<< tcu::TestLog::EndMessage;
6440 			return false;
6441 		}
6442 	}
6443 
6444 	return true;
6445 }
6446 
6447 /** Execute dispatch compute for 16x16x1
6448  *
6449  * @param ignored
6450  **/
6451 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */)
6452 {
6453 	const Functions& gl = m_context.getRenderContext().getFunctions();
6454 
6455 	gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */);
6456 	GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
6457 }
6458 
6459 /** Execute drawArrays for single vertex
6460  *
6461  * @param ignored
6462  **/
6463 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */)
6464 {
6465 	const Functions& gl = m_context.getRenderContext().getFunctions();
6466 
6467 	gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
6468 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
6469 }
6470 
6471 /** Prepare code snippet that will pass in variables to out variables
6472  *
6473  * @param ignored
6474  * @param varying_passthrough Collection of connections between in and out variables
6475  * @param stage               Shader stage
6476  *
6477  * @return Code that pass in variables to next stage
6478  **/
6479 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */,
6480 											Utils::VaryingPassthrough& varying_passthrough, Utils::Shader::STAGES stage)
6481 {
6482 	static const GLchar* separator = "\n    ";
6483 
6484 	/* Skip for compute shader */
6485 	if (Utils::Shader::COMPUTE == stage)
6486 	{
6487 		return "";
6488 	}
6489 
6490 	Utils::VaryingConnection::Vector& vector = varying_passthrough.Get(stage);
6491 
6492 	std::string result   = Utils::g_list;
6493 	size_t		position = 0;
6494 
6495 	for (GLuint i = 0; i < vector.size(); ++i)
6496 	{
6497 
6498 		Utils::VaryingConnection& connection = vector[i];
6499 
6500 		Utils::Variable* in  = connection.m_in;
6501 		Utils::Variable* out = connection.m_out;
6502 
6503 		Utils::Variable::FLAVOUR in_flavour  = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6504 		Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT);
6505 
6506 		const std::string passthrough =
6507 			getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour);
6508 
6509 		Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6510 	}
6511 
6512 	Utils::endList("", position, result);
6513 
6514 	return result;
6515 }
6516 
6517 /** Basic implementation of method getProgramInterface
6518  *
6519  * @param ignored
6520  * @param ignored
6521  * @param ignored
6522  **/
6523 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */,
6524 										  Utils::ProgramInterface& /* program_interface */,
6525 										  Utils::VaryingPassthrough& /* varying_passthrough */)
6526 {
6527 }
6528 
6529 /** Prepare code snippet that will verify in and uniform variables
6530  *
6531  * @param ignored
6532  * @param program_interface Interface of program
6533  * @param stage             Shader stage
6534  *
6535  * @return Code that verify variables
6536  **/
6537 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */,
6538 													Utils::ProgramInterface& program_interface,
6539 													Utils::Shader::STAGES	stage)
6540 {
6541 	static const GLchar* separator = " ||\n        ";
6542 
6543 	std::string verification = "if (LIST)\n"
6544 							   "    {\n"
6545 							   "        result = 0u;\n"
6546 							   "    }\n";
6547 
6548 	/* Get flavour of in and out variables */
6549 	Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6550 
6551 	/* Get interface for shader stage */
6552 	Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
6553 
6554 	/* There are no varialbes to verify */
6555 	if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size()))
6556 	{
6557 		return "";
6558 	}
6559 
6560 	/* For each in variable insert verification code */
6561 	size_t position = 0;
6562 
6563 	for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6564 	{
6565 		const Utils::Variable& var				= *si.m_inputs[i];
6566 		const std::string&	 var_verification = getVariableVerification("", var.m_data, var.m_descriptor, in_flavour);
6567 
6568 		Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6569 	}
6570 
6571 	/* For each unifrom variable insert verification code */
6572 	for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6573 	{
6574 		const Utils::Variable& var = *si.m_uniforms[i];
6575 		const std::string&	 var_verification =
6576 			getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6577 
6578 		Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6579 	}
6580 
6581 	/* For each ssb variable insert verification code */
6582 	for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6583 	{
6584 		const Utils::Variable& var = *si.m_ssb_blocks[i];
6585 		const std::string&	 var_verification =
6586 			getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6587 
6588 		Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6589 	}
6590 
6591 	Utils::endList("", position, verification);
6592 
6593 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE
6594 
6595 	{
6596 		GLchar buffer[16];
6597 		sprintf(buffer, "%d", stage + 10);
6598 		Utils::replaceToken("0u", position, buffer, verification);
6599 	}
6600 
6601 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE
6602 
6603 	if (Utils::Shader::VERTEX == stage)
6604 	{
6605 		Utils::replaceToken("0u", position, "in_vs_first.x", verification);
6606 	}
6607 	else
6608 	{
6609 		Utils::replaceToken("0u", position, "31u", verification);
6610 	}
6611 
6612 #endif
6613 
6614 	/* Done */
6615 	return verification;
6616 }
6617 
6618 /** Selects if "compute" stage is relevant for test
6619  *
6620  * @param ignored
6621  *
6622  * @return true
6623  **/
6624 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */)
6625 {
6626 	return true;
6627 }
6628 
6629 /** Selects if "draw" stages are relevant for test
6630  *
6631  * @param ignored
6632  *
6633  * @return true
6634  **/
6635 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */)
6636 {
6637 	return true;
6638 }
6639 
6640 /** Prepare code that will do assignment of single in to single out
6641  *
6642  * @param in_parent_name  Name of parent in variable
6643  * @param in_variable     Descriptor of in variable
6644  * @param in_flavour      Flavoud of in variable
6645  * @param out_parent_name Name of parent out variable
6646  * @param out_variable    Descriptor of out variable
6647  * @param out_flavour     Flavoud of out variable
6648  *
6649  * @return Code that does OUT = IN
6650  **/
6651 std::string TextureTestBase::getVariablePassthrough(const std::string&				   in_parent_name,
6652 													const Utils::Variable::Descriptor& in_variable,
6653 													Utils::Variable::FLAVOUR		   in_flavour,
6654 													const std::string&				   out_parent_name,
6655 													const Utils::Variable::Descriptor& out_variable,
6656 													Utils::Variable::FLAVOUR		   out_flavour)
6657 {
6658 	bool				 done		  = false;
6659 	GLuint				 index		  = 0;
6660 	GLuint				 member_index = 0;
6661 	size_t				 position	 = 0;
6662 	std::string			 result		  = Utils::g_list;
6663 	static const GLchar* separator	= ";\n    ";
6664 
6665 	/* For each member of each array element */
6666 	do
6667 	{
6668 		const std::string in_name  = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index);
6669 		const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index);
6670 		std::string		  passthrough;
6671 
6672 		/* Prepare verification */
6673 		if (Utils::Variable::BUILTIN == in_variable.m_type)
6674 		{
6675 			size_t pass_position = 0;
6676 
6677 			passthrough = "OUT = IN;";
6678 
6679 			Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough);
6680 			Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough);
6681 
6682 			/* Increment index */
6683 			++index;
6684 		}
6685 		else
6686 		{
6687 			const Utils::Interface* in_interface  = in_variable.m_interface;
6688 			const Utils::Interface* out_interface = out_variable.m_interface;
6689 
6690 			if ((0 == in_interface) || (0 == out_interface))
6691 			{
6692 				TCU_FAIL("Nullptr");
6693 			}
6694 
6695 			const Utils::Variable::Descriptor& in_member  = in_interface->m_members[member_index];
6696 			const Utils::Variable::Descriptor& out_member = out_interface->m_members[member_index];
6697 
6698 			passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member,
6699 												 Utils::Variable::BASIC);
6700 
6701 			/* Increment member_index */
6702 			++member_index;
6703 
6704 			/* Increment index and reset member_index if all members were processed */
6705 			if (in_interface->m_members.size() == member_index)
6706 			{
6707 				++index;
6708 				member_index = 0;
6709 			}
6710 		}
6711 
6712 		/* Check if loop should end */
6713 		if ((index >= in_variable.m_n_array_elements) && (0 == member_index))
6714 		{
6715 			done = true;
6716 		}
6717 
6718 		Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6719 
6720 	} while (true != done);
6721 
6722 	Utils::endList("", position, result);
6723 
6724 	/* Done */
6725 	return result;
6726 }
6727 
6728 /** Get verification of single variable
6729  *
6730  * @param parent_name Name of parent variable
6731  * @param data        Data that should be used as EXPECTED
6732  * @param variable    Descriptor of variable
6733  * @param flavour     Flavour of variable
6734  *
6735  * @return Code that does (EXPECTED != VALUE) ||
6736  **/
6737 std::string TextureTestBase::getVariableVerification(const std::string& parent_name, const GLvoid* data,
6738 													 const Utils::Variable::Descriptor& variable,
6739 													 Utils::Variable::FLAVOUR			flavour)
6740 {
6741 	static const GLchar* logic_op   = " ||\n        ";
6742 	const GLuint		 n_elements = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements;
6743 	size_t				 position   = 0;
6744 	std::string			 result		= Utils::g_list;
6745 	GLint				 stride		= variable.m_expected_stride_of_element;
6746 
6747 	/* For each each array element */
6748 	for (GLuint element = 0; element < n_elements; ++element)
6749 	{
6750 		const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element);
6751 
6752 		/* Calculate data pointer */
6753 		GLvoid* data_ptr = (GLvoid*)((GLubyte*)data + element * stride);
6754 
6755 		/* Prepare verification */
6756 		if (Utils::Variable::BUILTIN == variable.m_type)
6757 		{
6758 			const std::string& expected = variable.m_builtin.GetGLSLConstructor(data_ptr);
6759 			std::string		   verification;
6760 			size_t			   verification_position = 0;
6761 
6762 			verification = "(EXPECTED != NAME)";
6763 
6764 			Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification);
6765 			Utils::replaceToken("NAME", verification_position, name.c_str(), verification);
6766 
6767 			Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6768 		}
6769 		else
6770 		{
6771 			const Utils::Interface* interface = variable.m_interface;
6772 
6773 			if (0 == interface)
6774 			{
6775 				TCU_FAIL("Nullptr");
6776 			}
6777 
6778 			const GLuint n_members = static_cast<GLuint>(interface->m_members.size());
6779 
6780 			/* for each member */
6781 			for (GLuint member_index = 0; member_index < n_members; ++member_index)
6782 			{
6783 				const Utils::Variable::Descriptor& member = interface->m_members[member_index];
6784 
6785 				/* Get verification of member */
6786 				const std::string& verification =
6787 					getVariableVerification(name, (GLubyte*)data_ptr + member.m_offset, member, Utils::Variable::BASIC);
6788 
6789 				Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6790 			}
6791 		}
6792 	}
6793 
6794 	Utils::endList("", position, result);
6795 
6796 	return result;
6797 }
6798 
6799 /** Prepare attributes, vertex array object and array buffer
6800  *
6801  * @param test_case_index   Index of test case
6802  * @param program_interface Interface of program
6803  * @param buffer            Array buffer
6804  * @param vao               Vertex array object
6805  **/
6806 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6807 										Utils::Buffer& buffer, Utils::VertexArray& vao)
6808 {
6809 	const bool use_component_qualifier = useComponentQualifier(test_case_index);
6810 
6811 	/* Get shader interface */
6812 	const Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6813 
6814 	/* Bind vao and buffer */
6815 	vao.Bind();
6816 	buffer.Bind();
6817 
6818 	/* Skip if there are no input variables in vertex shader */
6819 	if (0 == si.m_inputs.size())
6820 	{
6821 		return;
6822 	}
6823 
6824 	const Functions& gl = m_context.getRenderContext().getFunctions();
6825 
6826 	/* Calculate vertex stride and check */
6827 	GLint max_inputs;
6828 	gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_inputs);
6829 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
6830 
6831 	/* dvec3/4 vertex inputs use a single location but require 2x16B slots */
6832 	const GLuint max_slots = max_inputs * 2;
6833 
6834 	/* Compute used slots */
6835 	std::vector<GLuint> slot_sizes(max_slots, 0);
6836 	for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6837 	{
6838 		const Utils::Variable& variable = *si.m_inputs[i];
6839 
6840 		const GLuint variable_size = static_cast<GLuint>(variable.m_data_size);
6841 
6842 		const GLuint base_slot = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
6843 		const GLuint ends_at   = variable.m_descriptor.m_offset % 16 + variable_size;
6844 
6845 		const GLuint array_length = std::max(1u, variable.m_descriptor.m_n_array_elements);
6846 		for (GLuint loc = 0; loc < array_length; loc++)
6847 		{
6848 			const GLuint slot = base_slot + loc;
6849 			slot_sizes[slot] = std::max(slot_sizes[slot], ends_at);
6850 		}
6851 	}
6852 
6853 	/* Compute the offsets where we need to put vertex buffer data for each slot */
6854 	std::vector<GLint> slot_offsets(max_slots, -1);
6855 	GLuint			   buffer_size = 0;
6856 	for (GLuint i = 0; i < max_slots; i++)
6857 	{
6858 		if (slot_sizes[i] == 0)
6859 			continue;
6860 		slot_offsets[i] = buffer_size;
6861 		buffer_size += slot_sizes[i];
6862 	}
6863 
6864 	/* Prepare buffer data and set up vao */
6865 	std::vector<GLubyte> buffer_data(buffer_size);
6866 
6867 	GLubyte* ptr = &buffer_data[0];
6868 
6869 	for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6870 	{
6871 		const Utils::Variable& variable = *si.m_inputs[i];
6872 
6873 		const GLuint base_slot		 = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
6874 		const GLuint variable_offset = variable.m_descriptor.m_offset % 16;
6875 		const GLuint array_length	= std::max(1u, variable.m_descriptor.m_n_array_elements);
6876 		for (GLuint loc = 0; loc < array_length; loc++)
6877 		{
6878 			const GLuint slot = base_slot + loc;
6879 			memcpy(ptr + slot_offsets[slot] + variable_offset, variable.m_data, variable.m_data_size);
6880 		}
6881 
6882 		if (!use_component_qualifier)
6883 		{
6884 			vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin,
6885 						  variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized,
6886 						  variable.GetStride(), (GLvoid*)(intptr_t)(slot_offsets[base_slot] + variable_offset));
6887 		}
6888 		else if (0 == variable.m_descriptor.m_expected_component)
6889 		{
6890 			/* Components can only be applied to types not surpassing
6891 			 * the bounds of a single slot. Therefore, we calculate
6892 			 * the amount of used components in the varying based on
6893 			 * the calculated slot sizes.
6894 			 */
6895 			const GLuint n_component_size = Utils::Type::Double == variable.m_descriptor.m_builtin.m_basic_type ? 8 : 4;
6896 			const GLuint n_rows			  = slot_sizes[base_slot] / n_component_size;
6897 
6898 			const Utils::Type& type = Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type,
6899 														   1 /* n_columns */, n_rows /* n_rows */);
6900 
6901 			vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements,
6902 						  variable.m_descriptor.m_normalized, variable.GetStride(),
6903 						  (GLvoid*)(intptr_t)(slot_offsets[base_slot] + variable_offset));
6904 		}
6905 	}
6906 
6907 	/* Update buffer */
6908 	buffer.Data(Utils::Buffer::StaticDraw, buffer_size, ptr);
6909 }
6910 
6911 /** Get locations for all outputs with automatic_location
6912  *
6913  * @param program           Program object
6914  * @param program_interface Interface of program
6915  **/
6916 void TextureTestBase::prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface)
6917 {
6918 	Utils::ShaderInterface&		si		= program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6919 	Utils::Variable::PtrVector& outputs = si.m_outputs;
6920 
6921 	for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
6922 	{
6923 		/* Test does not specify location, query value and set */
6924 		if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6925 		{
6926 			GLuint index	= program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT);
6927 			GLint  location = 0;
6928 
6929 			program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location);
6930 
6931 			(*it)->m_descriptor.m_expected_location = location;
6932 		}
6933 	}
6934 }
6935 
6936 /** Prepare framebuffer with single texture as color attachment
6937  *
6938  * @param framebuffer     Framebuffer
6939  * @param color_0_texture Texture that will used as color attachment
6940  **/
6941 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
6942 {
6943 	/* Prepare data */
6944 	std::vector<GLuint> texture_data;
6945 	texture_data.resize(m_width * m_height);
6946 
6947 	for (GLuint i = 0; i < texture_data.size(); ++i)
6948 	{
6949 		texture_data[i] = 0x20406080;
6950 	}
6951 
6952 	/* Prepare texture */
6953 	color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6954 						 &texture_data[0]);
6955 
6956 	/* Prepare framebuffer */
6957 	framebuffer.Init();
6958 	framebuffer.Bind();
6959 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height);
6960 
6961 	framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6962 	framebuffer.Clear(GL_COLOR_BUFFER_BIT);
6963 }
6964 
6965 /** Prepare iamge unit for compute shader
6966  *
6967  * @param location      Uniform location
6968  * @param image_texture Texture that will used as color attachment
6969  **/
6970 void TextureTestBase::prepareImage(GLint location, Utils::Texture& image_texture) const
6971 {
6972 	static const GLuint image_unit = 0;
6973 
6974 	std::vector<GLuint> texture_data;
6975 	texture_data.resize(m_width * m_height);
6976 
6977 	for (GLuint i = 0; i < texture_data.size(); ++i)
6978 	{
6979 		texture_data[i] = 0x20406080;
6980 	}
6981 
6982 	image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6983 					   &texture_data[0]);
6984 
6985 	const Functions& gl = m_context.getRenderContext().getFunctions();
6986 
6987 	gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */,
6988 						GL_WRITE_ONLY, GL_R32UI);
6989 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
6990 
6991 	Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit);
6992 }
6993 
6994 /** Basic implementation
6995  *
6996  * @param ignored
6997  * @param si        Shader interface
6998  * @param program   Program
6999  * @param cs_buffer Buffer for ssb blocks
7000  **/
7001 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
7002 								  Utils::Buffer& buffer)
7003 {
7004 	/* Skip if there are no input variables in vertex shader */
7005 	if (0 == si.m_ssb_blocks.size())
7006 	{
7007 		return;
7008 	}
7009 
7010 	/* Calculate vertex stride */
7011 	GLint ssbs_stride = 0;
7012 
7013 	for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
7014 	{
7015 		Utils::Variable& variable = *si.m_ssb_blocks[i];
7016 
7017 		if (false == variable.IsBlock())
7018 		{
7019 			continue;
7020 		}
7021 
7022 		GLint variable_stride = variable.GetStride();
7023 
7024 		GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
7025 
7026 		ssbs_stride = std::max(ssbs_stride, ends_at);
7027 	}
7028 
7029 	/* Set active program */
7030 	program.Use();
7031 
7032 	/* Allocate */
7033 	buffer.Bind();
7034 	buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0);
7035 
7036 	/* Set up uniforms */
7037 	for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
7038 	{
7039 		Utils::Variable& variable = *si.m_ssb_blocks[i];
7040 
7041 		/* prepareUnifor should work fine for ssb blocks */
7042 		prepareUniform(program, variable, buffer);
7043 	}
7044 }
7045 
7046 /** Basic implementation
7047  *
7048  * @param test_case_index   Test case index
7049  * @param program_interface Program interface
7050  * @param program           Program
7051  * @param cs_buffer         Buffer for compute shader stage
7052  **/
7053 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7054 								  Utils::Program& program, Utils::Buffer& cs_buffer)
7055 {
7056 	cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7057 
7058 	Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7059 
7060 	prepareSSBs(test_case_index, cs, program, cs_buffer);
7061 
7062 	cs_buffer.BindBase(Utils::Shader::COMPUTE);
7063 }
7064 
7065 /** Basic implementation
7066  *
7067  * @param test_case_index   Test case index
7068  * @param program_interface Program interface
7069  * @param program           Program
7070  * @param fs_buffer         Buffer for fragment shader stage
7071  * @param gs_buffer         Buffer for geometry shader stage
7072  * @param tcs_buffer        Buffer for tessellation control shader stage
7073  * @param tes_buffer        Buffer for tessellation evaluation shader stage
7074  * @param vs_buffer         Buffer for vertex shader stage
7075  **/
7076 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7077 								  Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7078 								  Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7079 {
7080 	fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7081 	gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7082 	tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7083 	tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7084 	vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7085 
7086 	Utils::ShaderInterface& fs  = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7087 	Utils::ShaderInterface& gs  = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7088 	Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7089 	Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7090 	Utils::ShaderInterface& vs  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7091 
7092 	prepareSSBs(test_case_index, fs, program, fs_buffer);
7093 	prepareSSBs(test_case_index, gs, program, gs_buffer);
7094 	prepareSSBs(test_case_index, tcs, program, tcs_buffer);
7095 	prepareSSBs(test_case_index, tes, program, tes_buffer);
7096 	prepareSSBs(test_case_index, vs, program, vs_buffer);
7097 
7098 	fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7099 	gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7100 	tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7101 	tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7102 	vs_buffer.BindBase(Utils::Shader::VERTEX);
7103 }
7104 
7105 /** Updates buffer data with variable
7106  *
7107  * @param program  Program object
7108  * @param variable Variable
7109  * @param buffer   Buffer
7110  **/
7111 void TextureTestBase::prepareUniform(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer)
7112 {
7113 	const Functions& gl = m_context.getRenderContext().getFunctions();
7114 
7115 	GLsizei count = variable.m_descriptor.m_n_array_elements;
7116 	if (0 == count)
7117 	{
7118 		count = 1;
7119 	}
7120 
7121 	if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type)
7122 	{
7123 		program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location,
7124 						variable.m_data);
7125 	}
7126 	else
7127 	{
7128 		const bool is_block = variable.IsBlock();
7129 
7130 		if (false == is_block)
7131 		{
7132 			TCU_FAIL("Not implemented");
7133 		}
7134 		else
7135 		{
7136 			buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count,
7137 						   variable.m_data);
7138 		}
7139 	}
7140 }
7141 
7142 /** Basic implementation
7143  *
7144  * @param ignored
7145  * @param si        Shader interface
7146  * @param program   Program
7147  * @param cs_buffer Buffer for uniform blocks
7148  **/
7149 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
7150 									  Utils::Buffer& buffer)
7151 {
7152 	/* Skip if there are no input variables in vertex shader */
7153 	if (0 == si.m_uniforms.size())
7154 	{
7155 		return;
7156 	}
7157 
7158 	/* Calculate vertex stride */
7159 	GLint uniforms_stride = 0;
7160 
7161 	for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7162 	{
7163 		Utils::Variable& variable = *si.m_uniforms[i];
7164 
7165 		if (false == variable.IsBlock())
7166 		{
7167 			continue;
7168 		}
7169 
7170 		GLint variable_stride = variable.GetStride();
7171 
7172 		GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
7173 
7174 		uniforms_stride = std::max(uniforms_stride, ends_at);
7175 	}
7176 
7177 	/* Set active program */
7178 	program.Use();
7179 
7180 	/* Allocate */
7181 	buffer.Bind();
7182 	buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0);
7183 
7184 	/* Set up uniforms */
7185 	for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7186 	{
7187 		Utils::Variable& variable = *si.m_uniforms[i];
7188 
7189 		prepareUniform(program, variable, buffer);
7190 	}
7191 }
7192 
7193 /** Basic implementation
7194  *
7195  * @param test_case_index   Test case index
7196  * @param program_interface Program interface
7197  * @param program           Program
7198  * @param cs_buffer         Buffer for compute shader stage
7199  **/
7200 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7201 									  Utils::Program& program, Utils::Buffer& cs_buffer)
7202 {
7203 	cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7204 
7205 	Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7206 
7207 	prepareUniforms(test_case_index, cs, program, cs_buffer);
7208 
7209 	cs_buffer.BindBase(Utils::Shader::COMPUTE);
7210 }
7211 
7212 /** Basic implementation
7213  *
7214  * @param test_case_index   Test case index
7215  * @param program_interface Program interface
7216  * @param program           Program
7217  * @param fs_buffer         Buffer for fragment shader stage
7218  * @param gs_buffer         Buffer for geometry shader stage
7219  * @param tcs_buffer        Buffer for tessellation control shader stage
7220  * @param tes_buffer        Buffer for tessellation evaluation shader stage
7221  * @param vs_buffer         Buffer for vertex shader stage
7222  **/
7223 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7224 									  Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7225 									  Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7226 {
7227 	fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7228 	gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7229 	tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7230 	tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7231 	vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7232 
7233 	Utils::ShaderInterface& fs  = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7234 	Utils::ShaderInterface& gs  = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7235 	Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7236 	Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7237 	Utils::ShaderInterface& vs  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7238 
7239 	prepareUniforms(test_case_index, fs, program, fs_buffer);
7240 	prepareUniforms(test_case_index, gs, program, gs_buffer);
7241 	prepareUniforms(test_case_index, tcs, program, tcs_buffer);
7242 	prepareUniforms(test_case_index, tes, program, tes_buffer);
7243 	prepareUniforms(test_case_index, vs, program, vs_buffer);
7244 
7245 	fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7246 	gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7247 	tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7248 	tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7249 	vs_buffer.BindBase(Utils::Shader::VERTEX);
7250 }
7251 
7252 /** Basic implementation
7253  *
7254  * @param test_case_index   Test case index
7255  * @param program_interface Program interface
7256  * @param program           Program
7257  * @param fs_buffer         Buffer for fragment shader stage
7258  * @param gs_buffer         Buffer for geometry shader stage
7259  * @param tcs_buffer        Buffer for tessellation control shader stage
7260  * @param tes_buffer        Buffer for tessellation evaluation shader stage
7261  * @param vs_buffer         Buffer for vertex shader stage
7262  **/
7263 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7264 									  Utils::Program& fs_program, Utils::Program& gs_program,
7265 									  Utils::Program& tcs_program, Utils::Program& tes_program,
7266 									  Utils::Program& vs_program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7267 									  Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7268 {
7269 	fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7270 	gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7271 	tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7272 	tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7273 	vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7274 
7275 	Utils::ShaderInterface& fs  = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7276 	Utils::ShaderInterface& gs  = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7277 	Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7278 	Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7279 	Utils::ShaderInterface& vs  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7280 
7281 	prepareUniforms(test_case_index, fs, fs_program, fs_buffer);
7282 	fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7283 
7284 	prepareUniforms(test_case_index, gs, gs_program, gs_buffer);
7285 	gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7286 
7287 	prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer);
7288 	tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7289 
7290 	prepareUniforms(test_case_index, tes, tes_program, tes_buffer);
7291 	tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7292 
7293 	prepareUniforms(test_case_index, vs, vs_program, vs_buffer);
7294 	vs_buffer.BindBase(Utils::Shader::VERTEX);
7295 }
7296 
7297 /** Prepare source for shader
7298  *
7299  * @param test_case_index     Index of test case
7300  * @param program_interface   Interface of program
7301  * @param varying_passthrough Collection of connection between in and out variables
7302  * @param stage               Shader stage
7303  *
7304  * @return Source of shader
7305  **/
7306 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7307 											 Utils::VaryingPassthrough& varying_passthrough,
7308 											 Utils::Shader::STAGES		stage)
7309 {
7310 	/* Get strings */
7311 	const GLchar*	  shader_template  = getShaderTemplate(stage);
7312 	glu::GLSLVersion   glslVersion		= glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
7313 	const char*		   shader_version   = glu::getGLSLVersionDeclaration(glslVersion);
7314 	const std::string& shader_interface = program_interface.GetInterfaceForStage(stage);
7315 	const std::string& verification = getVerificationSnippet(test_case_index, program_interface, stage);
7316 	const std::string& passthrough = getPassSnippet(test_case_index, varying_passthrough, stage);
7317 
7318 	const GLchar* per_vertex = "";
7319 
7320 	std::string source   = shader_template;
7321 	size_t		position = 0;
7322 
7323 	Utils::replaceToken("VERSION", position, shader_version, source);
7324 
7325 	/* Replace tokens in template */
7326 	if (Utils::Shader::GEOMETRY == stage)
7327 	{
7328 		if (false == useMonolithicProgram(test_case_index))
7329 		{
7330 			per_vertex = "out gl_PerVertex {\n"
7331 						 "vec4 gl_Position;\n"
7332 						 "};\n"
7333 						 "\n";
7334 		}
7335 
7336 		Utils::replaceToken("PERVERTEX", position, per_vertex, source);
7337 	}
7338 
7339 	Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source);
7340 	Utils::replaceToken("VERIFICATION", position, verification.c_str(), source);
7341 
7342 	if (false == verification.empty())
7343 	{
7344 		Utils::replaceAllTokens("ELSE", "    else ", source);
7345 	}
7346 	else
7347 	{
7348 		Utils::replaceAllTokens("ELSE", "", source);
7349 	}
7350 
7351 	Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source);
7352 
7353 	/* Done */
7354 	return source;
7355 }
7356 
7357 /** Returns template of shader for given stage
7358  *
7359  * @param stage Shade stage
7360  *
7361  * @return Proper template
7362  **/
7363 const GLchar* TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
7364 {
7365 
7366 	static const GLchar* compute_shader_template =
7367 		"VERSION\n"
7368 		"#extension GL_ARB_enhanced_layouts : require\n"
7369 		"\n"
7370 		"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7371 		"\n"
7372 		"writeonly uniform uimage2D uni_image;\n"
7373 		"\n"
7374 		"INTERFACE"
7375 		"\n"
7376 		"void main()\n"
7377 		"{\n"
7378 		"    uint result = 1u;\n"
7379 		"\n"
7380 		"    VERIFICATION"
7381 		"\n"
7382 		"    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
7383 		"}\n"
7384 		"\n";
7385 
7386 	static const GLchar* fragment_shader_template = "VERSION\n"
7387 													"#extension GL_ARB_enhanced_layouts : require\n"
7388 													"\n"
7389 													"flat in  uint gs_fs_result;\n"
7390 													"     out uint fs_out_result;\n"
7391 													"\n"
7392 													"INTERFACE"
7393 													"\n"
7394 													"void main()\n"
7395 													"{\n"
7396 													"    uint result = 1u;\n"
7397 													"\n"
7398 													"    if (1u != gs_fs_result)\n"
7399 													"    {\n"
7400 													"         result = gs_fs_result;\n"
7401 													"    }\n"
7402 													"ELSEVERIFICATION"
7403 													"\n"
7404 													"    fs_out_result = result;\n"
7405 													"    PASSTHROUGH\n"
7406 													"}\n"
7407 													"\n";
7408 
7409 	static const GLchar* geometry_shader_template =
7410 		"VERSION\n"
7411 		"#extension GL_ARB_enhanced_layouts : require\n"
7412 		"\n"
7413 		"layout(points)                           in;\n"
7414 		"layout(triangle_strip, max_vertices = 4) out;\n"
7415 		"\n"
7416 		"     in  uint tes_gs_result[];\n"
7417 		"     flat out uint gs_fs_result;\n"
7418 		"\n"
7419 		"PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
7420 		"INTERFACE"
7421 		"\n"
7422 		"void main()\n"
7423 		"{\n"
7424 		"    uint result = 1u;\n"
7425 		"\n"
7426 		"    if (1u != tes_gs_result[0])\n"
7427 		"    {\n"
7428 		"         result = tes_gs_result[0];\n"
7429 		"    }\n"
7430 		"ELSEVERIFICATION"
7431 		"\n"
7432 		"    gs_fs_result = result;\n"
7433 		"    PASSTHROUGH\n"
7434 		"    gl_Position  = vec4(-1, -1, 0, 1);\n"
7435 		"    EmitVertex();\n"
7436 		"    gs_fs_result = result;\n"
7437 		"    PASSTHROUGH\n"
7438 		"    gl_Position  = vec4(-1, 1, 0, 1);\n"
7439 		"    EmitVertex();\n"
7440 		"    gs_fs_result = result;\n"
7441 		"    PASSTHROUGH\n"
7442 		"    gl_Position  = vec4(1, -1, 0, 1);\n"
7443 		"    EmitVertex();\n"
7444 		"    gs_fs_result = result;\n"
7445 		"    PASSTHROUGH\n"
7446 		"    gl_Position  = vec4(1, 1, 0, 1);\n"
7447 		"    EmitVertex();\n"
7448 		"}\n"
7449 		"\n";
7450 
7451 	static const GLchar* tess_ctrl_shader_template = "VERSION\n"
7452 													 "#extension GL_ARB_enhanced_layouts : require\n"
7453 													 "\n"
7454 													 "layout(vertices = 1) out;\n"
7455 													 "\n"
7456 													 "in  uint vs_tcs_result[];\n"
7457 													 "out uint tcs_tes_result[];\n"
7458 													 "\n"
7459 													 "INTERFACE"
7460 													 "\n"
7461 													 "void main()\n"
7462 													 "{\n"
7463 													 "    uint result = 1u;\n"
7464 													 "\n"
7465 													 "    if (1u != vs_tcs_result[gl_InvocationID])\n"
7466 													 "    {\n"
7467 													 "         result = vs_tcs_result[gl_InvocationID];\n"
7468 													 "    }\n"
7469 													 "ELSEVERIFICATION"
7470 													 "\n"
7471 													 "    tcs_tes_result[gl_InvocationID] = result;\n"
7472 													 "\n"
7473 													 "    PASSTHROUGH\n"
7474 													 "\n"
7475 													 "    gl_TessLevelOuter[0] = 1.0;\n"
7476 													 "    gl_TessLevelOuter[1] = 1.0;\n"
7477 													 "    gl_TessLevelOuter[2] = 1.0;\n"
7478 													 "    gl_TessLevelOuter[3] = 1.0;\n"
7479 													 "    gl_TessLevelInner[0] = 1.0;\n"
7480 													 "    gl_TessLevelInner[1] = 1.0;\n"
7481 													 "}\n"
7482 													 "\n";
7483 
7484 	static const GLchar* tess_eval_shader_template = "VERSION\n"
7485 													 "#extension GL_ARB_enhanced_layouts : require\n"
7486 													 "\n"
7487 													 "layout(isolines, point_mode) in;\n"
7488 													 "\n"
7489 													 "in  uint tcs_tes_result[];\n"
7490 													 "out uint tes_gs_result;\n"
7491 													 "\n"
7492 													 "INTERFACE"
7493 													 "\n"
7494 													 "void main()\n"
7495 													 "{\n"
7496 													 "    uint result = 1u;\n"
7497 													 "\n"
7498 													 "    if (1u != tcs_tes_result[0])\n"
7499 													 "    {\n"
7500 													 "         result = tcs_tes_result[0];\n"
7501 													 "    }\n"
7502 													 "ELSEVERIFICATION"
7503 													 "\n"
7504 													 "    tes_gs_result = result;\n"
7505 													 "\n"
7506 													 "    PASSTHROUGH\n"
7507 													 "}\n"
7508 													 "\n";
7509 
7510 	static const GLchar* vertex_shader_template = "VERSION\n"
7511 												  "#extension GL_ARB_enhanced_layouts : require\n"
7512 												  "\n"
7513 												  "out uint vs_tcs_result;\n"
7514 												  "\n"
7515 												  "INTERFACE"
7516 												  "\n"
7517 												  "void main()\n"
7518 												  "{\n"
7519 												  "    uint result = 1u;\n"
7520 												  "\n"
7521 												  "    VERIFICATION\n"
7522 												  "\n"
7523 												  "    vs_tcs_result = result;\n"
7524 												  "\n"
7525 												  "    PASSTHROUGH\n"
7526 												  "}\n"
7527 												  "\n";
7528 
7529 	const GLchar* result = 0;
7530 
7531 	switch (stage)
7532 	{
7533 	case Utils::Shader::COMPUTE:
7534 		result = compute_shader_template;
7535 		break;
7536 	case Utils::Shader::FRAGMENT:
7537 		result = fragment_shader_template;
7538 		break;
7539 	case Utils::Shader::GEOMETRY:
7540 		result = geometry_shader_template;
7541 		break;
7542 	case Utils::Shader::TESS_CTRL:
7543 		result = tess_ctrl_shader_template;
7544 		break;
7545 	case Utils::Shader::TESS_EVAL:
7546 		result = tess_eval_shader_template;
7547 		break;
7548 	case Utils::Shader::VERTEX:
7549 		result = vertex_shader_template;
7550 		break;
7551 	default:
7552 		TCU_FAIL("Invalid enum");
7553 	}
7554 
7555 	return result;
7556 }
7557 
7558 /** Runs test case
7559  *
7560  * @param test_case_index Id of test case
7561  *
7562  * @return true if test case pass, false otherwise
7563  **/
7564 bool TextureTestBase::testCase(GLuint test_case_index)
7565 {
7566 	try
7567 	{
7568 		if (true == useMonolithicProgram(test_case_index))
7569 		{
7570 			return testMonolithic(test_case_index);
7571 		}
7572 		else
7573 		{
7574 			return testSeparable(test_case_index);
7575 		}
7576 	}
7577 	catch (Utils::Shader::InvalidSourceException& exc)
7578 	{
7579 		exc.log(m_context);
7580 		TCU_FAIL(exc.what());
7581 	}
7582 	catch (Utils::Program::BuildException& exc)
7583 	{
7584 		exc.log(m_context);
7585 		TCU_FAIL(exc.what());
7586 	}
7587 }
7588 
7589 /** Runs "draw" test with monolithic program
7590  *
7591  * @param test_case_index Id of test case
7592  **/
7593 bool TextureTestBase::testMonolithic(GLuint test_case_index)
7594 {
7595 	Utils::ProgramInterface   program_interface;
7596 	Utils::VaryingPassthrough varying_passthrough;
7597 
7598 	/* */
7599 	const std::string& test_name = getTestCaseName(test_case_index);
7600 
7601 	/* */
7602 	getProgramInterface(test_case_index, program_interface, varying_passthrough);
7603 
7604 	bool result = true;
7605 	/* Draw */
7606 	if (true == isDrawRelevant(test_case_index))
7607 	{
7608 		Utils::Buffer	  buffer_attr(m_context);
7609 		Utils::Buffer	  buffer_ssb_fs(m_context);
7610 		Utils::Buffer	  buffer_ssb_gs(m_context);
7611 		Utils::Buffer	  buffer_ssb_tcs(m_context);
7612 		Utils::Buffer	  buffer_ssb_tes(m_context);
7613 		Utils::Buffer	  buffer_ssb_vs(m_context);
7614 		Utils::Buffer	  buffer_u_fs(m_context);
7615 		Utils::Buffer	  buffer_u_gs(m_context);
7616 		Utils::Buffer	  buffer_u_tcs(m_context);
7617 		Utils::Buffer	  buffer_u_tes(m_context);
7618 		Utils::Buffer	  buffer_u_vs(m_context);
7619 		Utils::Framebuffer framebuffer(m_context);
7620 		Utils::Program	 program(m_context);
7621 		Utils::Texture	 texture_fb(m_context);
7622 		Utils::VertexArray vao(m_context);
7623 
7624 		/* */
7625 		const std::string& fragment_shader =
7626 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7627 		const std::string& geometry_shader =
7628 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7629 		const std::string& tess_ctrl_shader =
7630 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7631 		const std::string& tess_eval_shader =
7632 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7633 		const std::string& vertex_shader =
7634 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7635 
7636 		program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
7637 					 vertex_shader, false /* is_separable */);
7638 
7639 		/* */
7640 		prepareAttribLocation(program, program_interface);
7641 		prepareFragmentDataLoc(program, program_interface);
7642 
7643 		/* */
7644 		std::stringstream stream;
7645 		if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream))
7646 		{
7647 			m_context.getTestContext().getLog()
7648 				<< tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7649 				<< ". Inspection of draw program interface failed:\n"
7650 				<< stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7651 				<< tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7652 				<< tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7653 
7654 			return false;
7655 		}
7656 
7657 		/* */
7658 		program.Use();
7659 
7660 		/* */
7661 		buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7662 		vao.Init();
7663 		prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7664 
7665 		/* */
7666 		prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs,
7667 						buffer_u_tes, buffer_u_vs);
7668 
7669 		prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs,
7670 					buffer_ssb_tes, buffer_ssb_vs);
7671 
7672 		/* */
7673 		prepareFramebuffer(framebuffer, texture_fb);
7674 
7675 		/* Draw */
7676 		executeDrawCall(test_case_index);
7677 
7678 #if USE_NSIGHT
7679 		m_context.getRenderContext().postIterate();
7680 #endif
7681 
7682 		/* Check results */
7683 		if (false == checkResults(test_case_index, texture_fb))
7684 		{
7685 			m_context.getTestContext().getLog()
7686 				<< tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7687 				<< tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7688 				<< tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7689 				<< tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7690 
7691 			result = false;
7692 		}
7693 	}
7694 
7695 	/* Compute */
7696 	if (true == isComputeRelevant(test_case_index))
7697 	{
7698 		Utils::Buffer	  buffer_ssb_cs(m_context);
7699 		Utils::Buffer	  buffer_u_cs(m_context);
7700 		Utils::Program	 program(m_context);
7701 		Utils::Texture	 texture_im(m_context);
7702 		Utils::VertexArray vao(m_context);
7703 
7704 		/* */
7705 		const std::string& compute_shader =
7706 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7707 
7708 		program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7709 					 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7710 
7711 		/* */
7712 		{
7713 			std::stringstream stream;
7714 
7715 			if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7716 			{
7717 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7718 													<< ". Inspection of compute program interface failed:\n"
7719 													<< stream.str() << tcu::TestLog::EndMessage;
7720 
7721 				return false;
7722 			}
7723 		}
7724 
7725 		/* */
7726 		program.Use();
7727 
7728 		/* */
7729 		vao.Init();
7730 		vao.Bind();
7731 
7732 		/* */
7733 		prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7734 
7735 		prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs);
7736 
7737 		/* */
7738 		GLint image_location = program.GetUniformLocation("uni_image");
7739 		prepareImage(image_location, texture_im);
7740 
7741 		/* Draw */
7742 		executeDispatchCall(test_case_index);
7743 
7744 #if USE_NSIGHT
7745 		m_context.getRenderContext().postIterate();
7746 #endif
7747 
7748 		/* Check results */
7749 		if (false == checkResults(test_case_index, texture_im))
7750 		{
7751 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7752 												<< ". Compute - invalid results." << tcu::TestLog::EndMessage
7753 												<< tcu::TestLog::KernelSource(compute_shader);
7754 
7755 			result = false;
7756 		}
7757 	}
7758 
7759 	return result;
7760 }
7761 
7762 /** Runs "draw" test with separable program
7763  *
7764  * @param test_case_index Id of test case
7765  **/
7766 bool TextureTestBase::testSeparable(GLuint test_case_index)
7767 {
7768 	Utils::ProgramInterface   program_interface;
7769 	Utils::VaryingPassthrough varying_passthrough;
7770 
7771 	/* */
7772 	const std::string& test_name = getTestCaseName(test_case_index);
7773 
7774 	/* */
7775 	getProgramInterface(test_case_index, program_interface, varying_passthrough);
7776 
7777 	bool result = true;
7778 	/* Draw */
7779 	if (true == isDrawRelevant(test_case_index))
7780 	{
7781 		Utils::Buffer	  buffer_attr(m_context);
7782 		Utils::Buffer	  buffer_u_fs(m_context);
7783 		Utils::Buffer	  buffer_u_gs(m_context);
7784 		Utils::Buffer	  buffer_u_tcs(m_context);
7785 		Utils::Buffer	  buffer_u_tes(m_context);
7786 		Utils::Buffer	  buffer_u_vs(m_context);
7787 		Utils::Framebuffer framebuffer(m_context);
7788 		Utils::Pipeline	pipeline(m_context);
7789 		Utils::Program	 program_fs(m_context);
7790 		Utils::Program	 program_gs(m_context);
7791 		Utils::Program	 program_tcs(m_context);
7792 		Utils::Program	 program_tes(m_context);
7793 		Utils::Program	 program_vs(m_context);
7794 		Utils::Texture	 texture_fb(m_context);
7795 		Utils::VertexArray vao(m_context);
7796 
7797 		/* */
7798 		const std::string& fs =
7799 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7800 		const std::string& gs =
7801 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7802 		const std::string& tcs =
7803 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7804 		const std::string& tes =
7805 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7806 		const std::string& vs =
7807 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7808 
7809 		program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7810 		program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7811 		program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7812 		program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */);
7813 		program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */);
7814 
7815 		/* */
7816 		prepareAttribLocation(program_vs, program_interface);
7817 		prepareFragmentDataLoc(program_vs, program_interface);
7818 
7819 		/* */
7820 		std::stringstream stream;
7821 		if ((false ==
7822 			 Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) ||
7823 			(false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT,
7824 																stream)) ||
7825 			(false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY,
7826 																stream)) ||
7827 			(false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface,
7828 																Utils::Shader::TESS_CTRL, stream)) ||
7829 			(false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface,
7830 																Utils::Shader::TESS_EVAL, stream)))
7831 		{
7832 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7833 												<< ". Inspection of separable draw program interface failed:\n"
7834 												<< stream.str() << tcu::TestLog::EndMessage
7835 												<< tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7836 												<< tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7837 												<< tcu::TestLog::KernelSource(fs);
7838 
7839 			return false;
7840 		}
7841 
7842 		/* */
7843 		pipeline.Init();
7844 		pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT);
7845 		pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT);
7846 		pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT);
7847 		pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT);
7848 		pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT);
7849 		pipeline.Bind();
7850 
7851 		/* */
7852 
7853 		buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7854 		vao.Init();
7855 		prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7856 
7857 		/* */
7858 		prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes,
7859 						program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs);
7860 
7861 		Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id);
7862 
7863 		/* */
7864 		prepareFramebuffer(framebuffer, texture_fb);
7865 
7866 		/* Draw */
7867 		executeDrawCall(test_case_index);
7868 
7869 #if USE_NSIGHT
7870 		m_context.getRenderContext().postIterate();
7871 #endif
7872 
7873 		/* Check results */
7874 		if (false == checkResults(test_case_index, texture_fb))
7875 		{
7876 			m_context.getTestContext().getLog()
7877 				<< tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7878 				<< tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7879 				<< tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs);
7880 
7881 			result = false;
7882 		}
7883 		else
7884 		{
7885 			m_context.getTestContext().getLog()
7886 				<< tcu::TestLog::Message << "Success." << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs)
7887 				<< tcu::TestLog::KernelSource(tcs) << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7888 				<< tcu::TestLog::KernelSource(fs);
7889 		}
7890 	}
7891 
7892 	/* Compute */
7893 	if (true == isComputeRelevant(test_case_index))
7894 	{
7895 		Utils::Buffer	  buffer_u_cs(m_context);
7896 		Utils::Program	 program(m_context);
7897 		Utils::Texture	 texture_im(m_context);
7898 		Utils::VertexArray vao(m_context);
7899 
7900 		/* */
7901 		const std::string& compute_shader =
7902 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7903 
7904 		program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7905 					 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7906 
7907 		/* */
7908 		{
7909 			std::stringstream stream;
7910 
7911 			if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7912 			{
7913 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7914 													<< ". Inspection of compute program interface failed:\n"
7915 													<< stream.str() << tcu::TestLog::EndMessage;
7916 
7917 				return false;
7918 			}
7919 		}
7920 
7921 		/* */
7922 		program.Use();
7923 
7924 		/* */
7925 		vao.Init();
7926 		vao.Bind();
7927 
7928 		/* */
7929 		prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7930 
7931 		/* */
7932 		GLint image_location = program.GetUniformLocation("uni_image");
7933 		prepareImage(image_location, texture_im);
7934 
7935 		/* Draw */
7936 		executeDispatchCall(test_case_index);
7937 
7938 #if USE_NSIGHT
7939 		m_context.getRenderContext().postIterate();
7940 #endif
7941 
7942 		/* Check results */
7943 		if (false == checkResults(test_case_index, texture_im))
7944 		{
7945 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7946 												<< ". Compute - invalid results." << tcu::TestLog::EndMessage
7947 												<< tcu::TestLog::KernelSource(compute_shader);
7948 
7949 			result = false;
7950 		}
7951 	}
7952 
7953 	return result;
7954 }
7955 
7956 /** Basic implementation
7957  *
7958  * @param ignored
7959  *
7960  * @return false
7961  **/
7962 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */)
7963 {
7964 	return false;
7965 }
7966 
7967 /** Basic implementation
7968  *
7969  * @param ignored
7970  *
7971  * @return true
7972  **/
7973 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */)
7974 {
7975 	return true;
7976 }
7977 
7978 /** Constructor
7979  *
7980  * @param context Test framework context
7981  **/
7982 APIConstantValuesTest::APIConstantValuesTest(deqp::Context& context)
7983 	: TestCase(context, "api_constant_values", "Test verifies values of api constants")
7984 {
7985 	/* Nothing to be done here */
7986 }
7987 
7988 /** Execute test
7989  *
7990  * @return tcu::TestNode::STOP otherwise
7991  **/
7992 tcu::TestNode::IterateResult APIConstantValuesTest::iterate()
7993 {
7994 	static const GLuint expected_comp = 64;
7995 	static const GLuint expected_xfb  = 4;
7996 	static const GLuint expected_sep  = 4;
7997 	GLint				max_comp	  = 0;
7998 	GLint				max_xfb		  = 0;
7999 	GLint				max_sep		  = 0;
8000 	bool				test_result   = true;
8001 
8002 	const Functions& gl = m_context.getRenderContext().getFunctions();
8003 
8004 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
8005 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8006 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp);
8007 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8008 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep);
8009 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8010 
8011 	if (expected_xfb > (GLuint)max_xfb)
8012 	{
8013 		m_context.getTestContext().getLog() << tcu::TestLog::Message
8014 											<< "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb
8015 											<< " Expected at least " << expected_xfb << tcu::TestLog::EndMessage;
8016 
8017 		test_result = false;
8018 	}
8019 
8020 	if (expected_comp > (GLuint)max_comp)
8021 	{
8022 		m_context.getTestContext().getLog()
8023 			<< tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp
8024 			<< " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
8025 
8026 		test_result = false;
8027 	}
8028 
8029 	if (expected_sep > (GLuint)max_sep)
8030 	{
8031 		m_context.getTestContext().getLog() << tcu::TestLog::Message
8032 											<< "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp
8033 											<< " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
8034 
8035 		test_result = false;
8036 	}
8037 
8038 	/* Set result */
8039 	if (true == test_result)
8040 	{
8041 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
8042 	}
8043 	else
8044 	{
8045 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8046 	}
8047 
8048 	/* Done */
8049 	return tcu::TestNode::STOP;
8050 }
8051 
8052 /** Constructor
8053  *
8054  * @param context Test framework context
8055  **/
8056 APIErrorsTest::APIErrorsTest(deqp::Context& context)
8057 	: TestCase(context, "api_errors", "Test verifies errors reeturned by api")
8058 {
8059 	/* Nothing to be done here */
8060 }
8061 
8062 /** Execute test
8063  *
8064  * @return tcu::TestNode::STOP otherwise
8065  **/
8066 tcu::TestNode::IterateResult APIErrorsTest::iterate()
8067 {
8068 	GLint		   length = 0;
8069 	GLchar		   name[64];
8070 	GLint		   param = 0;
8071 	Utils::Program program(m_context);
8072 	bool		   test_result = true;
8073 
8074 	const Functions& gl = m_context.getRenderContext().getFunctions();
8075 
8076 	try
8077 	{
8078 		program.Init("" /* cs */, "#version 430 core\n"
8079 								  "#extension GL_ARB_enhanced_layouts : require\n"
8080 								  "\n"
8081 								  "in  vec4 vs_fs;\n"
8082 								  "out vec4 fs_out;\n"
8083 								  "\n"
8084 								  "void main()\n"
8085 								  "{\n"
8086 								  "    fs_out = vs_fs;\n"
8087 								  "}\n"
8088 								  "\n" /* fs */,
8089 					 "" /* gs */, "" /* tcs */, "" /* tes */, "#version 430 core\n"
8090 															  "#extension GL_ARB_enhanced_layouts : require\n"
8091 															  "\n"
8092 															  "in  vec4 in_vs;\n"
8093 															  "layout (xfb_offset = 16) out vec4 vs_fs;\n"
8094 															  "\n"
8095 															  "void main()\n"
8096 															  "{\n"
8097 															  "    vs_fs = in_vs;\n"
8098 															  "}\n"
8099 															  "\n" /* vs */,
8100 					 false /* separable */);
8101 	}
8102 	catch (Utils::Shader::InvalidSourceException& exc)
8103 	{
8104 		exc.log(m_context);
8105 		TCU_FAIL(exc.what());
8106 	}
8107 	catch (Utils::Program::BuildException& exc)
8108 	{
8109 		TCU_FAIL(exc.what());
8110 	}
8111 
8112 	/*
8113 	 * - GetProgramInterfaceiv should generate INVALID_OPERATION when
8114 	 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the
8115 	 * following:
8116 	 *   * MAX_NAME_LENGTH,
8117 	 *   * MAX_NUM_ACTIVE_VARIABLES;
8118 	 */
8119 	gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, &param);
8120 	checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)",
8121 			   test_result);
8122 
8123 	/*
8124 	 * - GetProgramResourceIndex should generate INVALID_ENUM when
8125 	 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
8126 	 */
8127 	gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0");
8128 	checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
8129 	/*
8130 	 * - GetProgramResourceName should generate INVALID_ENUM when
8131 	 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
8132 	 */
8133 	gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length,
8134 							  name);
8135 	checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
8136 
8137 	/* Set result */
8138 	if (true == test_result)
8139 	{
8140 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
8141 	}
8142 	else
8143 	{
8144 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8145 	}
8146 
8147 	/* Done */
8148 	return tcu::TestNode::STOP;
8149 }
8150 
8151 /** Check if error is the expected one.
8152  *
8153  * @param expected_error Expected error
8154  * @param message        Message to log in case of error
8155  * @param test_result    Test result, set to false in case of invalid error
8156  **/
8157 void APIErrorsTest::checkError(GLenum expected_error, const GLchar* message, bool& test_result)
8158 {
8159 	const Functions& gl = m_context.getRenderContext().getFunctions();
8160 
8161 	GLenum error = gl.getError();
8162 
8163 	if (error != expected_error)
8164 	{
8165 		m_context.getTestContext().getLog()
8166 			<< tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected "
8167 			<< glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage;
8168 
8169 		test_result = false;
8170 	}
8171 }
8172 
8173 /** Constructor
8174  *
8175  * @param context Test framework context
8176  **/
8177 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context& context)
8178 	: NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified")
8179 {
8180 	/* Nothing to be done here */
8181 }
8182 
8183 /** Source for given test case and stage
8184  *
8185  * @param test_case_index Index of test case
8186  * @param stage           Shader stage
8187  *
8188  * @return Shader source
8189  **/
8190 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
8191 {
8192 	static const GLchar* cs = "#version 430 core\n"
8193 							  "#extension GL_ARB_enhanced_layouts : require\n"
8194 							  "\n"
8195 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8196 							  "\n"
8197 							  "writeonly uniform uimage2D uni_image;\n"
8198 							  "\n"
8199 							  "void main()\n"
8200 							  "{\n"
8201 							  "    uint result = 1u;\n"
8202 							  "    CONSTANT = 3;\n"
8203 							  "\n"
8204 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
8205 							  "}\n"
8206 							  "\n";
8207 	static const GLchar* fs = "#version 430 core\n"
8208 							  "#extension GL_ARB_enhanced_layouts : require\n"
8209 							  "\n"
8210 							  "in  vec4 gs_fs;\n"
8211 							  "out vec4 fs_out;\n"
8212 							  "\n"
8213 							  "void main()\n"
8214 							  "{\n"
8215 							  "ASSIGNMENT"
8216 							  "    fs_out = gs_fs;\n"
8217 							  "}\n"
8218 							  "\n";
8219 	static const GLchar* gs = "#version 430 core\n"
8220 							  "#extension GL_ARB_enhanced_layouts : require\n"
8221 							  "\n"
8222 							  "layout(points)                           in;\n"
8223 							  "layout(triangle_strip, max_vertices = 4) out;\n"
8224 							  "\n"
8225 							  "in  vec4 tes_gs[];\n"
8226 							  "out vec4 gs_fs;\n"
8227 							  "\n"
8228 							  "void main()\n"
8229 							  "{\n"
8230 							  "ASSIGNMENT"
8231 							  "    gs_fs = tes_gs[0];\n"
8232 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
8233 							  "    EmitVertex();\n"
8234 							  "    gs_fs = tes_gs[0];\n"
8235 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
8236 							  "    EmitVertex();\n"
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 							  "}\n"
8244 							  "\n";
8245 	static const GLchar* tcs = "#version 430 core\n"
8246 							   "#extension GL_ARB_enhanced_layouts : require\n"
8247 							   "\n"
8248 							   "layout(vertices = 1) out;\n"
8249 							   "\n"
8250 							   "in  vec4 vs_tcs[];\n"
8251 							   "out vec4 tcs_tes[];\n"
8252 							   "\n"
8253 							   "void main()\n"
8254 							   "{\n"
8255 							   "\n"
8256 							   "ASSIGNMENT"
8257 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
8258 							   "\n"
8259 							   "    gl_TessLevelOuter[0] = 1.0;\n"
8260 							   "    gl_TessLevelOuter[1] = 1.0;\n"
8261 							   "    gl_TessLevelOuter[2] = 1.0;\n"
8262 							   "    gl_TessLevelOuter[3] = 1.0;\n"
8263 							   "    gl_TessLevelInner[0] = 1.0;\n"
8264 							   "    gl_TessLevelInner[1] = 1.0;\n"
8265 							   "}\n"
8266 							   "\n";
8267 	static const GLchar* tes = "#version 430 core\n"
8268 							   "#extension GL_ARB_enhanced_layouts : require\n"
8269 							   "\n"
8270 							   "layout(isolines, point_mode) in;\n"
8271 							   "\n"
8272 							   "in  vec4 tcs_tes[];\n"
8273 							   "out vec4 tes_gs;\n"
8274 							   "\n"
8275 							   "void main()\n"
8276 							   "{\n"
8277 							   "ASSIGNMENT"
8278 							   "    tes_gs = tcs_tes[0];\n"
8279 							   "}\n"
8280 							   "\n";
8281 	static const GLchar* vs = "#version 430 core\n"
8282 							  "#extension GL_ARB_enhanced_layouts : require\n"
8283 							  "\n"
8284 							  "in  vec4 in_vs;\n"
8285 							  "out vec4 vs_tcs;\n"
8286 							  "\n"
8287 							  "void main()\n"
8288 							  "{\n"
8289 							  "ASSIGNMENT"
8290 							  "    vs_tcs = in_vs;\n"
8291 							  "}\n"
8292 							  "\n";
8293 
8294 	std::string source;
8295 	testCase&   test_case = m_test_cases[test_case_index];
8296 
8297 	if (Utils::Shader::COMPUTE == test_case.m_stage)
8298 	{
8299 		size_t position = 0;
8300 
8301 		source = cs;
8302 
8303 		Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source);
8304 	}
8305 	else
8306 	{
8307 		std::string assignment = "    CONSTANT = 3;\n";
8308 		size_t		position   = 0;
8309 
8310 		switch (stage)
8311 		{
8312 		case Utils::Shader::FRAGMENT:
8313 			source = fs;
8314 			break;
8315 		case Utils::Shader::GEOMETRY:
8316 			source = gs;
8317 			break;
8318 		case Utils::Shader::TESS_CTRL:
8319 			source = tcs;
8320 			break;
8321 		case Utils::Shader::TESS_EVAL:
8322 			source = tes;
8323 			break;
8324 		case Utils::Shader::VERTEX:
8325 			source = vs;
8326 			break;
8327 		default:
8328 			TCU_FAIL("Invalid enum");
8329 		}
8330 
8331 		if (test_case.m_stage == stage)
8332 		{
8333 			Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment);
8334 		}
8335 		else
8336 		{
8337 			assignment = "";
8338 		}
8339 
8340 		position = 0;
8341 		Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source);
8342 	}
8343 
8344 	return source;
8345 }
8346 
8347 /** Get description of test case
8348  *
8349  * @param test_case_index Index of test case
8350  *
8351  * @return Constant name
8352  **/
8353 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index)
8354 {
8355 	std::string result = getConstantName(m_test_cases[test_case_index].m_constant);
8356 
8357 	return result;
8358 }
8359 
8360 /** Get number of test cases
8361  *
8362  * @return Number of test cases
8363  **/
8364 GLuint GLSLContantImmutablityTest::getTestCaseNumber()
8365 {
8366 	return static_cast<GLuint>(m_test_cases.size());
8367 }
8368 
8369 /** Selects if "compute" stage is relevant for test
8370  *
8371  * @param test_case_index Index of test case
8372  *
8373  * @return true when tested stage is compute
8374  **/
8375 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index)
8376 {
8377 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8378 }
8379 
8380 /** Prepare all test cases
8381  *
8382  **/
8383 void GLSLContantImmutablityTest::testInit()
8384 {
8385 	for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant)
8386 	{
8387 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8388 		{
8389 			testCase test_case = { (CONSTANTS)constant, (Utils::Shader::STAGES)stage };
8390 
8391 			m_test_cases.push_back(test_case);
8392 		}
8393 	}
8394 }
8395 
8396 /** Get name of glsl constant
8397  *
8398  * @param Constant id
8399  *
8400  * @return Name of constant used in GLSL
8401  **/
8402 const GLchar* GLSLContantImmutablityTest::getConstantName(CONSTANTS constant)
8403 {
8404 	const GLchar* name = "";
8405 
8406 	switch (constant)
8407 	{
8408 	case GL_ARB_ENHANCED_LAYOUTS:
8409 		name = "GL_ARB_enhanced_layouts";
8410 		break;
8411 	case GL_MAX_XFB:
8412 		name = "gl_MaxTransformFeedbackBuffers";
8413 		break;
8414 	case GL_MAX_XFB_INT_COMP:
8415 		name = "gl_MaxTransformFeedbackInterleavedComponents";
8416 		break;
8417 	default:
8418 		TCU_FAIL("Invalid enum");
8419 	}
8420 
8421 	return name;
8422 }
8423 
8424 /** Constructor
8425  *
8426  * @param context Test framework context
8427  **/
8428 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context& context)
8429 	: TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols")
8430 {
8431 }
8432 
8433 /** Selects if "compute" stage is relevant for test
8434  *
8435  * @param ignored
8436  *
8437  * @return false
8438  **/
8439 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */)
8440 {
8441 	return false;
8442 }
8443 
8444 /** Prepare code snippet that will verify in and uniform variables
8445  *
8446  * @param ignored
8447  * @param ignored
8448  * @param stage   Shader stage
8449  *
8450  * @return Code that verify variables
8451  **/
8452 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */,
8453 														  Utils::ProgramInterface& /* program_interface */,
8454 														  Utils::Shader::STAGES stage)
8455 {
8456 	/* Get constants */
8457 	const Functions& gl = m_context.getRenderContext().getFunctions();
8458 
8459 	GLint max_transform_feedback_buffers				= 0;
8460 	GLint max_transform_feedback_interleaved_components = 0;
8461 
8462 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8463 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8464 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8465 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8466 
8467 	std::string verification;
8468 
8469 	if (Utils::Shader::VERTEX == stage)
8470 	{
8471 		verification = "if (1 != GL_ARB_enhanced_layouts)\n"
8472 					   "    {\n"
8473 					   "        result = 0;\n"
8474 					   "    }\n"
8475 					   "    else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n"
8476 					   "        != gl_MaxTransformFeedbackBuffers)\n"
8477 					   "    {\n"
8478 					   "        result = 0;\n"
8479 					   "    }\n"
8480 					   "    else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n"
8481 					   "        != gl_MaxTransformFeedbackInterleavedComponents)\n"
8482 					   "    {\n"
8483 					   "        result = 0;\n"
8484 					   "    }\n";
8485 
8486 		size_t position = 0;
8487 		GLchar buffer[16];
8488 
8489 		sprintf(buffer, "%d", max_transform_feedback_buffers);
8490 		Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification);
8491 
8492 		sprintf(buffer, "%d", max_transform_feedback_interleaved_components);
8493 		Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification);
8494 	}
8495 	else
8496 	{
8497 		verification = "";
8498 	}
8499 
8500 	return verification;
8501 }
8502 
8503 /** Constructor
8504  *
8505  * @param context Test framework context
8506  **/
8507 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context& context)
8508 	: TextureTestBase(context, "glsl_constant_integral_expression",
8509 					  "Test verifies that symbols can be used as constant integral expressions")
8510 {
8511 }
8512 
8513 /** Get interface of program
8514  *
8515  * @param ignored
8516  * @param program_interface Interface of program
8517  * @param ignored
8518  **/
8519 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */,
8520 															 Utils::ProgramInterface& program_interface,
8521 															 Utils::VaryingPassthrough& /* varying_passthrough */)
8522 {
8523 	/* Get constants */
8524 	const Functions& gl = m_context.getRenderContext().getFunctions();
8525 
8526 	GLint max_transform_feedback_buffers				= 0;
8527 	GLint max_transform_feedback_interleaved_components = 0;
8528 
8529 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8530 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8531 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8532 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8533 
8534 	GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16);
8535 	GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16);
8536 
8537 	m_gohan_length = max_transform_feedback_buffers / gohan_div;
8538 	m_goten_length = max_transform_feedback_interleaved_components / goten_div;
8539 
8540 	/* Globals */
8541 	std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n"
8542 						  "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n"
8543 						  "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n";
8544 
8545 	size_t position = 0;
8546 	GLchar buffer[16];
8547 
8548 	sprintf(buffer, "%d", gohan_div);
8549 	Utils::replaceToken("GOHAN_DIV", position, buffer, globals);
8550 
8551 	sprintf(buffer, "%d", goten_div);
8552 	Utils::replaceToken("GOTEN_DIV", position, buffer, globals);
8553 
8554 	program_interface.m_vertex.m_globals	= globals;
8555 	program_interface.m_tess_ctrl.m_globals = globals;
8556 	program_interface.m_tess_eval.m_globals = globals;
8557 	program_interface.m_geometry.m_globals  = globals;
8558 	program_interface.m_fragment.m_globals  = globals;
8559 	program_interface.m_compute.m_globals   = globals;
8560 }
8561 
8562 /** Prepare code snippet that will verify in and uniform variables
8563  *
8564  * @param ignored
8565  * @param ignored
8566  * @param ignored
8567  *
8568  * @return Code that verify variables
8569  **/
8570 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(GLuint /* test_case_index */,
8571 																	   Utils::ProgramInterface& /* program_interface */,
8572 																	   Utils::Shader::STAGES /* stage */)
8573 {
8574 	std::string verification = "{\n"
8575 							   "        uint goku_sum = 0;\n"
8576 							   "        uint gohan_sum = 0;\n"
8577 							   "        uint goten_sum = 0;\n"
8578 							   "\n"
8579 							   "        for (uint i = 0u; i < goku.length(); ++i)\n"
8580 							   "        {\n"
8581 							   "            goku_sum += goku[i];\n"
8582 							   "        }\n"
8583 							   "\n"
8584 							   "        for (uint i = 0u; i < gohan.length(); ++i)\n"
8585 							   "        {\n"
8586 							   "            gohan_sum += gohan[i];\n"
8587 							   "        }\n"
8588 							   "\n"
8589 							   "        for (uint i = 0u; i < goten.length(); ++i)\n"
8590 							   "        {\n"
8591 							   "            goten_sum += goten[i];\n"
8592 							   "        }\n"
8593 							   "\n"
8594 							   "        if ( (1u != goku_sum)  &&\n"
8595 							   "             (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n"
8596 							   "             (EXPECTED_GOTEN_SUMu != goten_sum) )\n"
8597 							   "        {\n"
8598 							   "            result = 0u;\n"
8599 							   "        }\n"
8600 							   "    }\n";
8601 
8602 	size_t position = 0;
8603 	GLchar buffer[16];
8604 
8605 	sprintf(buffer, "%d", m_gohan_length);
8606 	Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification);
8607 
8608 	sprintf(buffer, "%d", m_goten_length);
8609 	Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification);
8610 
8611 	return verification;
8612 }
8613 
8614 /** Prepare unifroms
8615  *
8616  * @param ignored
8617  * @param ignored
8618  * @param program Program object
8619  * @param ignored
8620  **/
8621 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */,
8622 														 Utils::ProgramInterface& /* program_interface */,
8623 														 Utils::Program& program, Utils::Buffer& /* cs_buffer */)
8624 {
8625 	static const GLuint uniform_data[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
8626 
8627 	const Functions& gl = m_context.getRenderContext().getFunctions();
8628 
8629 	GLint goku_location  = program.GetUniformLocation("goku");
8630 	GLint gohan_location = program.GetUniformLocation("gohan");
8631 	GLint goten_location = program.GetUniformLocation("goten");
8632 
8633 	program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data);
8634 	program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data);
8635 	program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data);
8636 }
8637 
8638 /** Prepare unifroms
8639  *
8640  * @param test_case_index   Pass as param to first implemetnation
8641  * @param program_interface Pass as param to first implemetnation
8642  * @param program           Pass as param to first implemetnation
8643  * @param ignored
8644  * @param ignored
8645  * @param ignored
8646  * @param ignored
8647  * @param vs_buffer         Pass as param to first implemetnation
8648  **/
8649 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint					  test_case_index,
8650 														 Utils::ProgramInterface& program_interface,
8651 														 Utils::Program& program, Utils::Buffer& /* fs_buffer */,
8652 														 Utils::Buffer& /* gs_buffer */,
8653 														 Utils::Buffer& /* tcs_buffer */,
8654 														 Utils::Buffer& /* tes_buffer */, Utils::Buffer& vs_buffer)
8655 {
8656 	/* Call first implementation */
8657 	prepareUniforms(test_case_index, program_interface, program, vs_buffer);
8658 }
8659 
8660 /** Constructor
8661  *
8662  * @param context Test framework context
8663  **/
8664 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context& context)
8665 	: TextureTestBase(context, "uniform_block_member_offset_and_align",
8666 					  "Test verifies offsets and alignment of uniform buffer members")
8667 {
8668 }
8669 
8670 /** Get interface of program
8671  *
8672  * @param test_case_index     Test case index
8673  * @param program_interface   Interface of program
8674  * @param varying_passthrough Collection of connections between in and out variables
8675  **/
8676 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint					  test_case_index,
8677 															   Utils::ProgramInterface&   program_interface,
8678 															   Utils::VaryingPassthrough& varying_passthrough)
8679 {
8680 	std::string globals = "const int basic_size = BASIC_SIZE;\n"
8681 						  "const int type_align = TYPE_ALIGN;\n"
8682 						  "const int type_size  = TYPE_SIZE;\n";
8683 
8684 	Utils::Type  type		 = getType(test_case_index);
8685 	GLuint		 basic_size  = Utils::Type::GetTypeSize(type.m_basic_type);
8686 	const GLuint base_align  = type.GetBaseAlignment(false);
8687 	const GLuint array_align = type.GetBaseAlignment(true);
8688 	const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
8689 	const GLuint type_align  = Utils::roundUpToPowerOf2(base_stride);
8690 
8691 	/* Calculate offsets */
8692 	const GLuint first_offset  = 0;
8693 	const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
8694 
8695 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
8696 
8697 	const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, base_align);
8698 	const GLuint fourth_offset  = type.GetActualOffset(third_offset + base_stride, base_align);
8699 	const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
8700 	const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
8701 	const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8702 	const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, array_align);
8703 
8704 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8705 
8706 	const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
8707 	const GLuint fourth_offset  = type.GetActualOffset(3 * type_align + base_stride, base_align);
8708 	const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
8709 	const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
8710 	const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8711 	const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
8712 
8713 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8714 
8715 	/* Prepare data */
8716 	const std::vector<GLubyte>& first  = type.GenerateData();
8717 	const std::vector<GLubyte>& second = type.GenerateData();
8718 	const std::vector<GLubyte>& third  = type.GenerateData();
8719 	const std::vector<GLubyte>& fourth = type.GenerateData();
8720 
8721 	m_data.resize(eigth_offset + base_stride);
8722 	GLubyte* ptr = &m_data[0];
8723 	memcpy(ptr + first_offset, &first[0], first.size());
8724 	memcpy(ptr + second_offset, &second[0], second.size());
8725 	memcpy(ptr + third_offset, &third[0], third.size());
8726 	memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
8727 	memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
8728 	memcpy(ptr + sixth_offset, &third[0], third.size());
8729 	memcpy(ptr + seventh_offset, &second[0], second.size());
8730 	memcpy(ptr + eigth_offset, &first[0], first.size());
8731 
8732 	/* Prepare globals */
8733 	size_t position = 0;
8734 	GLchar buffer[16];
8735 
8736 	sprintf(buffer, "%d", basic_size);
8737 	Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
8738 
8739 	sprintf(buffer, "%d", type_align);
8740 	Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
8741 
8742 	sprintf(buffer, "%d", base_stride);
8743 	Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
8744 
8745 	/* Prepare Block */
8746 	Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
8747 
8748 	vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
8749 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8750 						 first_offset);
8751 
8752 	vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
8753 						 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
8754 						 0 /* n_array_elements */, base_stride, second_offset);
8755 
8756 	vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
8757 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8758 						 third_offset);
8759 
8760 	vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
8761 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8762 						 fourth_offset);
8763 
8764 	vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8765 						 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
8766 
8767 	vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8768 						 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
8769 
8770 	vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
8771 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8772 						 eigth_offset);
8773 
8774 	Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
8775 
8776 	/* Add globals */
8777 	vs_si.m_globals = globals;
8778 
8779 	/* Add uniform BLOCK */
8780 	vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
8781 				  static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size());
8782 
8783 	/* */
8784 	program_interface.CloneVertexInterface(varying_passthrough);
8785 }
8786 
8787 /** Get type name
8788  *
8789  * @param test_case_index Index of test case
8790  *
8791  * @return Name of type test in test_case_index
8792  **/
8793 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
8794 {
8795 	return getTypeName(test_case_index);
8796 }
8797 
8798 /** Returns number of types to test
8799  *
8800  * @return Number of types, 34
8801  **/
8802 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber()
8803 {
8804 	return getTypesNumber();
8805 }
8806 
8807 /** Prepare code snippet that will verify in and uniform variables
8808  *
8809  * @param ignored
8810  * @param ignored
8811  * @param stage   Shader stage
8812  *
8813  * @return Code that verify variables
8814  **/
8815 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet(
8816 	GLuint /* test_case_index */, Utils::ProgramInterface& /* program_interface */, Utils::Shader::STAGES stage)
8817 {
8818 	std::string verification = "if ( (PREFIXblock.at_first_offset  != PREFIXblock.at_eigth_offset   ) ||\n"
8819 							   "         (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
8820 							   "         (PREFIXblock.at_third_offset  != PREFIXblock.at_sixth_offset[0]) ||\n"
8821 							   "         (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset   )  )\n"
8822 							   "    {\n"
8823 							   "        result = 0;\n"
8824 							   "    }";
8825 
8826 	const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM);
8827 
8828 	Utils::replaceAllTokens("PREFIX", prefix, verification);
8829 
8830 	return verification;
8831 }
8832 
8833 /** Constructor
8834  *
8835  * @param context Test framework context
8836  **/
8837 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context& context)
8838 	: NegativeTestBase(
8839 		  context, "uniform_block_layout_qualifier_conflict",
8840 		  "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block")
8841 {
8842 	/* Nothing to be done here */
8843 }
8844 
8845 /** Source for given test case and stage
8846  *
8847  * @param test_case_index Index of test case
8848  * @param stage           Shader stage
8849  *
8850  * @return Shader source
8851  **/
8852 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint				   test_case_index,
8853 																	 Utils::Shader::STAGES stage)
8854 {
8855 	static const GLchar* cs = "#version 430 core\n"
8856 							  "#extension GL_ARB_enhanced_layouts : require\n"
8857 							  "\n"
8858 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8859 							  "\n"
8860 							  "LAYOUTuniform Block {\n"
8861 							  "    layout(offset = 16) vec4 boy;\n"
8862 							  "    layout(align  = 64) vec4 man;\n"
8863 							  "} uni_block;\n"
8864 							  "\n"
8865 							  "writeonly uniform image2D uni_image;\n"
8866 							  "\n"
8867 							  "void main()\n"
8868 							  "{\n"
8869 							  "    vec4 result = uni_block.boy + uni_block.man;\n"
8870 							  "\n"
8871 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8872 							  "}\n"
8873 							  "\n";
8874 	static const GLchar* fs = "#version 430 core\n"
8875 							  "#extension GL_ARB_enhanced_layouts : require\n"
8876 							  "\n"
8877 							  "LAYOUTuniform Block {\n"
8878 							  "    layout(offset = 16) vec4 boy;\n"
8879 							  "    layout(align  = 64) vec4 man;\n"
8880 							  "} uni_block;\n"
8881 							  "\n"
8882 							  "in  vec4 gs_fs;\n"
8883 							  "out vec4 fs_out;\n"
8884 							  "\n"
8885 							  "void main()\n"
8886 							  "{\n"
8887 							  "    fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
8888 							  "}\n"
8889 							  "\n";
8890 	static const GLchar* gs = "#version 430 core\n"
8891 							  "#extension GL_ARB_enhanced_layouts : require\n"
8892 							  "\n"
8893 							  "layout(points)                           in;\n"
8894 							  "layout(triangle_strip, max_vertices = 4) out;\n"
8895 							  "\n"
8896 							  "LAYOUTuniform Block {\n"
8897 							  "    layout(offset = 16) vec4 boy;\n"
8898 							  "    layout(align  = 64) vec4 man;\n"
8899 							  "} uni_block;\n"
8900 							  "\n"
8901 							  "in  vec4 tes_gs[];\n"
8902 							  "out vec4 gs_fs;\n"
8903 							  "\n"
8904 							  "void main()\n"
8905 							  "{\n"
8906 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8907 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
8908 							  "    EmitVertex();\n"
8909 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8910 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
8911 							  "    EmitVertex();\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 							  "}\n"
8919 							  "\n";
8920 	static const GLchar* tcs =
8921 		"#version 430 core\n"
8922 		"#extension GL_ARB_enhanced_layouts : require\n"
8923 		"\n"
8924 		"layout(vertices = 1) out;\n"
8925 		"\n"
8926 		"LAYOUTuniform Block {\n"
8927 		"    layout(offset = 16) vec4 boy;\n"
8928 		"    layout(align  = 64) vec4 man;\n"
8929 		"} uni_block;\n"
8930 		"\n"
8931 		"in  vec4 vs_tcs[];\n"
8932 		"out vec4 tcs_tes[];\n"
8933 		"\n"
8934 		"void main()\n"
8935 		"{\n"
8936 		"\n"
8937 		"    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
8938 		"\n"
8939 		"    gl_TessLevelOuter[0] = 1.0;\n"
8940 		"    gl_TessLevelOuter[1] = 1.0;\n"
8941 		"    gl_TessLevelOuter[2] = 1.0;\n"
8942 		"    gl_TessLevelOuter[3] = 1.0;\n"
8943 		"    gl_TessLevelInner[0] = 1.0;\n"
8944 		"    gl_TessLevelInner[1] = 1.0;\n"
8945 		"}\n"
8946 		"\n";
8947 	static const GLchar* tes = "#version 430 core\n"
8948 							   "#extension GL_ARB_enhanced_layouts : require\n"
8949 							   "\n"
8950 							   "layout(isolines, point_mode) in;\n"
8951 							   "\n"
8952 							   "LAYOUTuniform Block {\n"
8953 							   "    layout(offset = 16) vec4 boy;\n"
8954 							   "    layout(align  = 64) vec4 man;\n"
8955 							   "} uni_block;\n"
8956 							   "\n"
8957 							   "in  vec4 tcs_tes[];\n"
8958 							   "out vec4 tes_gs;\n"
8959 							   "\n"
8960 							   "void main()\n"
8961 							   "{\n"
8962 							   "    tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
8963 							   "}\n"
8964 							   "\n";
8965 	static const GLchar* vs = "#version 430 core\n"
8966 							  "#extension GL_ARB_enhanced_layouts : require\n"
8967 							  "\n"
8968 							  "LAYOUTuniform Block {\n"
8969 							  "    layout(offset = 16) vec4 boy;\n"
8970 							  "    layout(align  = 64) vec4 man;\n"
8971 							  "} uni_block;\n"
8972 							  "\n"
8973 							  "in  vec4 in_vs;\n"
8974 							  "out vec4 vs_tcs;\n"
8975 							  "\n"
8976 							  "void main()\n"
8977 							  "{\n"
8978 							  "    vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
8979 							  "}\n"
8980 							  "\n";
8981 
8982 	std::string   layout	= "";
8983 	size_t		  position  = 0;
8984 	testCase&	 test_case = m_test_cases[test_case_index];
8985 	const GLchar* qualifier = getQualifierName(test_case.m_qualifier);
8986 	std::string   source;
8987 
8988 	if (0 != qualifier[0])
8989 	{
8990 		size_t layout_position = 0;
8991 
8992 		layout = "layout (QUALIFIER) ";
8993 
8994 		Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout);
8995 	}
8996 
8997 	switch (stage)
8998 	{
8999 	case Utils::Shader::COMPUTE:
9000 		source = cs;
9001 		break;
9002 	case Utils::Shader::FRAGMENT:
9003 		source = fs;
9004 		break;
9005 	case Utils::Shader::GEOMETRY:
9006 		source = gs;
9007 		break;
9008 	case Utils::Shader::TESS_CTRL:
9009 		source = tcs;
9010 		break;
9011 	case Utils::Shader::TESS_EVAL:
9012 		source = tes;
9013 		break;
9014 	case Utils::Shader::VERTEX:
9015 		source = vs;
9016 		break;
9017 	default:
9018 		TCU_FAIL("Invalid enum");
9019 	}
9020 
9021 	if (test_case.m_stage == stage)
9022 	{
9023 		Utils::replaceToken("LAYOUT", position, layout.c_str(), source);
9024 	}
9025 	else
9026 	{
9027 		Utils::replaceToken("LAYOUT", position, "layout (std140) ", source);
9028 	}
9029 
9030 	return source;
9031 }
9032 
9033 /** Get description of test case
9034  *
9035  * @param test_case_index Index of test case
9036  *
9037  * @return Qualifier name
9038  **/
9039 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
9040 {
9041 	std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
9042 
9043 	return result;
9044 }
9045 
9046 /** Get number of test cases
9047  *
9048  * @return Number of test cases
9049  **/
9050 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber()
9051 {
9052 	return static_cast<GLuint>(m_test_cases.size());
9053 }
9054 
9055 /** Selects if "compute" stage is relevant for test
9056  *
9057  * @param test_case_index Index of test case
9058  *
9059  * @return true when tested stage is compute
9060  **/
9061 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
9062 {
9063 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9064 }
9065 
9066 /** Selects if compilation failure is expected result
9067  *
9068  * @param test_case_index Index of test case
9069  *
9070  * @return false for STD140 cases, true otherwise
9071  **/
9072 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
9073 {
9074 	return (STD140 != m_test_cases[test_case_index].m_qualifier);
9075 }
9076 
9077 /** Prepare all test cases
9078  *
9079  **/
9080 void UniformBlockLayoutQualifierConflictTest::testInit()
9081 {
9082 	for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
9083 	{
9084 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9085 		{
9086 			testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
9087 
9088 			m_test_cases.push_back(test_case);
9089 		}
9090 	}
9091 }
9092 
9093 /** Get name of glsl constant
9094  *
9095  * @param Constant id
9096  *
9097  * @return Name of constant used in GLSL
9098  **/
9099 const GLchar* UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
9100 {
9101 	const GLchar* name = "";
9102 
9103 	switch (qualifier)
9104 	{
9105 	case DEFAULT:
9106 		name = "";
9107 		break;
9108 	case STD140:
9109 		name = "std140";
9110 		break;
9111 	case SHARED:
9112 		name = "shared";
9113 		break;
9114 	case PACKED:
9115 		name = "packed";
9116 		break;
9117 	default:
9118 		TCU_FAIL("Invalid enum");
9119 	}
9120 
9121 	return name;
9122 }
9123 
9124 /** Constructor
9125  *
9126  * @param context Test framework context
9127  **/
9128 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context)
9129 	: NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment",
9130 					   "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
9131 {
9132 	/* Nothing to be done here */
9133 }
9134 
9135 /** Constructor
9136  *
9137  * @param context     Test framework context
9138  * @param name        Test name
9139  * @param description Test description
9140  **/
9141 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(
9142 	deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
9143 	: NegativeTestBase(context, name, description)
9144 {
9145 	/* Nothing to be done here */
9146 }
9147 
9148 /** Source for given test case and stage
9149  *
9150  * @param test_case_index Index of test case
9151  * @param stage           Shader stage
9152  *
9153  * @return Shader source
9154  **/
9155 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint				test_case_index,
9156 																		  Utils::Shader::STAGES stage)
9157 {
9158 	static const GLchar* cs = "#version 430 core\n"
9159 							  "#extension GL_ARB_enhanced_layouts : require\n"
9160 							  "\n"
9161 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9162 							  "\n"
9163 							  "layout (std140) uniform Block {\n"
9164 							  "    layout (offset = OFFSET) TYPE member;\n"
9165 							  "} block;\n"
9166 							  "\n"
9167 							  "writeonly uniform image2D uni_image;\n"
9168 							  "\n"
9169 							  "void main()\n"
9170 							  "{\n"
9171 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
9172 							  "\n"
9173 							  "    if (TYPE(1) == block.member)\n"
9174 							  "    {\n"
9175 							  "        result = vec4(1, 1, 1, 1);\n"
9176 							  "    }\n"
9177 							  "\n"
9178 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9179 							  "}\n"
9180 							  "\n";
9181 	static const GLchar* fs = "#version 430 core\n"
9182 							  "#extension GL_ARB_enhanced_layouts : require\n"
9183 							  "\n"
9184 							  "in  vec4 gs_fs;\n"
9185 							  "out vec4 fs_out;\n"
9186 							  "\n"
9187 							  "void main()\n"
9188 							  "{\n"
9189 							  "    fs_out = gs_fs;\n"
9190 							  "}\n"
9191 							  "\n";
9192 	static const GLchar* fs_tested = "#version 430 core\n"
9193 									 "#extension GL_ARB_enhanced_layouts : require\n"
9194 									 "\n"
9195 									 "layout (std140) uniform Block {\n"
9196 									 "    layout (offset = OFFSET) TYPE member;\n"
9197 									 "} block;\n"
9198 									 "\n"
9199 									 "in  vec4 gs_fs;\n"
9200 									 "out vec4 fs_out;\n"
9201 									 "\n"
9202 									 "void main()\n"
9203 									 "{\n"
9204 									 "    if (TYPE(1) == block.member)\n"
9205 									 "    {\n"
9206 									 "        fs_out = vec4(1, 1, 1, 1);\n"
9207 									 "    }\n"
9208 									 "\n"
9209 									 "    fs_out += gs_fs;\n"
9210 									 "}\n"
9211 									 "\n";
9212 	static const GLchar* gs = "#version 430 core\n"
9213 							  "#extension GL_ARB_enhanced_layouts : require\n"
9214 							  "\n"
9215 							  "layout(points)                           in;\n"
9216 							  "layout(triangle_strip, max_vertices = 4) out;\n"
9217 							  "\n"
9218 							  "in  vec4 tes_gs[];\n"
9219 							  "out vec4 gs_fs;\n"
9220 							  "\n"
9221 							  "void main()\n"
9222 							  "{\n"
9223 							  "    gs_fs = tes_gs[0];\n"
9224 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9225 							  "    EmitVertex();\n"
9226 							  "    gs_fs = tes_gs[0];\n"
9227 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9228 							  "    EmitVertex();\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 							  "}\n"
9236 							  "\n";
9237 	static const GLchar* gs_tested = "#version 430 core\n"
9238 									 "#extension GL_ARB_enhanced_layouts : require\n"
9239 									 "\n"
9240 									 "layout(points)                           in;\n"
9241 									 "layout(triangle_strip, max_vertices = 4) out;\n"
9242 									 "\n"
9243 									 "layout (std140) uniform Block {\n"
9244 									 "    layout (offset = OFFSET) TYPE member;\n"
9245 									 "} block;\n"
9246 									 "\n"
9247 									 "in  vec4 tes_gs[];\n"
9248 									 "out vec4 gs_fs;\n"
9249 									 "\n"
9250 									 "void main()\n"
9251 									 "{\n"
9252 									 "    if (TYPE(1) == block.member)\n"
9253 									 "    {\n"
9254 									 "        gs_fs = vec4(1, 1, 1, 1);\n"
9255 									 "    }\n"
9256 									 "\n"
9257 									 "    gs_fs += tes_gs[0];\n"
9258 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9259 									 "    EmitVertex();\n"
9260 									 "    gs_fs += tes_gs[0];\n"
9261 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9262 									 "    EmitVertex();\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 									 "}\n"
9270 									 "\n";
9271 	static const GLchar* tcs = "#version 430 core\n"
9272 							   "#extension GL_ARB_enhanced_layouts : require\n"
9273 							   "\n"
9274 							   "layout(vertices = 1) out;\n"
9275 							   "\n"
9276 							   "in  vec4 vs_tcs[];\n"
9277 							   "out vec4 tcs_tes[];\n"
9278 							   "\n"
9279 							   "void main()\n"
9280 							   "{\n"
9281 							   "\n"
9282 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9283 							   "\n"
9284 							   "    gl_TessLevelOuter[0] = 1.0;\n"
9285 							   "    gl_TessLevelOuter[1] = 1.0;\n"
9286 							   "    gl_TessLevelOuter[2] = 1.0;\n"
9287 							   "    gl_TessLevelOuter[3] = 1.0;\n"
9288 							   "    gl_TessLevelInner[0] = 1.0;\n"
9289 							   "    gl_TessLevelInner[1] = 1.0;\n"
9290 							   "}\n"
9291 							   "\n";
9292 	static const GLchar* tcs_tested = "#version 430 core\n"
9293 									  "#extension GL_ARB_enhanced_layouts : require\n"
9294 									  "\n"
9295 									  "layout(vertices = 1) out;\n"
9296 									  "\n"
9297 									  "layout (std140) uniform Block {\n"
9298 									  "    layout (offset = OFFSET) TYPE member;\n"
9299 									  "} block;\n"
9300 									  "\n"
9301 									  "in  vec4 vs_tcs[];\n"
9302 									  "out vec4 tcs_tes[];\n"
9303 									  "\n"
9304 									  "void main()\n"
9305 									  "{\n"
9306 									  "    if (TYPE(1) == block.member)\n"
9307 									  "    {\n"
9308 									  "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9309 									  "    }\n"
9310 									  "\n"
9311 									  "\n"
9312 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9313 									  "\n"
9314 									  "    gl_TessLevelOuter[0] = 1.0;\n"
9315 									  "    gl_TessLevelOuter[1] = 1.0;\n"
9316 									  "    gl_TessLevelOuter[2] = 1.0;\n"
9317 									  "    gl_TessLevelOuter[3] = 1.0;\n"
9318 									  "    gl_TessLevelInner[0] = 1.0;\n"
9319 									  "    gl_TessLevelInner[1] = 1.0;\n"
9320 									  "}\n"
9321 									  "\n";
9322 	static const GLchar* tes = "#version 430 core\n"
9323 							   "#extension GL_ARB_enhanced_layouts : require\n"
9324 							   "\n"
9325 							   "layout(isolines, point_mode) in;\n"
9326 							   "\n"
9327 							   "in  vec4 tcs_tes[];\n"
9328 							   "out vec4 tes_gs;\n"
9329 							   "\n"
9330 							   "void main()\n"
9331 							   "{\n"
9332 							   "    tes_gs = tcs_tes[0];\n"
9333 							   "}\n"
9334 							   "\n";
9335 	static const GLchar* tes_tested = "#version 430 core\n"
9336 									  "#extension GL_ARB_enhanced_layouts : require\n"
9337 									  "\n"
9338 									  "layout(isolines, point_mode) in;\n"
9339 									  "\n"
9340 									  "layout (std140) uniform Block {\n"
9341 									  "    layout (offset = OFFSET) TYPE member;\n"
9342 									  "} block;\n"
9343 									  "\n"
9344 									  "in  vec4 tcs_tes[];\n"
9345 									  "out vec4 tes_gs;\n"
9346 									  "\n"
9347 									  "void main()\n"
9348 									  "{\n"
9349 									  "    if (TYPE(1) == block.member)\n"
9350 									  "    {\n"
9351 									  "        tes_gs = vec4(1, 1, 1, 1);\n"
9352 									  "    }\n"
9353 									  "\n"
9354 									  "    tes_gs += tcs_tes[0];\n"
9355 									  "}\n"
9356 									  "\n";
9357 	static const GLchar* vs = "#version 430 core\n"
9358 							  "#extension GL_ARB_enhanced_layouts : require\n"
9359 							  "\n"
9360 							  "in  vec4 in_vs;\n"
9361 							  "out vec4 vs_tcs;\n"
9362 							  "\n"
9363 							  "void main()\n"
9364 							  "{\n"
9365 							  "    vs_tcs = in_vs;\n"
9366 							  "}\n"
9367 							  "\n";
9368 	static const GLchar* vs_tested = "#version 430 core\n"
9369 									 "#extension GL_ARB_enhanced_layouts : require\n"
9370 									 "\n"
9371 									 "layout (std140) uniform Block {\n"
9372 									 "    layout (offset = OFFSET) TYPE member;\n"
9373 									 "} block;\n"
9374 									 "\n"
9375 									 "in  vec4 in_vs;\n"
9376 									 "out vec4 vs_tcs;\n"
9377 									 "\n"
9378 									 "void main()\n"
9379 									 "{\n"
9380 									 "    if (TYPE(1) == block.member)\n"
9381 									 "    {\n"
9382 									 "        vs_tcs = vec4(1, 1, 1, 1);\n"
9383 									 "    }\n"
9384 									 "\n"
9385 									 "    vs_tcs += in_vs;\n"
9386 									 "}\n"
9387 									 "\n";
9388 
9389 	std::string source;
9390 	testCase&   test_case = m_test_cases[test_case_index];
9391 
9392 	if (test_case.m_stage == stage)
9393 	{
9394 		GLchar			   buffer[16];
9395 		const GLuint	   offset	= test_case.m_offset;
9396 		size_t			   position  = 0;
9397 		const Utils::Type& type		 = test_case.m_type;
9398 		const GLchar*	  type_name = type.GetGLSLTypeName();
9399 
9400 		sprintf(buffer, "%d", offset);
9401 
9402 		switch (stage)
9403 		{
9404 		case Utils::Shader::COMPUTE:
9405 			source = cs;
9406 			break;
9407 		case Utils::Shader::FRAGMENT:
9408 			source = fs_tested;
9409 			break;
9410 		case Utils::Shader::GEOMETRY:
9411 			source = gs_tested;
9412 			break;
9413 		case Utils::Shader::TESS_CTRL:
9414 			source = tcs_tested;
9415 			break;
9416 		case Utils::Shader::TESS_EVAL:
9417 			source = tes_tested;
9418 			break;
9419 		case Utils::Shader::VERTEX:
9420 			source = vs_tested;
9421 			break;
9422 		default:
9423 			TCU_FAIL("Invalid enum");
9424 		}
9425 
9426 		Utils::replaceToken("OFFSET", position, buffer, source);
9427 		Utils::replaceToken("TYPE", position, type_name, source);
9428 		Utils::replaceToken("TYPE", position, type_name, source);
9429 	}
9430 	else
9431 	{
9432 		switch (stage)
9433 		{
9434 		case Utils::Shader::FRAGMENT:
9435 			source = fs;
9436 			break;
9437 		case Utils::Shader::GEOMETRY:
9438 			source = gs;
9439 			break;
9440 		case Utils::Shader::TESS_CTRL:
9441 			source = tcs;
9442 			break;
9443 		case Utils::Shader::TESS_EVAL:
9444 			source = tes;
9445 			break;
9446 		case Utils::Shader::VERTEX:
9447 			source = vs;
9448 			break;
9449 		default:
9450 			TCU_FAIL("Invalid enum");
9451 		}
9452 	}
9453 
9454 	return source;
9455 }
9456 
9457 /** Get description of test case
9458  *
9459  * @param test_case_index Index of test case
9460  *
9461  * @return Type name and offset
9462  **/
9463 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
9464 {
9465 	std::stringstream stream;
9466 	testCase&		  test_case = m_test_cases[test_case_index];
9467 
9468 	stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
9469 
9470 	return stream.str();
9471 }
9472 
9473 /** Get number of test cases
9474  *
9475  * @return Number of test cases
9476  **/
9477 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber()
9478 {
9479 	return static_cast<GLuint>(m_test_cases.size());
9480 }
9481 
9482 /** Get the maximum size for an uniform block
9483  *
9484  * @return The maximum size in basic machine units of a uniform block.
9485  **/
9486 GLint UniformBlockMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
9487 {
9488 	const Functions& gl		  = m_context.getRenderContext().getFunctions();
9489 	GLint			 max_size = 0;
9490 
9491 	gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
9492 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
9493 
9494 	return max_size;
9495 }
9496 
9497 /** Selects if "compute" stage is relevant for test
9498  *
9499  * @param test_case_index Index of test case
9500  *
9501  * @return true when tested stage is compute
9502  **/
9503 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index)
9504 {
9505 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9506 }
9507 
9508 /** Selects if compilation failure is expected result
9509  *
9510  * @param test_case_index Index of test case
9511  *
9512  * @return should_fail field from testCase
9513  **/
9514 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index)
9515 {
9516 	return m_test_cases[test_case_index].m_should_fail;
9517 }
9518 
9519 /** Checks if stage is supported
9520  *
9521  * @param stage ignored
9522  *
9523  * @return true
9524  **/
9525 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9526 {
9527 	return true;
9528 }
9529 
9530 /** Prepare all test cases
9531  *
9532  **/
9533 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit()
9534 {
9535 	const GLuint n_types = getTypesNumber();
9536 	bool		 stage_support[Utils::Shader::STAGE_MAX];
9537 
9538 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9539 	{
9540 		stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9541 	}
9542 
9543 	for (GLuint i = 0; i < n_types; ++i)
9544 	{
9545 		const Utils::Type& type		  = getType(i);
9546 		const GLuint	   alignment  = type.GetBaseAlignment(false);
9547 		const GLuint	   type_size  = type.GetSize(true);
9548 		const GLuint	   sec_to_end = getMaxBlockSize() - 2 * type_size;
9549 
9550 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9551 		{
9552 			if (false == stage_support[stage])
9553 			{
9554 				continue;
9555 			}
9556 
9557 			for (GLuint offset = 0; offset <= type_size; ++offset)
9558 			{
9559 				const GLuint modulo		 = offset % alignment;
9560 				const bool   is_aligned  = (0 == modulo) ? true : false;
9561 				const bool   should_fail = !is_aligned;
9562 
9563 				testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9564 
9565 				m_test_cases.push_back(test_case);
9566 			}
9567 
9568 			for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset)
9569 			{
9570 				const GLuint modulo		 = offset % alignment;
9571 				const bool   is_aligned  = (0 == modulo) ? true : false;
9572 				const bool   should_fail = !is_aligned;
9573 
9574 				testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9575 
9576 				m_test_cases.push_back(test_case);
9577 			}
9578 		}
9579 	}
9580 }
9581 
9582 /** Constructor
9583  *
9584  * @param context Test framework context
9585  **/
9586 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context)
9587 	: NegativeTestBase(context, "uniform_block_member_overlapping_offsets",
9588 					   "Test verifies that overlapping offsets qualifiers cause compilation failure")
9589 {
9590 	/* Nothing to be done here */
9591 }
9592 
9593 /** Constructor
9594  *
9595  * @param context Test framework context
9596  * @param name        Test name
9597  * @param description Test description
9598  **/
9599 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context&	 context,
9600 																				   const glw::GLchar* name,
9601 																				   const glw::GLchar* description)
9602 	: NegativeTestBase(context, name, description)
9603 {
9604 	/* Nothing to be done here */
9605 }
9606 
9607 /** Source for given test case and stage
9608  *
9609  * @param test_case_index Index of test case
9610  * @param stage           Shader stage
9611  *
9612  * @return Shader source
9613  **/
9614 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint				test_case_index,
9615 																	  Utils::Shader::STAGES stage)
9616 {
9617 	static const GLchar* cs = "#version 430 core\n"
9618 							  "#extension GL_ARB_enhanced_layouts : require\n"
9619 							  "\n"
9620 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9621 							  "\n"
9622 							  "layout (std140) uniform Block {\n"
9623 							  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9624 							  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9625 							  "} block;\n"
9626 							  "\n"
9627 							  "writeonly uniform image2D uni_image;\n"
9628 							  "\n"
9629 							  "void main()\n"
9630 							  "{\n"
9631 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
9632 							  "\n"
9633 							  "    if ((BOY_TYPE(1) == block.boy) ||\n"
9634 							  "        (MAN_TYPE(0) == block.man) )\n"
9635 							  "    {\n"
9636 							  "        result = vec4(1, 1, 1, 1);\n"
9637 							  "    }\n"
9638 							  "\n"
9639 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9640 							  "}\n"
9641 							  "\n";
9642 	static const GLchar* fs = "#version 430 core\n"
9643 							  "#extension GL_ARB_enhanced_layouts : require\n"
9644 							  "\n"
9645 							  "in  vec4 gs_fs;\n"
9646 							  "out vec4 fs_out;\n"
9647 							  "\n"
9648 							  "void main()\n"
9649 							  "{\n"
9650 							  "    fs_out = gs_fs;\n"
9651 							  "}\n"
9652 							  "\n";
9653 	static const GLchar* fs_tested = "#version 430 core\n"
9654 									 "#extension GL_ARB_enhanced_layouts : require\n"
9655 									 "\n"
9656 									 "layout (std140) uniform Block {\n"
9657 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9658 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9659 									 "} block;\n"
9660 									 "\n"
9661 									 "in  vec4 gs_fs;\n"
9662 									 "out vec4 fs_out;\n"
9663 									 "\n"
9664 									 "void main()\n"
9665 									 "{\n"
9666 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
9667 									 "        (MAN_TYPE(0) == block.man) )\n"
9668 									 "    {\n"
9669 									 "        fs_out = vec4(1, 1, 1, 1);\n"
9670 									 "    }\n"
9671 									 "\n"
9672 									 "    fs_out += gs_fs;\n"
9673 									 "}\n"
9674 									 "\n";
9675 	static const GLchar* gs = "#version 430 core\n"
9676 							  "#extension GL_ARB_enhanced_layouts : require\n"
9677 							  "\n"
9678 							  "layout(points)                           in;\n"
9679 							  "layout(triangle_strip, max_vertices = 4) out;\n"
9680 							  "\n"
9681 							  "in  vec4 tes_gs[];\n"
9682 							  "out vec4 gs_fs;\n"
9683 							  "\n"
9684 							  "void main()\n"
9685 							  "{\n"
9686 							  "    gs_fs = tes_gs[0];\n"
9687 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9688 							  "    EmitVertex();\n"
9689 							  "    gs_fs = tes_gs[0];\n"
9690 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9691 							  "    EmitVertex();\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 							  "}\n"
9699 							  "\n";
9700 	static const GLchar* gs_tested = "#version 430 core\n"
9701 									 "#extension GL_ARB_enhanced_layouts : require\n"
9702 									 "\n"
9703 									 "layout(points)                           in;\n"
9704 									 "layout(triangle_strip, max_vertices = 4) out;\n"
9705 									 "\n"
9706 									 "layout (std140) uniform Block {\n"
9707 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9708 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9709 									 "} block;\n"
9710 									 "\n"
9711 									 "in  vec4 tes_gs[];\n"
9712 									 "out vec4 gs_fs;\n"
9713 									 "\n"
9714 									 "void main()\n"
9715 									 "{\n"
9716 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
9717 									 "        (MAN_TYPE(0) == block.man) )\n"
9718 									 "    {\n"
9719 									 "        gs_fs = vec4(1, 1, 1, 1);\n"
9720 									 "    }\n"
9721 									 "\n"
9722 									 "    gs_fs += tes_gs[0];\n"
9723 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9724 									 "    EmitVertex();\n"
9725 									 "    gs_fs += tes_gs[0];\n"
9726 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9727 									 "    EmitVertex();\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 									 "}\n"
9735 									 "\n";
9736 	static const GLchar* tcs = "#version 430 core\n"
9737 							   "#extension GL_ARB_enhanced_layouts : require\n"
9738 							   "\n"
9739 							   "layout(vertices = 1) out;\n"
9740 							   "\n"
9741 							   "in  vec4 vs_tcs[];\n"
9742 							   "out vec4 tcs_tes[];\n"
9743 							   "\n"
9744 							   "void main()\n"
9745 							   "{\n"
9746 							   "\n"
9747 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9748 							   "\n"
9749 							   "    gl_TessLevelOuter[0] = 1.0;\n"
9750 							   "    gl_TessLevelOuter[1] = 1.0;\n"
9751 							   "    gl_TessLevelOuter[2] = 1.0;\n"
9752 							   "    gl_TessLevelOuter[3] = 1.0;\n"
9753 							   "    gl_TessLevelInner[0] = 1.0;\n"
9754 							   "    gl_TessLevelInner[1] = 1.0;\n"
9755 							   "}\n"
9756 							   "\n";
9757 	static const GLchar* tcs_tested = "#version 430 core\n"
9758 									  "#extension GL_ARB_enhanced_layouts : require\n"
9759 									  "\n"
9760 									  "layout(vertices = 1) out;\n"
9761 									  "\n"
9762 									  "layout (std140) uniform Block {\n"
9763 									  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9764 									  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9765 									  "} block;\n"
9766 									  "\n"
9767 									  "in  vec4 vs_tcs[];\n"
9768 									  "out vec4 tcs_tes[];\n"
9769 									  "\n"
9770 									  "void main()\n"
9771 									  "{\n"
9772 									  "    if ((BOY_TYPE(1) == block.boy) ||\n"
9773 									  "        (MAN_TYPE(0) == block.man) )\n"
9774 									  "    {\n"
9775 									  "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9776 									  "    }\n"
9777 									  "\n"
9778 									  "\n"
9779 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9780 									  "\n"
9781 									  "    gl_TessLevelOuter[0] = 1.0;\n"
9782 									  "    gl_TessLevelOuter[1] = 1.0;\n"
9783 									  "    gl_TessLevelOuter[2] = 1.0;\n"
9784 									  "    gl_TessLevelOuter[3] = 1.0;\n"
9785 									  "    gl_TessLevelInner[0] = 1.0;\n"
9786 									  "    gl_TessLevelInner[1] = 1.0;\n"
9787 									  "}\n"
9788 									  "\n";
9789 	static const GLchar* tes = "#version 430 core\n"
9790 							   "#extension GL_ARB_enhanced_layouts : require\n"
9791 							   "\n"
9792 							   "layout(isolines, point_mode) in;\n"
9793 							   "\n"
9794 							   "in  vec4 tcs_tes[];\n"
9795 							   "out vec4 tes_gs;\n"
9796 							   "\n"
9797 							   "void main()\n"
9798 							   "{\n"
9799 							   "    tes_gs = tcs_tes[0];\n"
9800 							   "}\n"
9801 							   "\n";
9802 	static const GLchar* tes_tested = "#version 430 core\n"
9803 									  "#extension GL_ARB_enhanced_layouts : require\n"
9804 									  "\n"
9805 									  "layout(isolines, point_mode) in;\n"
9806 									  "\n"
9807 									  "layout (std140) uniform Block {\n"
9808 									  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9809 									  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9810 									  "} block;\n"
9811 									  "\n"
9812 									  "in  vec4 tcs_tes[];\n"
9813 									  "out vec4 tes_gs;\n"
9814 									  "\n"
9815 									  "void main()\n"
9816 									  "{\n"
9817 									  "    if ((BOY_TYPE(1) == block.boy) ||\n"
9818 									  "        (MAN_TYPE(0) == block.man) )\n"
9819 									  "    {\n"
9820 									  "        tes_gs = vec4(1, 1, 1, 1);\n"
9821 									  "    }\n"
9822 									  "\n"
9823 									  "    tes_gs += tcs_tes[0];\n"
9824 									  "}\n"
9825 									  "\n";
9826 	static const GLchar* vs = "#version 430 core\n"
9827 							  "#extension GL_ARB_enhanced_layouts : require\n"
9828 							  "\n"
9829 							  "in  vec4 in_vs;\n"
9830 							  "out vec4 vs_tcs;\n"
9831 							  "\n"
9832 							  "void main()\n"
9833 							  "{\n"
9834 							  "    vs_tcs = in_vs;\n"
9835 							  "}\n"
9836 							  "\n";
9837 	static const GLchar* vs_tested = "#version 430 core\n"
9838 									 "#extension GL_ARB_enhanced_layouts : require\n"
9839 									 "\n"
9840 									 "layout (std140) uniform Block {\n"
9841 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9842 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9843 									 "} block;\n"
9844 									 "\n"
9845 									 "in  vec4 in_vs;\n"
9846 									 "out vec4 vs_tcs;\n"
9847 									 "\n"
9848 									 "void main()\n"
9849 									 "{\n"
9850 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
9851 									 "        (MAN_TYPE(0) == block.man) )\n"
9852 									 "    {\n"
9853 									 "        vs_tcs = vec4(1, 1, 1, 1);\n"
9854 									 "    }\n"
9855 									 "\n"
9856 									 "    vs_tcs += in_vs;\n"
9857 									 "}\n"
9858 									 "\n";
9859 
9860 	std::string source;
9861 	testCase&   test_case = m_test_cases[test_case_index];
9862 
9863 	if (test_case.m_stage == stage)
9864 	{
9865 		GLchar			   buffer[16];
9866 		const GLuint	   boy_offset	= test_case.m_boy_offset;
9867 		const Utils::Type& boy_type		 = test_case.m_boy_type;
9868 		const GLchar*	  boy_type_name = boy_type.GetGLSLTypeName();
9869 		const GLuint	   man_offset	= test_case.m_man_offset;
9870 		const Utils::Type& man_type		 = test_case.m_man_type;
9871 		const GLchar*	  man_type_name = man_type.GetGLSLTypeName();
9872 		size_t			   position		 = 0;
9873 
9874 		switch (stage)
9875 		{
9876 		case Utils::Shader::COMPUTE:
9877 			source = cs;
9878 			break;
9879 		case Utils::Shader::FRAGMENT:
9880 			source = fs_tested;
9881 			break;
9882 		case Utils::Shader::GEOMETRY:
9883 			source = gs_tested;
9884 			break;
9885 		case Utils::Shader::TESS_CTRL:
9886 			source = tcs_tested;
9887 			break;
9888 		case Utils::Shader::TESS_EVAL:
9889 			source = tes_tested;
9890 			break;
9891 		case Utils::Shader::VERTEX:
9892 			source = vs_tested;
9893 			break;
9894 		default:
9895 			TCU_FAIL("Invalid enum");
9896 		}
9897 
9898 		sprintf(buffer, "%d", boy_offset);
9899 		Utils::replaceToken("BOY_OFFSET", position, buffer, source);
9900 		Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9901 		sprintf(buffer, "%d", man_offset);
9902 		Utils::replaceToken("MAN_OFFSET", position, buffer, source);
9903 		Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9904 		Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9905 		Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9906 	}
9907 	else
9908 	{
9909 		switch (stage)
9910 		{
9911 		case Utils::Shader::FRAGMENT:
9912 			source = fs;
9913 			break;
9914 		case Utils::Shader::GEOMETRY:
9915 			source = gs;
9916 			break;
9917 		case Utils::Shader::TESS_CTRL:
9918 			source = tcs;
9919 			break;
9920 		case Utils::Shader::TESS_EVAL:
9921 			source = tes;
9922 			break;
9923 		case Utils::Shader::VERTEX:
9924 			source = vs;
9925 			break;
9926 		default:
9927 			TCU_FAIL("Invalid enum");
9928 		}
9929 	}
9930 
9931 	return source;
9932 }
9933 
9934 /** Get description of test case
9935  *
9936  * @param test_case_index Index of test case
9937  *
9938  * @return Type name and offset
9939  **/
9940 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index)
9941 {
9942 	std::stringstream stream;
9943 	testCase&		  test_case = m_test_cases[test_case_index];
9944 
9945 	stream << "Type: " << test_case.m_boy_type.GetGLSLTypeName() << ", offset: " << test_case.m_boy_offset
9946 		   << ". Type: " << test_case.m_man_type.GetGLSLTypeName() << ", offset: " << test_case.m_man_offset;
9947 
9948 	return stream.str();
9949 }
9950 
9951 /** Get number of test cases
9952  *
9953  * @return Number of test cases
9954  **/
9955 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber()
9956 {
9957 	return static_cast<GLuint>(m_test_cases.size());
9958 }
9959 
9960 /** Selects if "compute" stage is relevant for test
9961  *
9962  * @param test_case_index Index of test case
9963  *
9964  * @return true when tested stage is compute
9965  **/
9966 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index)
9967 {
9968 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9969 }
9970 
9971 /** Checks if stage is supported
9972  *
9973  * @param stage ignored
9974  *
9975  * @return true
9976  **/
9977 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9978 {
9979 	return true;
9980 }
9981 
9982 /** Prepare all test cases
9983  *
9984  **/
9985 void UniformBlockMemberOverlappingOffsetsTest::testInit()
9986 {
9987 	const GLuint n_types = getTypesNumber();
9988 	bool		 stage_support[Utils::Shader::STAGE_MAX];
9989 
9990 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9991 	{
9992 		stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9993 	}
9994 
9995 	for (GLuint i = 0; i < n_types; ++i)
9996 	{
9997 		const Utils::Type& boy_type = getType(i);
9998 		const GLuint	   boy_size = boy_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9999 
10000 		for (GLuint j = 0; j < n_types; ++j)
10001 		{
10002 			const Utils::Type& man_type  = getType(j);
10003 			const GLuint	   man_align = man_type.GetBaseAlignment(false);
10004 			const GLuint	   man_size  = man_type.GetActualAlignment(1 /* align */, false /* is_array*/);
10005 
10006 			const GLuint boy_offset		  = lcm(boy_size, man_size);
10007 			const GLuint man_after_start  = boy_offset + 1;
10008 			const GLuint man_after_off	= man_type.GetActualOffset(man_after_start, man_size);
10009 			const GLuint man_before_start = boy_offset - man_align;
10010 			const GLuint man_before_off   = man_type.GetActualOffset(man_before_start, man_size);
10011 
10012 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10013 			{
10014 				if (false == stage_support[stage])
10015 				{
10016 					continue;
10017 				}
10018 
10019 				if ((boy_offset > man_before_off) && (boy_offset < man_before_off + man_size))
10020 				{
10021 					testCase test_case = { boy_offset, boy_type, man_before_off, man_type,
10022 										   (Utils::Shader::STAGES)stage };
10023 
10024 					m_test_cases.push_back(test_case);
10025 				}
10026 
10027 				if ((boy_offset < man_after_off) && (boy_offset + boy_size > man_after_off))
10028 				{
10029 					testCase test_case = { boy_offset, boy_type, man_after_off, man_type,
10030 										   (Utils::Shader::STAGES)stage };
10031 
10032 					m_test_cases.push_back(test_case);
10033 				}
10034 
10035 				/* Boy offset, should be fine for both types */
10036 				testCase test_case = { boy_offset, boy_type, boy_offset, man_type, (Utils::Shader::STAGES)stage };
10037 
10038 				m_test_cases.push_back(test_case);
10039 			}
10040 		}
10041 	}
10042 }
10043 
10044 /** Find greatest common divisor for a and b
10045  *
10046  * @param a A argument
10047  * @param b B argument
10048  *
10049  * @return Found gcd value
10050  **/
10051 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b)
10052 {
10053 	if ((0 != a) && (0 == b))
10054 	{
10055 		return a;
10056 	}
10057 	else
10058 	{
10059 		GLuint greater = std::max(a, b);
10060 		GLuint lesser  = std::min(a, b);
10061 
10062 		return gcd(lesser, greater % lesser);
10063 	}
10064 }
10065 
10066 /** Find lowest common multiple for a and b
10067  *
10068  * @param a A argument
10069  * @param b B argument
10070  *
10071  * @return Found gcd value
10072  **/
10073 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b)
10074 {
10075 	return (a * b) / gcd(a, b);
10076 }
10077 
10078 /** Constructor
10079  *
10080  * @param context Test framework context
10081  **/
10082 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context)
10083 	: NegativeTestBase(context, "uniform_block_member_align_non_power_of_2",
10084 					   "Test verifies that align qualifier requires value that is a power of 2")
10085 {
10086 	/* Nothing to be done here */
10087 }
10088 
10089 /** Constructor
10090  *
10091  * @param context Test framework context
10092  * @param name        Test name
10093  * @param description Test description
10094  **/
10095 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context&	 context,
10096 																			   const glw::GLchar* name,
10097 																			   const glw::GLchar* description)
10098 	: NegativeTestBase(context, name, description)
10099 {
10100 	/* Nothing to be done here */
10101 }
10102 
10103 /** Source for given test case and stage
10104  *
10105  * @param test_case_index Index of test case
10106  * @param stage           Shader stage
10107  *
10108  * @return Shader source
10109  **/
10110 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10111 {
10112 	static const GLchar* cs = "#version 430 core\n"
10113 							  "#extension GL_ARB_enhanced_layouts : require\n"
10114 							  "\n"
10115 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10116 							  "\n"
10117 							  "layout (std140) uniform Block {\n"
10118 							  "    vec4 boy;\n"
10119 							  "    layout (align = ALIGN) TYPE man;\n"
10120 							  "} block;\n"
10121 							  "\n"
10122 							  "writeonly uniform image2D uni_image;\n"
10123 							  "\n"
10124 							  "void main()\n"
10125 							  "{\n"
10126 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
10127 							  "\n"
10128 							  "    if (TYPE(0) == block.man)\n"
10129 							  "    {\n"
10130 							  "        result = vec4(1, 1, 1, 1) - block.boy;\n"
10131 							  "    }\n"
10132 							  "\n"
10133 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10134 							  "}\n"
10135 							  "\n";
10136 	static const GLchar* fs = "#version 430 core\n"
10137 							  "#extension GL_ARB_enhanced_layouts : require\n"
10138 							  "\n"
10139 							  "in  vec4 gs_fs;\n"
10140 							  "out vec4 fs_out;\n"
10141 							  "\n"
10142 							  "void main()\n"
10143 							  "{\n"
10144 							  "    fs_out = gs_fs;\n"
10145 							  "}\n"
10146 							  "\n";
10147 	static const GLchar* fs_tested = "#version 430 core\n"
10148 									 "#extension GL_ARB_enhanced_layouts : require\n"
10149 									 "\n"
10150 									 "layout (std140) uniform Block {\n"
10151 									 "    vec4 boy;\n"
10152 									 "    layout (align = ALIGN) TYPE man;\n"
10153 									 "} block;\n"
10154 									 "\n"
10155 									 "in  vec4 gs_fs;\n"
10156 									 "out vec4 fs_out;\n"
10157 									 "\n"
10158 									 "void main()\n"
10159 									 "{\n"
10160 									 "    if (TYPE(0) == block.man)\n"
10161 									 "    {\n"
10162 									 "        fs_out = block.boy;\n"
10163 									 "    }\n"
10164 									 "\n"
10165 									 "    fs_out += gs_fs;\n"
10166 									 "}\n"
10167 									 "\n";
10168 	static const GLchar* gs = "#version 430 core\n"
10169 							  "#extension GL_ARB_enhanced_layouts : require\n"
10170 							  "\n"
10171 							  "layout(points)                           in;\n"
10172 							  "layout(triangle_strip, max_vertices = 4) out;\n"
10173 							  "\n"
10174 							  "in  vec4 tes_gs[];\n"
10175 							  "out vec4 gs_fs;\n"
10176 							  "\n"
10177 							  "void main()\n"
10178 							  "{\n"
10179 							  "    gs_fs = tes_gs[0];\n"
10180 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
10181 							  "    EmitVertex();\n"
10182 							  "    gs_fs = tes_gs[0];\n"
10183 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
10184 							  "    EmitVertex();\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 							  "}\n"
10192 							  "\n";
10193 	static const GLchar* gs_tested = "#version 430 core\n"
10194 									 "#extension GL_ARB_enhanced_layouts : require\n"
10195 									 "\n"
10196 									 "layout(points)                           in;\n"
10197 									 "layout(triangle_strip, max_vertices = 4) out;\n"
10198 									 "\n"
10199 									 "layout (std140) uniform Block {\n"
10200 									 "    vec4 boy;\n"
10201 									 "    layout (align = ALIGN) TYPE man;\n"
10202 									 "} block;\n"
10203 									 "\n"
10204 									 "in  vec4 tes_gs[];\n"
10205 									 "out vec4 gs_fs;\n"
10206 									 "\n"
10207 									 "void main()\n"
10208 									 "{\n"
10209 									 "    if (TYPE(0) == block.man)\n"
10210 									 "    {\n"
10211 									 "        gs_fs = block.boy;\n"
10212 									 "    }\n"
10213 									 "\n"
10214 									 "    gs_fs += tes_gs[0];\n"
10215 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
10216 									 "    EmitVertex();\n"
10217 									 "    gs_fs += tes_gs[0];\n"
10218 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
10219 									 "    EmitVertex();\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 									 "}\n"
10227 									 "\n";
10228 	static const GLchar* tcs = "#version 430 core\n"
10229 							   "#extension GL_ARB_enhanced_layouts : require\n"
10230 							   "\n"
10231 							   "layout(vertices = 1) out;\n"
10232 							   "\n"
10233 							   "in  vec4 vs_tcs[];\n"
10234 							   "out vec4 tcs_tes[];\n"
10235 							   "\n"
10236 							   "void main()\n"
10237 							   "{\n"
10238 							   "\n"
10239 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
10240 							   "\n"
10241 							   "    gl_TessLevelOuter[0] = 1.0;\n"
10242 							   "    gl_TessLevelOuter[1] = 1.0;\n"
10243 							   "    gl_TessLevelOuter[2] = 1.0;\n"
10244 							   "    gl_TessLevelOuter[3] = 1.0;\n"
10245 							   "    gl_TessLevelInner[0] = 1.0;\n"
10246 							   "    gl_TessLevelInner[1] = 1.0;\n"
10247 							   "}\n"
10248 							   "\n";
10249 	static const GLchar* tcs_tested = "#version 430 core\n"
10250 									  "#extension GL_ARB_enhanced_layouts : require\n"
10251 									  "\n"
10252 									  "layout(vertices = 1) out;\n"
10253 									  "\n"
10254 									  "layout (std140) uniform Block {\n"
10255 									  "    vec4 boy;\n"
10256 									  "    layout (align = ALIGN) TYPE man;\n"
10257 									  "} block;\n"
10258 									  "\n"
10259 									  "in  vec4 vs_tcs[];\n"
10260 									  "out vec4 tcs_tes[];\n"
10261 									  "\n"
10262 									  "void main()\n"
10263 									  "{\n"
10264 									  "    if (TYPE(0) == block.man)\n"
10265 									  "    {\n"
10266 									  "        tcs_tes[gl_InvocationID] = block.boy;\n"
10267 									  "    }\n"
10268 									  "\n"
10269 									  "\n"
10270 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
10271 									  "\n"
10272 									  "    gl_TessLevelOuter[0] = 1.0;\n"
10273 									  "    gl_TessLevelOuter[1] = 1.0;\n"
10274 									  "    gl_TessLevelOuter[2] = 1.0;\n"
10275 									  "    gl_TessLevelOuter[3] = 1.0;\n"
10276 									  "    gl_TessLevelInner[0] = 1.0;\n"
10277 									  "    gl_TessLevelInner[1] = 1.0;\n"
10278 									  "}\n"
10279 									  "\n";
10280 	static const GLchar* tes = "#version 430 core\n"
10281 							   "#extension GL_ARB_enhanced_layouts : require\n"
10282 							   "\n"
10283 							   "layout(isolines, point_mode) in;\n"
10284 							   "\n"
10285 							   "in  vec4 tcs_tes[];\n"
10286 							   "out vec4 tes_gs;\n"
10287 							   "\n"
10288 							   "void main()\n"
10289 							   "{\n"
10290 							   "    tes_gs = tcs_tes[0];\n"
10291 							   "}\n"
10292 							   "\n";
10293 	static const GLchar* tes_tested = "#version 430 core\n"
10294 									  "#extension GL_ARB_enhanced_layouts : require\n"
10295 									  "\n"
10296 									  "layout(isolines, point_mode) in;\n"
10297 									  "\n"
10298 									  "layout (std140) uniform Block {\n"
10299 									  "    vec4 boy;\n"
10300 									  "    layout (align = ALIGN) TYPE man;\n"
10301 									  "} block;\n"
10302 									  "\n"
10303 									  "in  vec4 tcs_tes[];\n"
10304 									  "out vec4 tes_gs;\n"
10305 									  "\n"
10306 									  "void main()\n"
10307 									  "{\n"
10308 									  "    if (TYPE(0) == block.man)\n"
10309 									  "    {\n"
10310 									  "        tes_gs = block.boy;\n"
10311 									  "    }\n"
10312 									  "\n"
10313 									  "    tes_gs += tcs_tes[0];\n"
10314 									  "}\n"
10315 									  "\n";
10316 	static const GLchar* vs = "#version 430 core\n"
10317 							  "#extension GL_ARB_enhanced_layouts : require\n"
10318 							  "\n"
10319 							  "in  vec4 in_vs;\n"
10320 							  "out vec4 vs_tcs;\n"
10321 							  "\n"
10322 							  "void main()\n"
10323 							  "{\n"
10324 							  "    vs_tcs = in_vs;\n"
10325 							  "}\n"
10326 							  "\n";
10327 	static const GLchar* vs_tested = "#version 430 core\n"
10328 									 "#extension GL_ARB_enhanced_layouts : require\n"
10329 									 "\n"
10330 									 "layout (std140) uniform Block {\n"
10331 									 "    vec4 boy;\n"
10332 									 "    layout (align = ALIGN) TYPE man;\n"
10333 									 "} block;\n"
10334 									 "\n"
10335 									 "in  vec4 in_vs;\n"
10336 									 "out vec4 vs_tcs;\n"
10337 									 "\n"
10338 									 "void main()\n"
10339 									 "{\n"
10340 									 "    if (TYPE(0) == block.man)\n"
10341 									 "    {\n"
10342 									 "        vs_tcs = block.boy;\n"
10343 									 "    }\n"
10344 									 "\n"
10345 									 "    vs_tcs += in_vs;\n"
10346 									 "}\n"
10347 									 "\n";
10348 
10349 	std::string source;
10350 	testCase&   test_case = m_test_cases[test_case_index];
10351 
10352 	if (test_case.m_stage == stage)
10353 	{
10354 		GLchar			   buffer[16];
10355 		const GLuint	   alignment = test_case.m_alignment;
10356 		const Utils::Type& type		 = test_case.m_type;
10357 		const GLchar*	  type_name = type.GetGLSLTypeName();
10358 		size_t			   position  = 0;
10359 
10360 		switch (stage)
10361 		{
10362 		case Utils::Shader::COMPUTE:
10363 			source = cs;
10364 			break;
10365 		case Utils::Shader::FRAGMENT:
10366 			source = fs_tested;
10367 			break;
10368 		case Utils::Shader::GEOMETRY:
10369 			source = gs_tested;
10370 			break;
10371 		case Utils::Shader::TESS_CTRL:
10372 			source = tcs_tested;
10373 			break;
10374 		case Utils::Shader::TESS_EVAL:
10375 			source = tes_tested;
10376 			break;
10377 		case Utils::Shader::VERTEX:
10378 			source = vs_tested;
10379 			break;
10380 		default:
10381 			TCU_FAIL("Invalid enum");
10382 		}
10383 
10384 		sprintf(buffer, "%d", alignment);
10385 		Utils::replaceToken("ALIGN", position, buffer, source);
10386 		Utils::replaceToken("TYPE", position, type_name, source);
10387 		Utils::replaceToken("TYPE", position, type_name, source);
10388 	}
10389 	else
10390 	{
10391 		switch (stage)
10392 		{
10393 		case Utils::Shader::FRAGMENT:
10394 			source = fs;
10395 			break;
10396 		case Utils::Shader::GEOMETRY:
10397 			source = gs;
10398 			break;
10399 		case Utils::Shader::TESS_CTRL:
10400 			source = tcs;
10401 			break;
10402 		case Utils::Shader::TESS_EVAL:
10403 			source = tes;
10404 			break;
10405 		case Utils::Shader::VERTEX:
10406 			source = vs;
10407 			break;
10408 		default:
10409 			TCU_FAIL("Invalid enum");
10410 		}
10411 	}
10412 
10413 	return source;
10414 }
10415 
10416 /** Get description of test case
10417  *
10418  * @param test_case_index Index of test case
10419  *
10420  * @return Type name and offset
10421  **/
10422 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index)
10423 {
10424 	std::stringstream stream;
10425 	testCase&		  test_case = m_test_cases[test_case_index];
10426 
10427 	stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment;
10428 
10429 	return stream.str();
10430 }
10431 
10432 /** Get number of test cases
10433  *
10434  * @return Number of test cases
10435  **/
10436 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber()
10437 {
10438 	return static_cast<GLuint>(m_test_cases.size());
10439 }
10440 
10441 /** Selects if "compute" stage is relevant for test
10442  *
10443  * @param test_case_index Index of test case
10444  *
10445  * @return true when tested stage is compute
10446  **/
10447 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index)
10448 {
10449 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10450 }
10451 
10452 /** Checks if stage is supported
10453  *
10454  * @param ignored
10455  *
10456  * @return true
10457  **/
10458 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */)
10459 {
10460 	return true;
10461 }
10462 
10463 /** Selects if compilation failure is expected result
10464  *
10465  * @param test_case_index Index of test case
10466  *
10467  * @return should_fail field from testCase
10468  **/
10469 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index)
10470 {
10471 	return m_test_cases[test_case_index].m_should_fail;
10472 }
10473 
10474 /** Prepare all test cases
10475  *
10476  **/
10477 void UniformBlockMemberAlignNonPowerOf2Test::testInit()
10478 {
10479 	static const GLuint dmat4_size = 128;
10480 	const GLuint		n_types	= getTypesNumber();
10481 	bool				stage_support[Utils::Shader::STAGE_MAX];
10482 
10483 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10484 	{
10485 		stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10486 	}
10487 
10488 	for (GLuint j = 0; j < n_types; ++j)
10489 	{
10490 		const Utils::Type& type = getType(j);
10491 
10492 		for (GLuint align = 0; align <= dmat4_size; ++align)
10493 		{
10494 
10495 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST
10496 
10497 			const bool should_fail = (0 == align) ? false : !isPowerOf2(align);
10498 
10499 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10500 
10501 			const bool should_fail = !isPowerOf2(align);
10502 
10503 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10504 
10505 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10506 			{
10507 				if (false == stage_support[stage])
10508 				{
10509 					continue;
10510 				}
10511 
10512 				testCase test_case = { align, type, should_fail, (Utils::Shader::STAGES)stage };
10513 
10514 				m_test_cases.push_back(test_case);
10515 			}
10516 		}
10517 	}
10518 }
10519 
10520 /** Check if value is power of 2
10521  *
10522  * @param val Tested value
10523  *
10524  * @return true if val is power of 2, false otherwise
10525  **/
10526 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val)
10527 {
10528 	if (0 == val)
10529 	{
10530 		return false;
10531 	}
10532 
10533 	return (0 == (val & (val - 1)));
10534 }
10535 
10536 /** Constructor
10537  *
10538  * @param context Test framework context
10539  **/
10540 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context& context)
10541 	: TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer")
10542 {
10543 }
10544 
10545 /** Get interface of program
10546  *
10547  * @param ignored
10548  * @param program_interface Interface of program
10549  * @param varying_passthrough Collection of connections between in and out variables
10550  **/
10551 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */,
10552 													Utils::ProgramInterface&   program_interface,
10553 													Utils::VaryingPassthrough& varying_passthrough)
10554 {
10555 	static const Utils::Type vec4 = Utils::Type::vec4;
10556 
10557 #if WRKARD_UNIFORMBLOCKALIGNMENT
10558 
10559 	static const GLuint block_align = 16;
10560 
10561 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10562 
10563 	static const GLuint block_align = 64;
10564 
10565 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10566 
10567 	static const GLuint vec4_stride = 16;
10568 	static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
10569 
10570 	/*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual
10571 	 alignment of a member will be the greater of the specified alignment and the base aligment for the member type
10572 	 */
10573 	const GLuint first_offset  = 0;																		/* vec4 at 0 */
10574 	const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
10575 	const GLuint third_offset =
10576 		Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
10577 	const GLuint fourth_offset =
10578 		Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
10579 	const GLuint fifth_offset =
10580 		Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */
10581 	const GLuint sixth_offset =
10582 		Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
10583 
10584 	Utils::Interface* structure = program_interface.Structure("Data");
10585 
10586 	structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10587 					  false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
10588 
10589 	structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
10590 					  false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
10591 					  Utils::Type::vec4.GetSize() /* offset */);
10592 
10593 	/* Prepare Block */
10594 	Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
10595 
10596 	vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10597 						 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
10598 
10599 	vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10600 						 0 /* n_array_elements */, data_stride, second_offset);
10601 
10602 	vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10603 						 2 /* n_array_elements */, data_stride, third_offset);
10604 
10605 	vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
10606 						 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
10607 
10608 	vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4,
10609 						 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
10610 
10611 	vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10612 						 0 /* n_array_elements */, data_stride, sixth_offset);
10613 
10614 	const GLuint stride = calculateStride(*vs_uni_block);
10615 	m_data.resize(stride);
10616 	generateData(*vs_uni_block, 0, m_data);
10617 
10618 	Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10619 
10620 /* Add uniform BLOCK */
10621 #if WRKARD_UNIFORMBLOCKALIGNMENT
10622 	vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
10623 				  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10624 #else  /* WRKARD_UNIFORMBLOCKALIGNMENT */
10625 	vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0,
10626 				  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10627 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10628 
10629 	program_interface.CloneVertexInterface(varying_passthrough);
10630 }
10631 
10632 /** Constructor
10633  *
10634  * @param context Test framework context
10635  **/
10636 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context& context)
10637 	: TextureTestBase(context, "ssb_member_offset_and_align",
10638 					  "Test verifies offsets and alignment of storage buffer members")
10639 {
10640 }
10641 
10642 /** Get interface of program
10643  *
10644  * @param test_case_index     Test case index
10645  * @param program_interface   Interface of program
10646  * @param varying_passthrough Collection of connections between in and out variables
10647  **/
10648 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint					 test_case_index,
10649 													  Utils::ProgramInterface&   program_interface,
10650 													  Utils::VaryingPassthrough& varying_passthrough)
10651 {
10652 	std::string globals = "const int basic_size = BASIC_SIZE;\n"
10653 						  "const int type_align = TYPE_ALIGN;\n"
10654 						  "const int type_size  = TYPE_SIZE;\n";
10655 
10656 	Utils::Type  type		 = getType(test_case_index);
10657 	GLuint		 basic_size  = Utils::Type::GetTypeSize(type.m_basic_type);
10658 	const GLuint base_align  = type.GetBaseAlignment(false);
10659 	const GLuint array_align = type.GetBaseAlignment(true);
10660 	const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
10661 	const GLuint type_align  = Utils::roundUpToPowerOf2(base_stride);
10662 
10663 	/* Calculate offsets */
10664 	const GLuint first_offset  = 0;
10665 	const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
10666 
10667 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
10668 
10669 	const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, base_align);
10670 	const GLuint fourth_offset  = type.GetActualOffset(third_offset + base_stride, base_align);
10671 	const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
10672 	const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
10673 	const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10674 	const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, array_align);
10675 
10676 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10677 
10678 	const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
10679 	const GLuint fourth_offset  = type.GetActualOffset(3 * type_align + base_stride, base_align);
10680 	const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
10681 	const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
10682 	const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10683 	const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
10684 
10685 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10686 
10687 	/* Prepare data */
10688 	const std::vector<GLubyte>& first  = type.GenerateData();
10689 	const std::vector<GLubyte>& second = type.GenerateData();
10690 	const std::vector<GLubyte>& third  = type.GenerateData();
10691 	const std::vector<GLubyte>& fourth = type.GenerateData();
10692 
10693 	m_data.resize(eigth_offset + base_stride);
10694 	GLubyte* ptr = &m_data[0];
10695 	memcpy(ptr + first_offset, &first[0], first.size());
10696 	memcpy(ptr + second_offset, &second[0], second.size());
10697 	memcpy(ptr + third_offset, &third[0], third.size());
10698 	memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
10699 	memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
10700 	memcpy(ptr + sixth_offset, &third[0], third.size());
10701 	memcpy(ptr + seventh_offset, &second[0], second.size());
10702 	memcpy(ptr + eigth_offset, &first[0], first.size());
10703 
10704 	/* Prepare globals */
10705 	size_t position = 0;
10706 	GLchar buffer[16];
10707 
10708 	sprintf(buffer, "%d", basic_size);
10709 	Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
10710 
10711 	sprintf(buffer, "%d", type_align);
10712 	Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
10713 
10714 	sprintf(buffer, "%d", base_stride);
10715 	Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
10716 
10717 	/* Prepare Block */
10718 	Utils::Interface* vs_buf_block = program_interface.Block("vs_buf_Block");
10719 
10720 	vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
10721 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10722 						 first_offset);
10723 
10724 	vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
10725 						 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
10726 						 0 /* n_array_elements */, base_stride, second_offset);
10727 
10728 	vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
10729 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10730 						 third_offset);
10731 
10732 	vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
10733 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10734 						 fourth_offset);
10735 
10736 	vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10737 						 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
10738 
10739 	vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10740 						 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
10741 
10742 	vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
10743 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10744 						 eigth_offset);
10745 
10746 	Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10747 
10748 	/* Add globals */
10749 	vs_si.m_globals = globals;
10750 
10751 	/* Add uniform BLOCK */
10752 	vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0,
10753 			  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10754 
10755 	/* */
10756 	program_interface.CloneVertexInterface(varying_passthrough);
10757 }
10758 
10759 /** Get type name
10760  *
10761  * @param test_case_index Index of test case
10762  *
10763  * @return Name of type test in test_case_index
10764  **/
10765 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
10766 {
10767 	return getTypeName(test_case_index);
10768 }
10769 
10770 /** Returns number of types to test
10771  *
10772  * @return Number of types, 34
10773  **/
10774 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber()
10775 {
10776 	return getTypesNumber();
10777 }
10778 
10779 /** Prepare code snippet that will verify in and uniform variables
10780  *
10781  * @param ignored
10782  * @param ignored
10783  * @param stage   Shader stage
10784  *
10785  * @return Code that verify variables
10786  **/
10787 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */,
10788 																Utils::ProgramInterface& /* program_interface */,
10789 																Utils::Shader::STAGES stage)
10790 {
10791 	std::string verification = "if ( (PREFIXblock.at_first_offset  != PREFIXblock.at_eigth_offset   ) ||\n"
10792 							   "         (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
10793 							   "         (PREFIXblock.at_third_offset  != PREFIXblock.at_sixth_offset[0]) ||\n"
10794 							   "         (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset   )  )\n"
10795 							   "    {\n"
10796 							   "        result = 0;\n"
10797 							   "    }";
10798 
10799 	const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB);
10800 
10801 	Utils::replaceAllTokens("PREFIX", prefix, verification);
10802 
10803 	return verification;
10804 }
10805 
10806 /** Selects if "draw" stages are relevant for test
10807  *
10808  * @param ignored
10809  *
10810  * @return true if all stages support shader storage buffers, false otherwise
10811  **/
10812 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */)
10813 {
10814 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
10815 	GLint			 gs_supported_buffers  = 0;
10816 	GLint			 tcs_supported_buffers = 0;
10817 	GLint			 tes_supported_buffers = 0;
10818 	GLint			 vs_supported_buffers  = 0;
10819 
10820 	gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
10821 	gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
10822 	gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
10823 	gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
10824 
10825 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10826 
10827 	return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
10828 			(1 <= vs_supported_buffers));
10829 }
10830 
10831 /** Constructor
10832  *
10833  * @param context Test framework context
10834  **/
10835 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context& context)
10836 	: NegativeTestBase(context, "ssb_layout_qualifier_conflict", "Test verifies that std140 or std430 is required when "
10837 																 "offset and/or align qualifiers are used with storage "
10838 																 "block")
10839 {
10840 	/* Nothing to be done here */
10841 }
10842 
10843 /** Source for given test case and stage
10844  *
10845  * @param test_case_index Index of test case
10846  * @param stage           Shader stage
10847  *
10848  * @return Shader source
10849  **/
10850 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10851 {
10852 	static const GLchar* cs = "#version 430 core\n"
10853 							  "#extension GL_ARB_enhanced_layouts : require\n"
10854 							  "\n"
10855 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10856 							  "\n"
10857 							  "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n"
10858 							  "    layout(offset = 16) vec4 boy;\n"
10859 							  "    layout(align  = 64) vec4 man;\n"
10860 							  "} uni_block;\n"
10861 							  "\n"
10862 							  "writeonly uniform image2D uni_image;\n"
10863 							  "\n"
10864 							  "void main()\n"
10865 							  "{\n"
10866 							  "    vec4 result = uni_block.boy + uni_block.man;\n"
10867 							  "\n"
10868 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10869 							  "}\n"
10870 							  "\n";
10871 	static const GLchar* fs = "#version 430 core\n"
10872 							  "#extension GL_ARB_enhanced_layouts : require\n"
10873 							  "\n"
10874 							  "layout (QUALIFIERbinding = BINDING) buffer Block {\n"
10875 							  "    layout(offset = 16) vec4 boy;\n"
10876 							  "    layout(align  = 64) vec4 man;\n"
10877 							  "} uni_block;\n"
10878 							  "\n"
10879 							  "in  vec4 gs_fs;\n"
10880 							  "out vec4 fs_out;\n"
10881 							  "\n"
10882 							  "void main()\n"
10883 							  "{\n"
10884 							  "    fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
10885 							  "}\n"
10886 							  "\n";
10887 	static const GLchar* gs = "#version 430 core\n"
10888 							  "#extension GL_ARB_enhanced_layouts : require\n"
10889 							  "\n"
10890 							  "layout(points)                           in;\n"
10891 							  "layout(triangle_strip, max_vertices = 4) out;\n"
10892 							  "\n"
10893 							  "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n"
10894 							  "    layout(offset = 16) vec4 boy;\n"
10895 							  "    layout(align  = 64) vec4 man;\n"
10896 							  "} uni_block;\n"
10897 							  "\n"
10898 							  "in  vec4 tes_gs[];\n"
10899 							  "out vec4 gs_fs;\n"
10900 							  "\n"
10901 							  "void main()\n"
10902 							  "{\n"
10903 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10904 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
10905 							  "    EmitVertex();\n"
10906 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10907 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
10908 							  "    EmitVertex();\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 							  "}\n"
10916 							  "\n";
10917 	static const GLchar* tcs =
10918 		"#version 430 core\n"
10919 		"#extension GL_ARB_enhanced_layouts : require\n"
10920 		"\n"
10921 		"layout(vertices = 1) out;\n"
10922 		"\n"
10923 		"layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n"
10924 		"    layout(offset = 16) vec4 boy;\n"
10925 		"    layout(align  = 64) vec4 man;\n"
10926 		"} uni_block;\n"
10927 		"\n"
10928 		"in  vec4 vs_tcs[];\n"
10929 		"out vec4 tcs_tes[];\n"
10930 		"\n"
10931 		"void main()\n"
10932 		"{\n"
10933 		"\n"
10934 		"    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
10935 		"\n"
10936 		"    gl_TessLevelOuter[0] = 1.0;\n"
10937 		"    gl_TessLevelOuter[1] = 1.0;\n"
10938 		"    gl_TessLevelOuter[2] = 1.0;\n"
10939 		"    gl_TessLevelOuter[3] = 1.0;\n"
10940 		"    gl_TessLevelInner[0] = 1.0;\n"
10941 		"    gl_TessLevelInner[1] = 1.0;\n"
10942 		"}\n"
10943 		"\n";
10944 	static const GLchar* tes = "#version 430 core\n"
10945 							   "#extension GL_ARB_enhanced_layouts : require\n"
10946 							   "\n"
10947 							   "layout(isolines, point_mode) in;\n"
10948 							   "\n"
10949 							   "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n"
10950 							   "    layout(offset = 16) vec4 boy;\n"
10951 							   "    layout(align  = 64) vec4 man;\n"
10952 							   "} uni_block;\n"
10953 							   "\n"
10954 							   "in  vec4 tcs_tes[];\n"
10955 							   "out vec4 tes_gs;\n"
10956 							   "\n"
10957 							   "void main()\n"
10958 							   "{\n"
10959 							   "    tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
10960 							   "}\n"
10961 							   "\n";
10962 	static const GLchar* vs = "#version 430 core\n"
10963 							  "#extension GL_ARB_enhanced_layouts : require\n"
10964 							  "\n"
10965 							  "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n"
10966 							  "    layout(offset = 16) vec4 boy;\n"
10967 							  "    layout(align  = 64) vec4 man;\n"
10968 							  "} uni_block;\n"
10969 							  "\n"
10970 							  "in  vec4 in_vs;\n"
10971 							  "out vec4 vs_tcs;\n"
10972 							  "\n"
10973 							  "void main()\n"
10974 							  "{\n"
10975 							  "    vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
10976 							  "}\n"
10977 							  "\n";
10978 
10979 	GLchar		buffer[16];
10980 	size_t		position = 0;
10981 	std::string source;
10982 	testCase&   test_case = m_test_cases[test_case_index];
10983 	std::string qualifier = getQualifierName(test_case.m_qualifier);
10984 
10985 	if (false == qualifier.empty())
10986 	{
10987 		qualifier.append(", ");
10988 	}
10989 
10990 	sprintf(buffer, "%d", stage);
10991 
10992 	switch (stage)
10993 	{
10994 	case Utils::Shader::COMPUTE:
10995 		source = cs;
10996 		break;
10997 	case Utils::Shader::FRAGMENT:
10998 		source = fs;
10999 		break;
11000 	case Utils::Shader::GEOMETRY:
11001 		source = gs;
11002 		break;
11003 	case Utils::Shader::TESS_CTRL:
11004 		source = tcs;
11005 		break;
11006 	case Utils::Shader::TESS_EVAL:
11007 		source = tes;
11008 		break;
11009 	case Utils::Shader::VERTEX:
11010 		source = vs;
11011 		break;
11012 	default:
11013 		TCU_FAIL("Invalid enum");
11014 	}
11015 
11016 	if (test_case.m_stage == stage)
11017 	{
11018 		Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source);
11019 	}
11020 	else
11021 	{
11022 		Utils::replaceToken("QUALIFIER", position, "std140, ", source);
11023 	}
11024 
11025 	Utils::replaceToken("BINDING", position, buffer, source);
11026 
11027 	return source;
11028 }
11029 
11030 /** Get description of test case
11031  *
11032  * @param test_case_index Index of test case
11033  *
11034  * @return Qualifier name
11035  **/
11036 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
11037 {
11038 	std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
11039 
11040 	return result;
11041 }
11042 
11043 /** Get number of test cases
11044  *
11045  * @return Number of test cases
11046  **/
11047 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber()
11048 {
11049 	return static_cast<GLuint>(m_test_cases.size());
11050 }
11051 
11052 /** Selects if "compute" stage is relevant for test
11053  *
11054  * @param test_case_index Index of test case
11055  *
11056  * @return true when tested stage is compute
11057  **/
11058 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
11059 {
11060 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
11061 }
11062 
11063 /** Selects if compilation failure is expected result
11064  *
11065  * @param test_case_index Index of test case
11066  *
11067  * @return false for STD140 and STD430 cases, true otherwise
11068  **/
11069 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
11070 {
11071 	const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier;
11072 
11073 	return !((STD140 == qualifier) || (STD430 == qualifier));
11074 }
11075 
11076 /** Checks if stage is supported
11077  *
11078  * @param stage Shader stage
11079  *
11080  * @return true if supported, false otherwise
11081  **/
11082 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage)
11083 {
11084 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
11085 	GLint			 max_supported_buffers = 0;
11086 	GLenum			 pname				   = 0;
11087 
11088 	switch (stage)
11089 	{
11090 	case Utils::Shader::COMPUTE:
11091 		pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11092 		break;
11093 	case Utils::Shader::FRAGMENT:
11094 		pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11095 		break;
11096 	case Utils::Shader::GEOMETRY:
11097 		pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11098 		break;
11099 	case Utils::Shader::TESS_CTRL:
11100 		pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11101 		break;
11102 	case Utils::Shader::TESS_EVAL:
11103 		pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11104 		break;
11105 	case Utils::Shader::VERTEX:
11106 		pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11107 		break;
11108 	default:
11109 		TCU_FAIL("Invalid enum");
11110 	}
11111 
11112 	gl.getIntegerv(pname, &max_supported_buffers);
11113 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11114 
11115 	return 1 <= max_supported_buffers;
11116 }
11117 
11118 /** Prepare all test cases
11119  *
11120  **/
11121 void SSBLayoutQualifierConflictTest::testInit()
11122 {
11123 	bool stage_support[Utils::Shader::STAGE_MAX];
11124 
11125 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
11126 	{
11127 		stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
11128 	}
11129 
11130 	for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
11131 	{
11132 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
11133 		{
11134 			if (false == stage_support[stage])
11135 			{
11136 				continue;
11137 			}
11138 
11139 			testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
11140 
11141 			m_test_cases.push_back(test_case);
11142 		}
11143 	}
11144 }
11145 
11146 /** Get name of glsl constant
11147  *
11148  * @param Constant id
11149  *
11150  * @return Name of constant used in GLSL
11151  **/
11152 const GLchar* SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
11153 {
11154 	const GLchar* name = "";
11155 
11156 	switch (qualifier)
11157 	{
11158 	case DEFAULT:
11159 		name = "";
11160 		break;
11161 	case STD140:
11162 		name = "std140";
11163 		break;
11164 	case STD430:
11165 		name = "std430";
11166 		break;
11167 	case SHARED:
11168 		name = "shared";
11169 		break;
11170 	case PACKED:
11171 		name = "packed";
11172 		break;
11173 	default:
11174 		TCU_FAIL("Invalid enum");
11175 	}
11176 
11177 	return name;
11178 }
11179 
11180 /** Constructor
11181  *
11182  * @param context Test framework context
11183  **/
11184 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context& context)
11185 	: UniformBlockMemberInvalidOffsetAlignmentTest(
11186 		  context, "ssb_member_invalid_offset_alignment",
11187 		  "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
11188 {
11189 	/* Nothing to be done here */
11190 }
11191 
11192 /** Get the maximum size for a shader storage block
11193  *
11194  * @return The maximum size in basic machine units of a shader storage block.
11195  **/
11196 GLint SSBMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
11197 {
11198 	const Functions& gl		  = m_context.getRenderContext().getFunctions();
11199 	GLint			 max_size = 0;
11200 
11201 	gl.getIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_size);
11202 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11203 
11204 	return max_size;
11205 }
11206 
11207 /** Source for given test case and stage
11208  *
11209  * @param test_case_index Index of test case
11210  * @param stage           Shader stage
11211  *
11212  * @return Shader source
11213  **/
11214 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11215 {
11216 	static const GLchar* cs = "#version 430 core\n"
11217 							  "#extension GL_ARB_enhanced_layouts : require\n"
11218 							  "\n"
11219 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11220 							  "\n"
11221 							  "layout (std140) buffer Block {\n"
11222 							  "    layout (offset = OFFSET) TYPE member;\n"
11223 							  "} block;\n"
11224 							  "\n"
11225 							  "writeonly uniform image2D uni_image;\n"
11226 							  "\n"
11227 							  "void main()\n"
11228 							  "{\n"
11229 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
11230 							  "\n"
11231 							  "    if (TYPE(1) == block.member)\n"
11232 							  "    {\n"
11233 							  "        result = vec4(1, 1, 1, 1);\n"
11234 							  "    }\n"
11235 							  "\n"
11236 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11237 							  "}\n"
11238 							  "\n";
11239 	static const GLchar* fs = "#version 430 core\n"
11240 							  "#extension GL_ARB_enhanced_layouts : require\n"
11241 							  "\n"
11242 							  "in  vec4 gs_fs;\n"
11243 							  "out vec4 fs_out;\n"
11244 							  "\n"
11245 							  "void main()\n"
11246 							  "{\n"
11247 							  "    fs_out = gs_fs;\n"
11248 							  "}\n"
11249 							  "\n";
11250 	static const GLchar* fs_tested = "#version 430 core\n"
11251 									 "#extension GL_ARB_enhanced_layouts : require\n"
11252 									 "\n"
11253 									 "layout (std140) buffer Block {\n"
11254 									 "    layout (offset = OFFSET) TYPE member;\n"
11255 									 "} block;\n"
11256 									 "\n"
11257 									 "in  vec4 gs_fs;\n"
11258 									 "out vec4 fs_out;\n"
11259 									 "\n"
11260 									 "void main()\n"
11261 									 "{\n"
11262 									 "    if (TYPE(1) == block.member)\n"
11263 									 "    {\n"
11264 									 "        fs_out = vec4(1, 1, 1, 1);\n"
11265 									 "    }\n"
11266 									 "\n"
11267 									 "    fs_out += gs_fs;\n"
11268 									 "}\n"
11269 									 "\n";
11270 	static const GLchar* gs = "#version 430 core\n"
11271 							  "#extension GL_ARB_enhanced_layouts : require\n"
11272 							  "\n"
11273 							  "layout(points)                           in;\n"
11274 							  "layout(triangle_strip, max_vertices = 4) out;\n"
11275 							  "\n"
11276 							  "in  vec4 tes_gs[];\n"
11277 							  "out vec4 gs_fs;\n"
11278 							  "\n"
11279 							  "void main()\n"
11280 							  "{\n"
11281 							  "    gs_fs = tes_gs[0];\n"
11282 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11283 							  "    EmitVertex();\n"
11284 							  "    gs_fs = tes_gs[0];\n"
11285 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11286 							  "    EmitVertex();\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 							  "}\n"
11294 							  "\n";
11295 	static const GLchar* gs_tested = "#version 430 core\n"
11296 									 "#extension GL_ARB_enhanced_layouts : require\n"
11297 									 "\n"
11298 									 "layout(points)                           in;\n"
11299 									 "layout(triangle_strip, max_vertices = 4) out;\n"
11300 									 "\n"
11301 									 "layout (std140) buffer Block {\n"
11302 									 "    layout (offset = OFFSET) TYPE member;\n"
11303 									 "} block;\n"
11304 									 "\n"
11305 									 "in  vec4 tes_gs[];\n"
11306 									 "out vec4 gs_fs;\n"
11307 									 "\n"
11308 									 "void main()\n"
11309 									 "{\n"
11310 									 "    if (TYPE(1) == block.member)\n"
11311 									 "    {\n"
11312 									 "        gs_fs = vec4(1, 1, 1, 1);\n"
11313 									 "    }\n"
11314 									 "\n"
11315 									 "    gs_fs += tes_gs[0];\n"
11316 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11317 									 "    EmitVertex();\n"
11318 									 "    gs_fs += tes_gs[0];\n"
11319 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11320 									 "    EmitVertex();\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 									 "}\n"
11328 									 "\n";
11329 	static const GLchar* tcs = "#version 430 core\n"
11330 							   "#extension GL_ARB_enhanced_layouts : require\n"
11331 							   "\n"
11332 							   "layout(vertices = 1) out;\n"
11333 							   "\n"
11334 							   "in  vec4 vs_tcs[];\n"
11335 							   "out vec4 tcs_tes[];\n"
11336 							   "\n"
11337 							   "void main()\n"
11338 							   "{\n"
11339 							   "\n"
11340 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11341 							   "\n"
11342 							   "    gl_TessLevelOuter[0] = 1.0;\n"
11343 							   "    gl_TessLevelOuter[1] = 1.0;\n"
11344 							   "    gl_TessLevelOuter[2] = 1.0;\n"
11345 							   "    gl_TessLevelOuter[3] = 1.0;\n"
11346 							   "    gl_TessLevelInner[0] = 1.0;\n"
11347 							   "    gl_TessLevelInner[1] = 1.0;\n"
11348 							   "}\n"
11349 							   "\n";
11350 	static const GLchar* tcs_tested = "#version 430 core\n"
11351 									  "#extension GL_ARB_enhanced_layouts : require\n"
11352 									  "\n"
11353 									  "layout(vertices = 1) out;\n"
11354 									  "\n"
11355 									  "layout (std140) buffer Block {\n"
11356 									  "    layout (offset = OFFSET) TYPE member;\n"
11357 									  "} block;\n"
11358 									  "\n"
11359 									  "in  vec4 vs_tcs[];\n"
11360 									  "out vec4 tcs_tes[];\n"
11361 									  "\n"
11362 									  "void main()\n"
11363 									  "{\n"
11364 									  "    if (TYPE(1) == block.member)\n"
11365 									  "    {\n"
11366 									  "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11367 									  "    }\n"
11368 									  "\n"
11369 									  "\n"
11370 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11371 									  "\n"
11372 									  "    gl_TessLevelOuter[0] = 1.0;\n"
11373 									  "    gl_TessLevelOuter[1] = 1.0;\n"
11374 									  "    gl_TessLevelOuter[2] = 1.0;\n"
11375 									  "    gl_TessLevelOuter[3] = 1.0;\n"
11376 									  "    gl_TessLevelInner[0] = 1.0;\n"
11377 									  "    gl_TessLevelInner[1] = 1.0;\n"
11378 									  "}\n"
11379 									  "\n";
11380 	static const GLchar* tes = "#version 430 core\n"
11381 							   "#extension GL_ARB_enhanced_layouts : require\n"
11382 							   "\n"
11383 							   "layout(isolines, point_mode) in;\n"
11384 							   "\n"
11385 							   "in  vec4 tcs_tes[];\n"
11386 							   "out vec4 tes_gs;\n"
11387 							   "\n"
11388 							   "void main()\n"
11389 							   "{\n"
11390 							   "    tes_gs = tcs_tes[0];\n"
11391 							   "}\n"
11392 							   "\n";
11393 	static const GLchar* tes_tested = "#version 430 core\n"
11394 									  "#extension GL_ARB_enhanced_layouts : require\n"
11395 									  "\n"
11396 									  "layout(isolines, point_mode) in;\n"
11397 									  "\n"
11398 									  "layout (std140) buffer Block {\n"
11399 									  "    layout (offset = OFFSET) TYPE member;\n"
11400 									  "} block;\n"
11401 									  "\n"
11402 									  "in  vec4 tcs_tes[];\n"
11403 									  "out vec4 tes_gs;\n"
11404 									  "\n"
11405 									  "void main()\n"
11406 									  "{\n"
11407 									  "    if (TYPE(1) == block.member)\n"
11408 									  "    {\n"
11409 									  "        tes_gs = vec4(1, 1, 1, 1);\n"
11410 									  "    }\n"
11411 									  "\n"
11412 									  "    tes_gs += tcs_tes[0];\n"
11413 									  "}\n"
11414 									  "\n";
11415 	static const GLchar* vs = "#version 430 core\n"
11416 							  "#extension GL_ARB_enhanced_layouts : require\n"
11417 							  "\n"
11418 							  "in  vec4 in_vs;\n"
11419 							  "out vec4 vs_tcs;\n"
11420 							  "\n"
11421 							  "void main()\n"
11422 							  "{\n"
11423 							  "    vs_tcs = in_vs;\n"
11424 							  "}\n"
11425 							  "\n";
11426 	static const GLchar* vs_tested = "#version 430 core\n"
11427 									 "#extension GL_ARB_enhanced_layouts : require\n"
11428 									 "\n"
11429 									 "layout (std140) buffer Block {\n"
11430 									 "    layout (offset = OFFSET) TYPE member;\n"
11431 									 "} block;\n"
11432 									 "\n"
11433 									 "in  vec4 in_vs;\n"
11434 									 "out vec4 vs_tcs;\n"
11435 									 "\n"
11436 									 "void main()\n"
11437 									 "{\n"
11438 									 "    if (TYPE(1) == block.member)\n"
11439 									 "    {\n"
11440 									 "        vs_tcs = vec4(1, 1, 1, 1);\n"
11441 									 "    }\n"
11442 									 "\n"
11443 									 "    vs_tcs += in_vs;\n"
11444 									 "}\n"
11445 									 "\n";
11446 
11447 	std::string source;
11448 	testCase&   test_case = m_test_cases[test_case_index];
11449 
11450 	if (test_case.m_stage == stage)
11451 	{
11452 		GLchar			   buffer[16];
11453 		const GLuint	   offset	= test_case.m_offset;
11454 		size_t			   position  = 0;
11455 		const Utils::Type& type		 = test_case.m_type;
11456 		const GLchar*	  type_name = type.GetGLSLTypeName();
11457 
11458 		sprintf(buffer, "%d", offset);
11459 
11460 		switch (stage)
11461 		{
11462 		case Utils::Shader::COMPUTE:
11463 			source = cs;
11464 			break;
11465 		case Utils::Shader::FRAGMENT:
11466 			source = fs_tested;
11467 			break;
11468 		case Utils::Shader::GEOMETRY:
11469 			source = gs_tested;
11470 			break;
11471 		case Utils::Shader::TESS_CTRL:
11472 			source = tcs_tested;
11473 			break;
11474 		case Utils::Shader::TESS_EVAL:
11475 			source = tes_tested;
11476 			break;
11477 		case Utils::Shader::VERTEX:
11478 			source = vs_tested;
11479 			break;
11480 		default:
11481 			TCU_FAIL("Invalid enum");
11482 		}
11483 
11484 		Utils::replaceToken("OFFSET", position, buffer, source);
11485 		Utils::replaceToken("TYPE", position, type_name, source);
11486 		Utils::replaceToken("TYPE", position, type_name, source);
11487 	}
11488 	else
11489 	{
11490 		switch (stage)
11491 		{
11492 		case Utils::Shader::FRAGMENT:
11493 			source = fs;
11494 			break;
11495 		case Utils::Shader::GEOMETRY:
11496 			source = gs;
11497 			break;
11498 		case Utils::Shader::TESS_CTRL:
11499 			source = tcs;
11500 			break;
11501 		case Utils::Shader::TESS_EVAL:
11502 			source = tes;
11503 			break;
11504 		case Utils::Shader::VERTEX:
11505 			source = vs;
11506 			break;
11507 		default:
11508 			TCU_FAIL("Invalid enum");
11509 		}
11510 	}
11511 
11512 	return source;
11513 }
11514 
11515 /** Checks if stage is supported
11516  *
11517  * @param stage Shader stage
11518  *
11519  * @return true if supported, false otherwise
11520  **/
11521 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage)
11522 {
11523 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
11524 	GLint			 max_supported_buffers = 0;
11525 	GLenum			 pname				   = 0;
11526 
11527 	switch (stage)
11528 	{
11529 	case Utils::Shader::COMPUTE:
11530 		pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11531 		break;
11532 	case Utils::Shader::FRAGMENT:
11533 		pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11534 		break;
11535 	case Utils::Shader::GEOMETRY:
11536 		pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11537 		break;
11538 	case Utils::Shader::TESS_CTRL:
11539 		pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11540 		break;
11541 	case Utils::Shader::TESS_EVAL:
11542 		pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11543 		break;
11544 	case Utils::Shader::VERTEX:
11545 		pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11546 		break;
11547 	default:
11548 		TCU_FAIL("Invalid enum");
11549 	}
11550 
11551 	gl.getIntegerv(pname, &max_supported_buffers);
11552 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11553 
11554 	return 1 <= max_supported_buffers;
11555 }
11556 
11557 /** Constructor
11558  *
11559  * @param context Test framework context
11560  **/
11561 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context& context)
11562 	: UniformBlockMemberOverlappingOffsetsTest(
11563 		  context, "ssb_member_overlapping_offsets",
11564 		  "Test verifies that overlapping offsets qualifiers cause compilation failure")
11565 {
11566 	/* Nothing to be done here */
11567 }
11568 
11569 /** Source for given test case and stage
11570  *
11571  * @param test_case_index Index of test case
11572  * @param stage           Shader stage
11573  *
11574  * @return Shader source
11575  **/
11576 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11577 {
11578 	static const GLchar* cs = "#version 430 core\n"
11579 							  "#extension GL_ARB_enhanced_layouts : require\n"
11580 							  "\n"
11581 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11582 							  "\n"
11583 							  "layout (std140) buffer Block {\n"
11584 							  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11585 							  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11586 							  "} block;\n"
11587 							  "\n"
11588 							  "writeonly uniform image2D uni_image;\n"
11589 							  "\n"
11590 							  "void main()\n"
11591 							  "{\n"
11592 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
11593 							  "\n"
11594 							  "    if ((BOY_TYPE(1) == block.boy) ||\n"
11595 							  "        (MAN_TYPE(0) == block.man) )\n"
11596 							  "    {\n"
11597 							  "        result = vec4(1, 1, 1, 1);\n"
11598 							  "    }\n"
11599 							  "\n"
11600 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11601 							  "}\n"
11602 							  "\n";
11603 	static const GLchar* fs = "#version 430 core\n"
11604 							  "#extension GL_ARB_enhanced_layouts : require\n"
11605 							  "\n"
11606 							  "in  vec4 gs_fs;\n"
11607 							  "out vec4 fs_out;\n"
11608 							  "\n"
11609 							  "void main()\n"
11610 							  "{\n"
11611 							  "    fs_out = gs_fs;\n"
11612 							  "}\n"
11613 							  "\n";
11614 	static const GLchar* fs_tested = "#version 430 core\n"
11615 									 "#extension GL_ARB_enhanced_layouts : require\n"
11616 									 "\n"
11617 									 "layout (std140) buffer Block {\n"
11618 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11619 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11620 									 "} block;\n"
11621 									 "\n"
11622 									 "in  vec4 gs_fs;\n"
11623 									 "out vec4 fs_out;\n"
11624 									 "\n"
11625 									 "void main()\n"
11626 									 "{\n"
11627 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
11628 									 "        (MAN_TYPE(0) == block.man) )\n"
11629 									 "    {\n"
11630 									 "        fs_out = vec4(1, 1, 1, 1);\n"
11631 									 "    }\n"
11632 									 "\n"
11633 									 "    fs_out += gs_fs;\n"
11634 									 "}\n"
11635 									 "\n";
11636 	static const GLchar* gs = "#version 430 core\n"
11637 							  "#extension GL_ARB_enhanced_layouts : require\n"
11638 							  "\n"
11639 							  "layout(points)                           in;\n"
11640 							  "layout(triangle_strip, max_vertices = 4) out;\n"
11641 							  "\n"
11642 							  "in  vec4 tes_gs[];\n"
11643 							  "out vec4 gs_fs;\n"
11644 							  "\n"
11645 							  "void main()\n"
11646 							  "{\n"
11647 							  "    gs_fs = tes_gs[0];\n"
11648 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11649 							  "    EmitVertex();\n"
11650 							  "    gs_fs = tes_gs[0];\n"
11651 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11652 							  "    EmitVertex();\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 							  "}\n"
11660 							  "\n";
11661 	static const GLchar* gs_tested = "#version 430 core\n"
11662 									 "#extension GL_ARB_enhanced_layouts : require\n"
11663 									 "\n"
11664 									 "layout(points)                           in;\n"
11665 									 "layout(triangle_strip, max_vertices = 4) out;\n"
11666 									 "\n"
11667 									 "layout (std140) buffer Block {\n"
11668 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11669 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11670 									 "} block;\n"
11671 									 "\n"
11672 									 "in  vec4 tes_gs[];\n"
11673 									 "out vec4 gs_fs;\n"
11674 									 "\n"
11675 									 "void main()\n"
11676 									 "{\n"
11677 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
11678 									 "        (MAN_TYPE(0) == block.man) )\n"
11679 									 "    {\n"
11680 									 "        gs_fs = vec4(1, 1, 1, 1);\n"
11681 									 "    }\n"
11682 									 "\n"
11683 									 "    gs_fs += tes_gs[0];\n"
11684 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11685 									 "    EmitVertex();\n"
11686 									 "    gs_fs += tes_gs[0];\n"
11687 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11688 									 "    EmitVertex();\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 									 "}\n"
11696 									 "\n";
11697 	static const GLchar* tcs = "#version 430 core\n"
11698 							   "#extension GL_ARB_enhanced_layouts : require\n"
11699 							   "\n"
11700 							   "layout(vertices = 1) out;\n"
11701 							   "\n"
11702 							   "in  vec4 vs_tcs[];\n"
11703 							   "out vec4 tcs_tes[];\n"
11704 							   "\n"
11705 							   "void main()\n"
11706 							   "{\n"
11707 							   "\n"
11708 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11709 							   "\n"
11710 							   "    gl_TessLevelOuter[0] = 1.0;\n"
11711 							   "    gl_TessLevelOuter[1] = 1.0;\n"
11712 							   "    gl_TessLevelOuter[2] = 1.0;\n"
11713 							   "    gl_TessLevelOuter[3] = 1.0;\n"
11714 							   "    gl_TessLevelInner[0] = 1.0;\n"
11715 							   "    gl_TessLevelInner[1] = 1.0;\n"
11716 							   "}\n"
11717 							   "\n";
11718 	static const GLchar* tcs_tested = "#version 430 core\n"
11719 									  "#extension GL_ARB_enhanced_layouts : require\n"
11720 									  "\n"
11721 									  "layout(vertices = 1) out;\n"
11722 									  "\n"
11723 									  "layout (std140) buffer Block {\n"
11724 									  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11725 									  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11726 									  "} block;\n"
11727 									  "\n"
11728 									  "in  vec4 vs_tcs[];\n"
11729 									  "out vec4 tcs_tes[];\n"
11730 									  "\n"
11731 									  "void main()\n"
11732 									  "{\n"
11733 									  "    if ((BOY_TYPE(1) == block.boy) ||\n"
11734 									  "        (MAN_TYPE(0) == block.man) )\n"
11735 									  "    {\n"
11736 									  "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11737 									  "    }\n"
11738 									  "\n"
11739 									  "\n"
11740 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11741 									  "\n"
11742 									  "    gl_TessLevelOuter[0] = 1.0;\n"
11743 									  "    gl_TessLevelOuter[1] = 1.0;\n"
11744 									  "    gl_TessLevelOuter[2] = 1.0;\n"
11745 									  "    gl_TessLevelOuter[3] = 1.0;\n"
11746 									  "    gl_TessLevelInner[0] = 1.0;\n"
11747 									  "    gl_TessLevelInner[1] = 1.0;\n"
11748 									  "}\n"
11749 									  "\n";
11750 	static const GLchar* tes = "#version 430 core\n"
11751 							   "#extension GL_ARB_enhanced_layouts : require\n"
11752 							   "\n"
11753 							   "layout(isolines, point_mode) in;\n"
11754 							   "\n"
11755 							   "in  vec4 tcs_tes[];\n"
11756 							   "out vec4 tes_gs;\n"
11757 							   "\n"
11758 							   "void main()\n"
11759 							   "{\n"
11760 							   "    tes_gs = tcs_tes[0];\n"
11761 							   "}\n"
11762 							   "\n";
11763 	static const GLchar* tes_tested = "#version 430 core\n"
11764 									  "#extension GL_ARB_enhanced_layouts : require\n"
11765 									  "\n"
11766 									  "layout(isolines, point_mode) in;\n"
11767 									  "\n"
11768 									  "layout (std140) buffer Block {\n"
11769 									  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11770 									  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11771 									  "} block;\n"
11772 									  "\n"
11773 									  "in  vec4 tcs_tes[];\n"
11774 									  "out vec4 tes_gs;\n"
11775 									  "\n"
11776 									  "void main()\n"
11777 									  "{\n"
11778 									  "    if ((BOY_TYPE(1) == block.boy) ||\n"
11779 									  "        (MAN_TYPE(0) == block.man) )\n"
11780 									  "    {\n"
11781 									  "        tes_gs = vec4(1, 1, 1, 1);\n"
11782 									  "    }\n"
11783 									  "\n"
11784 									  "    tes_gs += tcs_tes[0];\n"
11785 									  "}\n"
11786 									  "\n";
11787 	static const GLchar* vs = "#version 430 core\n"
11788 							  "#extension GL_ARB_enhanced_layouts : require\n"
11789 							  "\n"
11790 							  "in  vec4 in_vs;\n"
11791 							  "out vec4 vs_tcs;\n"
11792 							  "\n"
11793 							  "void main()\n"
11794 							  "{\n"
11795 							  "    vs_tcs = in_vs;\n"
11796 							  "}\n"
11797 							  "\n";
11798 	static const GLchar* vs_tested = "#version 430 core\n"
11799 									 "#extension GL_ARB_enhanced_layouts : require\n"
11800 									 "\n"
11801 									 "layout (std140) buffer Block {\n"
11802 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11803 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11804 									 "} block;\n"
11805 									 "\n"
11806 									 "in  vec4 in_vs;\n"
11807 									 "out vec4 vs_tcs;\n"
11808 									 "\n"
11809 									 "void main()\n"
11810 									 "{\n"
11811 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
11812 									 "        (MAN_TYPE(0) == block.man) )\n"
11813 									 "    {\n"
11814 									 "        vs_tcs = vec4(1, 1, 1, 1);\n"
11815 									 "    }\n"
11816 									 "\n"
11817 									 "    vs_tcs += in_vs;\n"
11818 									 "}\n"
11819 									 "\n";
11820 
11821 	std::string source;
11822 	testCase&   test_case = m_test_cases[test_case_index];
11823 
11824 	if (test_case.m_stage == stage)
11825 	{
11826 		GLchar			   buffer[16];
11827 		const GLuint	   boy_offset	= test_case.m_boy_offset;
11828 		const Utils::Type& boy_type		 = test_case.m_boy_type;
11829 		const GLchar*	  boy_type_name = boy_type.GetGLSLTypeName();
11830 		const GLuint	   man_offset	= test_case.m_man_offset;
11831 		const Utils::Type& man_type		 = test_case.m_man_type;
11832 		const GLchar*	  man_type_name = man_type.GetGLSLTypeName();
11833 		size_t			   position		 = 0;
11834 
11835 		switch (stage)
11836 		{
11837 		case Utils::Shader::COMPUTE:
11838 			source = cs;
11839 			break;
11840 		case Utils::Shader::FRAGMENT:
11841 			source = fs_tested;
11842 			break;
11843 		case Utils::Shader::GEOMETRY:
11844 			source = gs_tested;
11845 			break;
11846 		case Utils::Shader::TESS_CTRL:
11847 			source = tcs_tested;
11848 			break;
11849 		case Utils::Shader::TESS_EVAL:
11850 			source = tes_tested;
11851 			break;
11852 		case Utils::Shader::VERTEX:
11853 			source = vs_tested;
11854 			break;
11855 		default:
11856 			TCU_FAIL("Invalid enum");
11857 		}
11858 
11859 		sprintf(buffer, "%d", boy_offset);
11860 		Utils::replaceToken("BOY_OFFSET", position, buffer, source);
11861 		Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11862 		sprintf(buffer, "%d", man_offset);
11863 		Utils::replaceToken("MAN_OFFSET", position, buffer, source);
11864 		Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11865 		Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11866 		Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11867 	}
11868 	else
11869 	{
11870 		switch (stage)
11871 		{
11872 		case Utils::Shader::FRAGMENT:
11873 			source = fs;
11874 			break;
11875 		case Utils::Shader::GEOMETRY:
11876 			source = gs;
11877 			break;
11878 		case Utils::Shader::TESS_CTRL:
11879 			source = tcs;
11880 			break;
11881 		case Utils::Shader::TESS_EVAL:
11882 			source = tes;
11883 			break;
11884 		case Utils::Shader::VERTEX:
11885 			source = vs;
11886 			break;
11887 		default:
11888 			TCU_FAIL("Invalid enum");
11889 		}
11890 	}
11891 
11892 	return source;
11893 }
11894 
11895 /** Checks if stage is supported
11896  *
11897  * @param stage Shader stage
11898  *
11899  * @return true if supported, false otherwise
11900  **/
11901 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage)
11902 {
11903 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
11904 	GLint			 max_supported_buffers = 0;
11905 	GLenum			 pname				   = 0;
11906 
11907 	switch (stage)
11908 	{
11909 	case Utils::Shader::COMPUTE:
11910 		pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11911 		break;
11912 	case Utils::Shader::FRAGMENT:
11913 		pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11914 		break;
11915 	case Utils::Shader::GEOMETRY:
11916 		pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11917 		break;
11918 	case Utils::Shader::TESS_CTRL:
11919 		pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11920 		break;
11921 	case Utils::Shader::TESS_EVAL:
11922 		pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11923 		break;
11924 	case Utils::Shader::VERTEX:
11925 		pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11926 		break;
11927 	default:
11928 		TCU_FAIL("Invalid enum");
11929 	}
11930 
11931 	gl.getIntegerv(pname, &max_supported_buffers);
11932 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11933 
11934 	return 1 <= max_supported_buffers;
11935 }
11936 
11937 /** Constructor
11938  *
11939  * @param context Test framework context
11940  **/
11941 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context& context)
11942 	: UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2",
11943 											 "Test verifies that align qualifier requires value that is a power of 2")
11944 {
11945 	/* Nothing to be done here */
11946 }
11947 
11948 /** Source for given test case and stage
11949  *
11950  * @param test_case_index Index of test case
11951  * @param stage           Shader stage
11952  *
11953  * @return Shader source
11954  **/
11955 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11956 {
11957 	static const GLchar* cs = "#version 430 core\n"
11958 							  "#extension GL_ARB_enhanced_layouts : require\n"
11959 							  "\n"
11960 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11961 							  "\n"
11962 							  "layout (std140) buffer Block {\n"
11963 							  "    vec4 boy;\n"
11964 							  "    layout (align = ALIGN) TYPE man;\n"
11965 							  "} block;\n"
11966 							  "\n"
11967 							  "writeonly uniform image2D uni_image;\n"
11968 							  "\n"
11969 							  "void main()\n"
11970 							  "{\n"
11971 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
11972 							  "\n"
11973 							  "    if (TYPE(0) == block.man)\n"
11974 							  "    {\n"
11975 							  "        result = vec4(1, 1, 1, 1) - block.boy;\n"
11976 							  "    }\n"
11977 							  "\n"
11978 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11979 							  "}\n"
11980 							  "\n";
11981 	static const GLchar* fs = "#version 430 core\n"
11982 							  "#extension GL_ARB_enhanced_layouts : require\n"
11983 							  "\n"
11984 							  "in  vec4 gs_fs;\n"
11985 							  "out vec4 fs_out;\n"
11986 							  "\n"
11987 							  "void main()\n"
11988 							  "{\n"
11989 							  "    fs_out = gs_fs;\n"
11990 							  "}\n"
11991 							  "\n";
11992 	static const GLchar* fs_tested = "#version 430 core\n"
11993 									 "#extension GL_ARB_enhanced_layouts : require\n"
11994 									 "\n"
11995 									 "layout (std140) buffer Block {\n"
11996 									 "    vec4 boy;\n"
11997 									 "    layout (align = ALIGN) TYPE man;\n"
11998 									 "} block;\n"
11999 									 "\n"
12000 									 "in  vec4 gs_fs;\n"
12001 									 "out vec4 fs_out;\n"
12002 									 "\n"
12003 									 "void main()\n"
12004 									 "{\n"
12005 									 "    if (TYPE(0) == block.man)\n"
12006 									 "    {\n"
12007 									 "        fs_out = block.boy;\n"
12008 									 "    }\n"
12009 									 "\n"
12010 									 "    fs_out += gs_fs;\n"
12011 									 "}\n"
12012 									 "\n";
12013 	static const GLchar* gs = "#version 430 core\n"
12014 							  "#extension GL_ARB_enhanced_layouts : require\n"
12015 							  "\n"
12016 							  "layout(points)                           in;\n"
12017 							  "layout(triangle_strip, max_vertices = 4) out;\n"
12018 							  "\n"
12019 							  "in  vec4 tes_gs[];\n"
12020 							  "out vec4 gs_fs;\n"
12021 							  "\n"
12022 							  "void main()\n"
12023 							  "{\n"
12024 							  "    gs_fs = tes_gs[0];\n"
12025 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
12026 							  "    EmitVertex();\n"
12027 							  "    gs_fs = tes_gs[0];\n"
12028 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
12029 							  "    EmitVertex();\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 							  "}\n"
12037 							  "\n";
12038 	static const GLchar* gs_tested = "#version 430 core\n"
12039 									 "#extension GL_ARB_enhanced_layouts : require\n"
12040 									 "\n"
12041 									 "layout(points)                           in;\n"
12042 									 "layout(triangle_strip, max_vertices = 4) out;\n"
12043 									 "\n"
12044 									 "layout (std140) buffer Block {\n"
12045 									 "    vec4 boy;\n"
12046 									 "    layout (align = ALIGN) TYPE man;\n"
12047 									 "} block;\n"
12048 									 "\n"
12049 									 "in  vec4 tes_gs[];\n"
12050 									 "out vec4 gs_fs;\n"
12051 									 "\n"
12052 									 "void main()\n"
12053 									 "{\n"
12054 									 "    if (TYPE(0) == block.man)\n"
12055 									 "    {\n"
12056 									 "        gs_fs = block.boy;\n"
12057 									 "    }\n"
12058 									 "\n"
12059 									 "    gs_fs += tes_gs[0];\n"
12060 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
12061 									 "    EmitVertex();\n"
12062 									 "    gs_fs += tes_gs[0];\n"
12063 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
12064 									 "    EmitVertex();\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 									 "}\n"
12072 									 "\n";
12073 	static const GLchar* tcs = "#version 430 core\n"
12074 							   "#extension GL_ARB_enhanced_layouts : require\n"
12075 							   "\n"
12076 							   "layout(vertices = 1) out;\n"
12077 							   "\n"
12078 							   "in  vec4 vs_tcs[];\n"
12079 							   "out vec4 tcs_tes[];\n"
12080 							   "\n"
12081 							   "void main()\n"
12082 							   "{\n"
12083 							   "\n"
12084 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
12085 							   "\n"
12086 							   "    gl_TessLevelOuter[0] = 1.0;\n"
12087 							   "    gl_TessLevelOuter[1] = 1.0;\n"
12088 							   "    gl_TessLevelOuter[2] = 1.0;\n"
12089 							   "    gl_TessLevelOuter[3] = 1.0;\n"
12090 							   "    gl_TessLevelInner[0] = 1.0;\n"
12091 							   "    gl_TessLevelInner[1] = 1.0;\n"
12092 							   "}\n"
12093 							   "\n";
12094 	static const GLchar* tcs_tested = "#version 430 core\n"
12095 									  "#extension GL_ARB_enhanced_layouts : require\n"
12096 									  "\n"
12097 									  "layout(vertices = 1) out;\n"
12098 									  "\n"
12099 									  "layout (std140) buffer Block {\n"
12100 									  "    vec4 boy;\n"
12101 									  "    layout (align = ALIGN) TYPE man;\n"
12102 									  "} block;\n"
12103 									  "\n"
12104 									  "in  vec4 vs_tcs[];\n"
12105 									  "out vec4 tcs_tes[];\n"
12106 									  "\n"
12107 									  "void main()\n"
12108 									  "{\n"
12109 									  "    if (TYPE(0) == block.man)\n"
12110 									  "    {\n"
12111 									  "        tcs_tes[gl_InvocationID] = block.boy;\n"
12112 									  "    }\n"
12113 									  "\n"
12114 									  "\n"
12115 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
12116 									  "\n"
12117 									  "    gl_TessLevelOuter[0] = 1.0;\n"
12118 									  "    gl_TessLevelOuter[1] = 1.0;\n"
12119 									  "    gl_TessLevelOuter[2] = 1.0;\n"
12120 									  "    gl_TessLevelOuter[3] = 1.0;\n"
12121 									  "    gl_TessLevelInner[0] = 1.0;\n"
12122 									  "    gl_TessLevelInner[1] = 1.0;\n"
12123 									  "}\n"
12124 									  "\n";
12125 	static const GLchar* tes = "#version 430 core\n"
12126 							   "#extension GL_ARB_enhanced_layouts : require\n"
12127 							   "\n"
12128 							   "layout(isolines, point_mode) in;\n"
12129 							   "\n"
12130 							   "in  vec4 tcs_tes[];\n"
12131 							   "out vec4 tes_gs;\n"
12132 							   "\n"
12133 							   "void main()\n"
12134 							   "{\n"
12135 							   "    tes_gs = tcs_tes[0];\n"
12136 							   "}\n"
12137 							   "\n";
12138 	static const GLchar* tes_tested = "#version 430 core\n"
12139 									  "#extension GL_ARB_enhanced_layouts : require\n"
12140 									  "\n"
12141 									  "layout(isolines, point_mode) in;\n"
12142 									  "\n"
12143 									  "layout (std140) buffer Block {\n"
12144 									  "    vec4 boy;\n"
12145 									  "    layout (align = ALIGN) TYPE man;\n"
12146 									  "} block;\n"
12147 									  "\n"
12148 									  "in  vec4 tcs_tes[];\n"
12149 									  "out vec4 tes_gs;\n"
12150 									  "\n"
12151 									  "void main()\n"
12152 									  "{\n"
12153 									  "    if (TYPE(0) == block.man)\n"
12154 									  "    {\n"
12155 									  "        tes_gs = block.boy;\n"
12156 									  "    }\n"
12157 									  "\n"
12158 									  "    tes_gs += tcs_tes[0];\n"
12159 									  "}\n"
12160 									  "\n";
12161 	static const GLchar* vs = "#version 430 core\n"
12162 							  "#extension GL_ARB_enhanced_layouts : require\n"
12163 							  "\n"
12164 							  "in  vec4 in_vs;\n"
12165 							  "out vec4 vs_tcs;\n"
12166 							  "\n"
12167 							  "void main()\n"
12168 							  "{\n"
12169 							  "    vs_tcs = in_vs;\n"
12170 							  "}\n"
12171 							  "\n";
12172 	static const GLchar* vs_tested = "#version 430 core\n"
12173 									 "#extension GL_ARB_enhanced_layouts : require\n"
12174 									 "\n"
12175 									 "layout (std140) buffer Block {\n"
12176 									 "    vec4 boy;\n"
12177 									 "    layout (align = ALIGN) TYPE man;\n"
12178 									 "} block;\n"
12179 									 "\n"
12180 									 "in  vec4 in_vs;\n"
12181 									 "out vec4 vs_tcs;\n"
12182 									 "\n"
12183 									 "void main()\n"
12184 									 "{\n"
12185 									 "    if (TYPE(0) == block.man)\n"
12186 									 "    {\n"
12187 									 "        vs_tcs = block.boy;\n"
12188 									 "    }\n"
12189 									 "\n"
12190 									 "    vs_tcs += in_vs;\n"
12191 									 "}\n"
12192 									 "\n";
12193 
12194 	std::string source;
12195 	testCase&   test_case = m_test_cases[test_case_index];
12196 
12197 	if (test_case.m_stage == stage)
12198 	{
12199 		GLchar			   buffer[16];
12200 		const GLuint	   alignment = test_case.m_alignment;
12201 		const Utils::Type& type		 = test_case.m_type;
12202 		const GLchar*	  type_name = type.GetGLSLTypeName();
12203 		size_t			   position  = 0;
12204 
12205 		switch (stage)
12206 		{
12207 		case Utils::Shader::COMPUTE:
12208 			source = cs;
12209 			break;
12210 		case Utils::Shader::FRAGMENT:
12211 			source = fs_tested;
12212 			break;
12213 		case Utils::Shader::GEOMETRY:
12214 			source = gs_tested;
12215 			break;
12216 		case Utils::Shader::TESS_CTRL:
12217 			source = tcs_tested;
12218 			break;
12219 		case Utils::Shader::TESS_EVAL:
12220 			source = tes_tested;
12221 			break;
12222 		case Utils::Shader::VERTEX:
12223 			source = vs_tested;
12224 			break;
12225 		default:
12226 			TCU_FAIL("Invalid enum");
12227 		}
12228 
12229 		sprintf(buffer, "%d", alignment);
12230 		Utils::replaceToken("ALIGN", position, buffer, source);
12231 		Utils::replaceToken("TYPE", position, type_name, source);
12232 		Utils::replaceToken("TYPE", position, type_name, source);
12233 	}
12234 	else
12235 	{
12236 		switch (stage)
12237 		{
12238 		case Utils::Shader::FRAGMENT:
12239 			source = fs;
12240 			break;
12241 		case Utils::Shader::GEOMETRY:
12242 			source = gs;
12243 			break;
12244 		case Utils::Shader::TESS_CTRL:
12245 			source = tcs;
12246 			break;
12247 		case Utils::Shader::TESS_EVAL:
12248 			source = tes;
12249 			break;
12250 		case Utils::Shader::VERTEX:
12251 			source = vs;
12252 			break;
12253 		default:
12254 			TCU_FAIL("Invalid enum");
12255 		}
12256 	}
12257 
12258 	return source;
12259 }
12260 
12261 /** Checks if stage is supported
12262  *
12263  * @param stage Shader stage
12264  *
12265  * @return true if supported, false otherwise
12266  **/
12267 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage)
12268 {
12269 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
12270 	GLint			 max_supported_buffers = 0;
12271 	GLenum			 pname				   = 0;
12272 
12273 	switch (stage)
12274 	{
12275 	case Utils::Shader::COMPUTE:
12276 		pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
12277 		break;
12278 	case Utils::Shader::FRAGMENT:
12279 		pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
12280 		break;
12281 	case Utils::Shader::GEOMETRY:
12282 		pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
12283 		break;
12284 	case Utils::Shader::TESS_CTRL:
12285 		pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
12286 		break;
12287 	case Utils::Shader::TESS_EVAL:
12288 		pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
12289 		break;
12290 	case Utils::Shader::VERTEX:
12291 		pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
12292 		break;
12293 	default:
12294 		TCU_FAIL("Invalid enum");
12295 	}
12296 
12297 	gl.getIntegerv(pname, &max_supported_buffers);
12298 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12299 
12300 	return 1 <= max_supported_buffers;
12301 }
12302 
12303 /** Constructor
12304  *
12305  * @param context Test framework context
12306  **/
12307 SSBAlignmentTest::SSBAlignmentTest(deqp::Context& context)
12308 	: TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer")
12309 {
12310 }
12311 
12312 /** Get interface of program
12313  *
12314  * @param ignored
12315  * @param program_interface Interface of program
12316  * @param varying_passthrough Collection of connections between in and out variables
12317  **/
12318 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface& program_interface,
12319 										   Utils::VaryingPassthrough& varying_passthrough)
12320 {
12321 	static const Utils::Type vec4 = Utils::Type::vec4;
12322 
12323 #if WRKARD_UNIFORMBLOCKALIGNMENT
12324 
12325 	static const GLuint block_align = 16;
12326 
12327 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12328 
12329 	static const GLuint block_align = 64;
12330 
12331 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12332 
12333 	static const GLuint fifth_align = 16;
12334 	static const GLuint vec4_stride = 16;
12335 	static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
12336 
12337 	const GLuint first_offset  = 0;																		/* vec4 at 0 */
12338 	const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
12339 	const GLuint third_offset =
12340 		Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
12341 	const GLuint fourth_offset =
12342 		Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
12343 	const GLuint fifth_offset =
12344 		Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */
12345 	const GLuint sixth_offset =
12346 		Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
12347 
12348 	Utils::Interface* structure = program_interface.Structure("Data");
12349 
12350 	structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12351 					  false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
12352 
12353 	structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
12354 					  false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
12355 					  Utils::Type::vec4.GetSize() /* offset */);
12356 
12357 	/* Prepare Block */
12358 	Utils::Interface* vs_buf_Block = program_interface.Block("vs_buf_Block");
12359 
12360 	vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12361 						 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
12362 
12363 	vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12364 						 0 /* n_array_elements */, data_stride, second_offset);
12365 
12366 	vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12367 						 2 /* n_array_elements */, data_stride, third_offset);
12368 
12369 	vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
12370 						 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
12371 
12372 	vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4,
12373 						 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
12374 
12375 	vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12376 						 0 /* n_array_elements */, data_stride, sixth_offset);
12377 
12378 	const GLuint stride = calculateStride(*vs_buf_Block);
12379 	m_data.resize(stride);
12380 	generateData(*vs_buf_Block, 0, m_data);
12381 
12382 	Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12383 
12384 /* Add uniform BLOCK */
12385 #if WRKARD_UNIFORMBLOCKALIGNMENT
12386 	vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0,
12387 			  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12388 #else  /* WRKARD_UNIFORMBLOCKALIGNMENT */
12389 	vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0,
12390 			  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12391 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12392 
12393 	program_interface.CloneVertexInterface(varying_passthrough);
12394 }
12395 
12396 /** Selects if "draw" stages are relevant for test
12397  *
12398  * @param ignored
12399  *
12400  * @return true if all stages support shader storage buffers, false otherwise
12401  **/
12402 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */)
12403 {
12404 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
12405 	GLint			 gs_supported_buffers  = 0;
12406 	GLint			 tcs_supported_buffers = 0;
12407 	GLint			 tes_supported_buffers = 0;
12408 	GLint			 vs_supported_buffers  = 0;
12409 
12410 	gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
12411 	gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
12412 	gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
12413 	gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
12414 
12415 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12416 
12417 	return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
12418 			(1 <= vs_supported_buffers));
12419 }
12420 
12421 /** Constructor
12422  *
12423  * @param context Test framework context
12424  **/
12425 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context)
12426 	: TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected")
12427 {
12428 }
12429 
12430 /** Constructor
12431  *
12432  * @param context          Test context
12433  * @param test_name        Name of test
12434  * @param test_description Description of test
12435  **/
12436 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context, const glw::GLchar* test_name,
12437 										   const glw::GLchar* test_description)
12438 	: TextureTestBase(context, test_name, test_description)
12439 {
12440 }
12441 
12442 /** Get interface of program
12443  *
12444  * @param test_case_index     Test case
12445  * @param program_interface   Interface of program
12446  * @param varying_passthrough Collection of connections between in and out variables
12447  **/
12448 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
12449 											   Utils::VaryingPassthrough& varying_passthrough)
12450 {
12451 	const Utils::Type type = getType(test_case_index);
12452 
12453 	m_first_data = type.GenerateDataPacked();
12454 	m_last_data  = type.GenerateDataPacked();
12455 
12456 	prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough);
12457 	prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough);
12458 	prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough);
12459 	prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough);
12460 	prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough);
12461 }
12462 
12463 /** Get type name
12464  *
12465  * @param test_case_index Index of test case
12466  *
12467  * @return Name of type test in test_case_index
12468  **/
12469 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12470 {
12471 	return getTypeName(test_case_index);
12472 }
12473 
12474 /** Returns number of types to test
12475  *
12476  * @return Number of types, 34
12477  **/
12478 glw::GLuint VaryingLocationsTest::getTestCaseNumber()
12479 {
12480 	return getTypesNumber();
12481 }
12482 
12483 /** Selects if "compute" stage is relevant for test
12484  *
12485  * @param ignored
12486  *
12487  * @return false
12488  **/
12489 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12490 {
12491 	return false;
12492 }
12493 
12494 /**
12495  *
12496  *
12497  **/
12498 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc)
12499 {
12500 	GLchar		buffer[16];
12501 	std::string globals = "const uint first_input_location  = 0u;\n"
12502 						  "const uint first_output_location = 0u;\n"
12503 						  "const uint last_input_location   = LAST_INPUTu;\n"
12504 						  "const uint last_output_location  = LAST_OUTPUTu;\n";
12505 	size_t position = 100; /* Skip first part */
12506 
12507 	sprintf(buffer, "%d", last_in_loc);
12508 	Utils::replaceToken("LAST_INPUT", position, buffer, globals);
12509 
12510 	sprintf(buffer, "%d", last_out_loc);
12511 	Utils::replaceToken("LAST_OUTPUT", position, buffer, globals);
12512 
12513 	return globals;
12514 }
12515 
12516 /**
12517  *
12518  **/
12519 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12520 											  Utils::ProgramInterface&   program_interface,
12521 											  Utils::VaryingPassthrough& varying_passthrough)
12522 {
12523 	const GLuint array_length  = 1;
12524 	const GLuint first_in_loc  = 0;
12525 	const GLuint first_out_loc = 0;
12526 	const GLuint last_in_loc   = getLastInputLocation(stage, type, array_length, false);
12527 	size_t		 position	  = 0;
12528 
12529 	const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12530 
12531 	const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12532 
12533 	const GLchar* qual_first_in  = "layout (location = first_input_location)";
12534 	const GLchar* qual_first_out = "layout (location = first_output_location)";
12535 	const GLchar* qual_last_in   = "layout (location = last_input_location)";
12536 	const GLchar* qual_last_out  = "layout (location = last_output_location)";
12537 
12538 	Utils::ShaderInterface& si		  = program_interface.GetShaderInterface(stage);
12539 	const GLuint			type_size = type.GetSize();
12540 
12541 	std::string first_in_name  = "PREFIXfirst";
12542 	std::string first_out_name = "PREFIXfirst";
12543 	std::string last_in_name   = "PREFIXlast";
12544 	std::string last_out_name  = "PREFIXlast";
12545 
12546 	Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12547 	position = 0;
12548 	Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12549 	position = 0;
12550 	Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12551 	position = 0;
12552 	Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12553 
12554 	if (Utils::Shader::FRAGMENT == stage)
12555 	{
12556 		qual_first_in = "layout (location = first_input_location) flat";
12557 		qual_last_in  = "layout (location = last_input_location)  flat";
12558 	}
12559 	if (Utils::Shader::GEOMETRY == stage)
12560 	{
12561 		qual_first_out = "layout (location = first_output_location) flat";
12562 		qual_last_out  = "layout (location = last_output_location)  flat";
12563 	}
12564 
12565 	Utils::Variable* first_in = si.Input(
12566 		first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12567 		first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12568 		0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12569 
12570 	Utils::Variable* last_in =
12571 		si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12572 				 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12573 				 0u /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12574 				 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12575 
12576 	if (Utils::Shader::FRAGMENT != stage)
12577 	{
12578 		const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length, false);
12579 
12580 		Utils::Variable* first_out =
12581 			si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12582 					  first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12583 					  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */,
12584 					  m_first_data.size() /* data_size */);
12585 
12586 		Utils::Variable* last_out = si.Output(
12587 			last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12588 			last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12589 			0u /* stride */, 0u /* offset */, (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12590 
12591 		si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12592 
12593 		varying_passthrough.Add(stage, first_in, first_out);
12594 		varying_passthrough.Add(stage, last_in, last_out);
12595 	}
12596 	else
12597 	{
12598 		/* No outputs for fragment shader, so last_output_location can be 0 */
12599 		si.m_globals = prepareGlobals(last_in_loc, 0);
12600 	}
12601 }
12602 
12603 /** This test should be run with separable programs
12604  *
12605  * @param ignored
12606  *
12607  * @return true
12608  **/
12609 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12610 {
12611 	return false;
12612 }
12613 
12614 /* Constants used by VertexAttribLocationsTest */
12615 const GLuint VertexAttribLocationsTest::m_base_vertex   = 4;
12616 const GLuint VertexAttribLocationsTest::m_base_instance = 2;
12617 const GLuint VertexAttribLocationsTest::m_loc_vertex	= 2;
12618 const GLuint VertexAttribLocationsTest::m_loc_instance  = 5;
12619 const GLuint VertexAttribLocationsTest::m_n_instances   = 4;
12620 
12621 /** Constructor
12622  *
12623  * @param context Test framework context
12624  **/
12625 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context& context)
12626 	: TextureTestBase(context, "vertex_attrib_locations",
12627 					  "Test verifies that attribute locations are respected by drawing operations")
12628 {
12629 }
12630 
12631 /** Execute proper draw command for test case
12632  *
12633  * @param test_case_index Index of test case
12634  **/
12635 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index)
12636 {
12637 	const Functions& gl = m_context.getRenderContext().getFunctions();
12638 
12639 	switch (test_case_index)
12640 	{
12641 	case DRAWARRAYS:
12642 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
12643 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
12644 		break;
12645 	case DRAWARRAYSINSTANCED:
12646 		gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances);
12647 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced");
12648 		break;
12649 	case DRAWELEMENTS:
12650 		gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL);
12651 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
12652 		break;
12653 	case DRAWELEMENTSBASEVERTEX:
12654 		gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_base_vertex);
12655 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex");
12656 		break;
12657 	case DRAWELEMENTSINSTANCED:
12658 		gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances);
12659 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced");
12660 		break;
12661 	case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12662 		gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12663 											 m_base_instance);
12664 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance");
12665 		break;
12666 	case DRAWELEMENTSINSTANCEDBASEVERTEX:
12667 		gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12668 										   m_base_vertex);
12669 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex");
12670 		break;
12671 	case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12672 		gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL,
12673 													   m_n_instances, m_base_vertex, m_base_instance);
12674 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance");
12675 		break;
12676 	default:
12677 		TCU_FAIL("Invalid enum");
12678 	}
12679 }
12680 
12681 /** Get interface of program
12682  *
12683  * @param ignored
12684  * @param program_interface   Interface of program
12685  * @param ignored
12686  **/
12687 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */,
12688 													Utils::ProgramInterface& program_interface,
12689 													Utils::VaryingPassthrough& /* varying_passthrough */)
12690 {
12691 	Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12692 
12693 	/* Globals */
12694 	si.m_globals = "const uint vertex_index_location   = 2;\n"
12695 				   "const uint instance_index_location = 5;\n";
12696 
12697 	/* Attributes */
12698 	si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */,
12699 			 0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */,
12700 			 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */,
12701 			 (GLvoid*)0 /* data */, 0 /* data_size */);
12702 	si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */,
12703 			 0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */,
12704 			 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */,
12705 			 (GLvoid*)0 /* data */, 0 /* data_size */);
12706 }
12707 
12708 /** Get name of test case
12709  *
12710  * @param test_case_index Index of test case
12711  *
12712  * @return Name of test case
12713  **/
12714 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12715 {
12716 	std::string result;
12717 
12718 	switch (test_case_index)
12719 	{
12720 	case DRAWARRAYS:
12721 		result = "DrawArrays";
12722 		break;
12723 	case DRAWARRAYSINSTANCED:
12724 		result = "DrawArraysInstanced";
12725 		break;
12726 	case DRAWELEMENTS:
12727 		result = "DrawElements";
12728 		break;
12729 	case DRAWELEMENTSBASEVERTEX:
12730 		result = "DrawElementsBaseVertex";
12731 		break;
12732 	case DRAWELEMENTSINSTANCED:
12733 		result = "DrawElementsInstanced";
12734 		break;
12735 	case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12736 		result = "DrawElementsInstancedBaseInstance";
12737 		break;
12738 	case DRAWELEMENTSINSTANCEDBASEVERTEX:
12739 		result = "DrawElementsInstancedBaseVertex";
12740 		break;
12741 	case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12742 		result = "DrawElementsInstancedBaseVertexBaseInstance";
12743 		break;
12744 	default:
12745 		TCU_FAIL("Invalid enum");
12746 	}
12747 
12748 	return result;
12749 }
12750 
12751 /** Get number of test cases
12752  *
12753  * @return Number of test cases
12754  **/
12755 GLuint VertexAttribLocationsTest::getTestCaseNumber()
12756 {
12757 	return TESTCASES_MAX;
12758 }
12759 
12760 /** Prepare code snippet that will verify in and uniform variables
12761  *
12762  * @param ignored
12763  * @param ignored
12764  * @param stage   Shader stage
12765  *
12766  * @return Code that verify variables
12767  **/
12768 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */,
12769 															  Utils::ProgramInterface& /* program_interface */,
12770 															  Utils::Shader::STAGES stage)
12771 {
12772 	std::string verification;
12773 
12774 	if (Utils::Shader::VERTEX == stage)
12775 	{
12776 
12777 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE
12778 
12779 		verification = "if (gl_InstanceID != instance_index)\n"
12780 					   "    {\n"
12781 					   "        result = 12u;\n"
12782 					   "    }\n"
12783 					   "    else if (gl_VertexID != vertex_index)\n"
12784 					   "    {\n"
12785 					   "        result = 11u;\n"
12786 					   "    }\n";
12787 
12788 #else
12789 
12790 		verification = "if ((gl_VertexID   != vertex_index)  ||\n"
12791 					   "        (gl_InstanceID != instance_index) )\n"
12792 					   "    {\n"
12793 					   "        result = 0u;\n"
12794 					   "    }\n";
12795 
12796 #endif
12797 	}
12798 	else
12799 	{
12800 		verification = "";
12801 	}
12802 
12803 	return verification;
12804 }
12805 
12806 /** Selects if "compute" stage is relevant for test
12807  *
12808  * @param ignored
12809  *
12810  * @return false
12811  **/
12812 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12813 {
12814 	return false;
12815 }
12816 
12817 /** Prepare attributes, vertex array object and array buffer
12818  *
12819  * @param ignored
12820  * @param ignored Interface of program
12821  * @param buffer  Array buffer
12822  * @param vao     Vertex array object
12823  **/
12824 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */,
12825 												  Utils::ProgramInterface& /* program_interface */,
12826 												  Utils::Buffer& buffer, Utils::VertexArray& vao)
12827 {
12828 	static const GLuint vertex_index_data[8]   = { 0, 1, 2, 3, 4, 5, 6, 7 };
12829 	static const GLuint instance_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12830 
12831 	std::vector<GLuint> buffer_data;
12832 	buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */
12833 
12834 	GLubyte* ptr = (GLubyte*)&buffer_data[0];
12835 
12836 	/*
12837 	 When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on,
12838 	 So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER
12839 	 */
12840 	if (test_case_index >= 2)
12841 	{
12842 		buffer.m_buffer = Utils::Buffer::Element;
12843 	}
12844 	vao.Bind();
12845 	buffer.Bind();
12846 
12847 	vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */,
12848 				  0 /* stride */, 0 /* offset */);
12849 
12850 	vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */,
12851 				  false /* normalized */, 0 /* stride */, (GLvoid*)sizeof(vertex_index_data) /* offset */);
12852 	// when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance
12853 	// the instancecount is 4, the baseinstance is 2, the divisor should be set 2
12854 	bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE ||
12855 							test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE);
12856 	vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */,
12857 				isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */);
12858 
12859 	memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data));
12860 	memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data));
12861 
12862 	buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr);
12863 }
12864 
12865 /** This test should be run with separable programs
12866  *
12867  * @param ignored
12868  *
12869  * @return true
12870  **/
12871 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12872 {
12873 	return false;
12874 }
12875 
12876 /** Constructor
12877  *
12878  * @param context Test framework context
12879  **/
12880 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context& context)
12881 	: VaryingLocationsTest(context, "varying_array_locations",
12882 						   "Test verifies that input and output locations are respected for arrays")
12883 {
12884 }
12885 
12886 /**
12887  *
12888  **/
12889 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12890 												   Utils::ProgramInterface&   program_interface,
12891 												   Utils::VaryingPassthrough& varying_passthrough)
12892 {
12893 	const GLuint array_length  = 1u;
12894 	const GLuint first_in_loc  = 0;
12895 	const GLuint first_out_loc = 0;
12896 	const GLuint last_in_loc   = getLastInputLocation(stage, type, array_length, false);
12897 	size_t		 position	  = 0;
12898 
12899 	const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12900 
12901 	const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12902 
12903 	const GLchar* qual_first_in  = "layout (location = first_input_location)";
12904 	const GLchar* qual_first_out = "layout (location = first_output_location)";
12905 	const GLchar* qual_last_in   = "layout (location = last_input_location)";
12906 	const GLchar* qual_last_out  = "layout (location = last_output_location)";
12907 
12908 	Utils::ShaderInterface& si		  = program_interface.GetShaderInterface(stage);
12909 	const GLuint			type_size = type.GetSize();
12910 
12911 	std::string first_in_name  = "PREFIXfirst";
12912 	std::string first_out_name = "PREFIXfirst";
12913 	std::string last_in_name   = "PREFIXlast";
12914 	std::string last_out_name  = "PREFIXlast";
12915 
12916 	Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12917 	position = 0;
12918 	Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12919 	position = 0;
12920 	Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12921 	position = 0;
12922 	Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12923 
12924 	if (Utils::Shader::FRAGMENT == stage)
12925 	{
12926 		qual_first_in = "layout (location = first_input_location) flat";
12927 		qual_last_in  = "layout (location = last_input_location)  flat";
12928 	}
12929 	if (Utils::Shader::GEOMETRY == stage)
12930 	{
12931 		qual_first_out = "layout (location = first_output_location) flat";
12932 		qual_last_out  = "layout (location = last_output_location)  flat";
12933 	}
12934 
12935 	Utils::Variable* first_in =
12936 		si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12937 				 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12938 				 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12939 				 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12940 
12941 	Utils::Variable* last_in =
12942 		si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12943 				 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12944 				 array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12945 				 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12946 
12947 	if (Utils::Shader::FRAGMENT != stage)
12948 	{
12949 		const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length, false);
12950 
12951 		Utils::Variable* first_out =
12952 			si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12953 					  first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12954 					  array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12955 					  (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12956 
12957 		Utils::Variable* last_out =
12958 			si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12959 					  last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12960 					  array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12961 					  (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12962 
12963 		si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12964 
12965 		varying_passthrough.Add(stage, first_in, first_out);
12966 		varying_passthrough.Add(stage, last_in, last_out);
12967 	}
12968 	else
12969 	{
12970 		/* No outputs for fragment shader, so last_output_location can be 0 */
12971 		si.m_globals = prepareGlobals(last_in_loc, 0);
12972 	}
12973 }
12974 
12975 /** Constructor
12976  *
12977  * @param context Test framework context
12978  **/
12979 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context& context)
12980 	: TextureTestBase(context, "varying_structure_locations",
12981 					  "Test verifies that locations are respected when structures are used as in and out ")
12982 {
12983 }
12984 
12985 /** Prepare code snippet that will pass in variables to out variables
12986  *
12987  * @param ignored
12988  * @param varying_passthrough Collection of connections between in and out variables
12989  * @param stage               Shader stage
12990  *
12991  * @return Code that pass in variables to next stage
12992  **/
12993 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */,
12994 														  Utils::VaryingPassthrough& varying_passthrough,
12995 														  Utils::Shader::STAGES		 stage)
12996 {
12997 	std::string result;
12998 
12999 	if (Utils::Shader::VERTEX != stage)
13000 	{
13001 		result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13002 	}
13003 	else
13004 	{
13005 		result = "    vs_tcs_output[0].single   = vs_in_single[0];\n"
13006 				 "    vs_tcs_output[0].array[0] = vs_in_array[0];\n";
13007 	}
13008 
13009 	return result;
13010 }
13011 
13012 /** Get interface of program
13013  *
13014  * @param test_case_index     Test case
13015  * @param program_interface   Interface of program
13016  * @param varying_passthrough Collection of connections between in and out variables
13017  **/
13018 void VaryingStructureLocationsTest::getProgramInterface(GLuint					   test_case_index,
13019 														Utils::ProgramInterface&   program_interface,
13020 														Utils::VaryingPassthrough& varying_passthrough)
13021 {
13022 	Utils::ShaderInterface& si   = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13023 	const Utils::Type		type = getType(test_case_index);
13024 
13025 	/* Prepare data */
13026 	// We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct
13027 	m_single_data = type.GenerateDataPacked();
13028 	m_array_data  = type.GenerateDataPacked();
13029 
13030 	m_data.resize(m_single_data.size() + m_array_data.size());
13031 	GLubyte* ptr = (GLubyte*)&m_data[0];
13032 	memcpy(ptr, &m_single_data[0], m_single_data.size());
13033 	memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size());
13034 
13035 	Utils::Interface* structure = program_interface.Structure("Data");
13036 
13037 	structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */,
13038 					  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */);
13039 
13040 	// the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed.
13041 	structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type,
13042 					  false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */);
13043 
13044 	si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */,
13045 			 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_single_data[0] /* data */,
13046 			 m_single_data.size() /* data_size */);
13047 
13048 	si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */,
13049 			 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */,
13050 			 (GLvoid*)&m_array_data[0] /* data */, m_array_data.size() /* data_size */);
13051 
13052 	si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure,
13053 			  1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
13054 			  m_data.size() /* data_size */);
13055 
13056 	program_interface.CloneVertexInterface(varying_passthrough);
13057 }
13058 
13059 /** Get type name
13060  *
13061  * @param test_case_index Index of test case
13062  *
13063  * @return Name of type test in test_case_index
13064  **/
13065 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index)
13066 {
13067 	return getTypeName(test_case_index);
13068 }
13069 
13070 /** Returns number of types to test
13071  *
13072  * @return Number of types, 34
13073  **/
13074 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber()
13075 {
13076 	return getTypesNumber();
13077 }
13078 
13079 /** Selects if "compute" stage is relevant for test
13080  *
13081  * @param ignored
13082  *
13083  * @return false
13084  **/
13085 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13086 {
13087 	return false;
13088 }
13089 
13090 /** This test should be run with separable programs
13091  *
13092  * @param ignored
13093  *
13094  * @return true
13095  **/
13096 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13097 {
13098 	return false;
13099 }
13100 
13101 /** Constructor
13102  *
13103  * @param context          Test context
13104  * @param test_name        Name of test
13105  * @param test_description Description of test
13106  **/
13107 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context& context)
13108 	: NegativeTestBase(context, "varying_structure_member_location",
13109 					   "Test verifies that compiler does not allow location qualifier on member of structure")
13110 {
13111 }
13112 
13113 /** Source for given test case and stage
13114  *
13115  * @param test_case_index Index of test case
13116  * @param stage           Shader stage
13117  *
13118  * @return Shader source
13119  **/
13120 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13121 {
13122 	static const GLchar* struct_definition = "struct Data {\n"
13123 											 "    vec4 gohan;\n"
13124 #if DEBUG_NEG_REMOVE_ERROR
13125 											 "    /* layout (location = 4) */ vec4 goten;\n"
13126 #else
13127 											 "    layout (location = 4) vec4 goten;\n"
13128 #endif /* DEBUG_NEG_REMOVE_ERROR */
13129 											 "};\n";
13130 	static const GLchar* input_use  = "    result += data.gohan + data.goten;\n";
13131 	static const GLchar* input_var  = "in Data dataARRAY;\n";
13132 	static const GLchar* output_var = "out Data dataARRAY;\n";
13133 	static const GLchar* output_use = "    dataINDEX.gohan = result / 2;\n"
13134 									  "    dataINDEX.goten = result / 4 - dataINDEX.gohan;\n";
13135 	static const GLchar* fs = "#version 430 core\n"
13136 							  "#extension GL_ARB_enhanced_layouts : require\n"
13137 							  "\n"
13138 							  "in  vec4 gs_fs;\n"
13139 							  "out vec4 fs_out;\n"
13140 							  "\n"
13141 							  "void main()\n"
13142 							  "{\n"
13143 							  "    fs_out = gs_fs;\n"
13144 							  "}\n"
13145 							  "\n";
13146 	static const GLchar* fs_tested = "#version 430 core\n"
13147 									 "#extension GL_ARB_enhanced_layouts : require\n"
13148 									 "\n"
13149 									 "STRUCT_DEFINITION"
13150 									 "\n"
13151 									 "VARIABLE_DEFINITION"
13152 									 "\n"
13153 									 "in  vec4 gs_fs;\n"
13154 									 "out vec4 fs_out;\n"
13155 									 "\n"
13156 									 "void main()\n"
13157 									 "{\n"
13158 									 "    vec4 result = gs_fs;\n"
13159 									 "\n"
13160 									 "VARIABLE_USE"
13161 									 "\n"
13162 									 "    fs_out += result;\n"
13163 									 "}\n"
13164 									 "\n";
13165 	static const GLchar* gs = "#version 430 core\n"
13166 							  "#extension GL_ARB_enhanced_layouts : require\n"
13167 							  "\n"
13168 							  "layout(points)                           in;\n"
13169 							  "layout(triangle_strip, max_vertices = 4) out;\n"
13170 							  "\n"
13171 							  "in  vec4 tes_gs[];\n"
13172 							  "out vec4 gs_fs;\n"
13173 							  "\n"
13174 							  "void main()\n"
13175 							  "{\n"
13176 							  "    gs_fs = tes_gs[0];\n"
13177 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13178 							  "    EmitVertex();\n"
13179 							  "    gs_fs = tes_gs[0];\n"
13180 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13181 							  "    EmitVertex();\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 							  "}\n"
13189 							  "\n";
13190 	static const GLchar* gs_tested = "#version 430 core\n"
13191 									 "#extension GL_ARB_enhanced_layouts : require\n"
13192 									 "\n"
13193 									 "layout(points)                           in;\n"
13194 									 "layout(triangle_strip, max_vertices = 4) out;\n"
13195 									 "\n"
13196 									 "STRUCT_DEFINITION"
13197 									 "\n"
13198 									 "VARIABLE_DEFINITION"
13199 									 "\n"
13200 									 "in  vec4 tes_gs[];\n"
13201 									 "out vec4 gs_fs;\n"
13202 									 "\n"
13203 									 "void main()\n"
13204 									 "{\n"
13205 									 "    vec4 result = tes_gs[0];\n"
13206 									 "\n"
13207 									 "VARIABLE_USE"
13208 									 "\n"
13209 									 "    gs_fs = result;\n"
13210 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13211 									 "    EmitVertex();\n"
13212 									 "    gs_fs = result;\n"
13213 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13214 									 "    EmitVertex();\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 									 "}\n"
13222 									 "\n";
13223 	static const GLchar* tcs = "#version 430 core\n"
13224 							   "#extension GL_ARB_enhanced_layouts : require\n"
13225 							   "\n"
13226 							   "layout(vertices = 1) out;\n"
13227 							   "\n"
13228 							   "in  vec4 vs_tcs[];\n"
13229 							   "out vec4 tcs_tes[];\n"
13230 							   "\n"
13231 							   "void main()\n"
13232 							   "{\n"
13233 							   "\n"
13234 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13235 							   "\n"
13236 							   "    gl_TessLevelOuter[0] = 1.0;\n"
13237 							   "    gl_TessLevelOuter[1] = 1.0;\n"
13238 							   "    gl_TessLevelOuter[2] = 1.0;\n"
13239 							   "    gl_TessLevelOuter[3] = 1.0;\n"
13240 							   "    gl_TessLevelInner[0] = 1.0;\n"
13241 							   "    gl_TessLevelInner[1] = 1.0;\n"
13242 							   "}\n"
13243 							   "\n";
13244 	static const GLchar* tcs_tested = "#version 430 core\n"
13245 									  "#extension GL_ARB_enhanced_layouts : require\n"
13246 									  "\n"
13247 									  "layout(vertices = 1) out;\n"
13248 									  "\n"
13249 									  "STRUCT_DEFINITION"
13250 									  "\n"
13251 									  "VARIABLE_DEFINITION"
13252 									  "\n"
13253 									  "in  vec4 vs_tcs[];\n"
13254 									  "out vec4 tcs_tes[];\n"
13255 									  "\n"
13256 									  "void main()\n"
13257 									  "{\n"
13258 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
13259 									  "\n"
13260 									  "VARIABLE_USE"
13261 									  "\n"
13262 									  "    tcs_tes[gl_InvocationID] = result;\n"
13263 									  "\n"
13264 									  "    gl_TessLevelOuter[0] = 1.0;\n"
13265 									  "    gl_TessLevelOuter[1] = 1.0;\n"
13266 									  "    gl_TessLevelOuter[2] = 1.0;\n"
13267 									  "    gl_TessLevelOuter[3] = 1.0;\n"
13268 									  "    gl_TessLevelInner[0] = 1.0;\n"
13269 									  "    gl_TessLevelInner[1] = 1.0;\n"
13270 									  "}\n"
13271 									  "\n";
13272 	static const GLchar* tes = "#version 430 core\n"
13273 							   "#extension GL_ARB_enhanced_layouts : require\n"
13274 							   "\n"
13275 							   "layout(isolines, point_mode) in;\n"
13276 							   "\n"
13277 							   "in  vec4 tcs_tes[];\n"
13278 							   "out vec4 tes_gs;\n"
13279 							   "\n"
13280 							   "void main()\n"
13281 							   "{\n"
13282 							   "    tes_gs = tcs_tes[0];\n"
13283 							   "}\n"
13284 							   "\n";
13285 	static const GLchar* tes_tested = "#version 430 core\n"
13286 									  "#extension GL_ARB_enhanced_layouts : require\n"
13287 									  "\n"
13288 									  "layout(isolines, point_mode) in;\n"
13289 									  "\n"
13290 									  "STRUCT_DEFINITION"
13291 									  "\n"
13292 									  "VARIABLE_DEFINITION"
13293 									  "\n"
13294 									  "in  vec4 tcs_tes[];\n"
13295 									  "out vec4 tes_gs;\n"
13296 									  "\n"
13297 									  "void main()\n"
13298 									  "{\n"
13299 									  "    vec4 result = tcs_tes[0];\n"
13300 									  "\n"
13301 									  "VARIABLE_USE"
13302 									  "\n"
13303 									  "    tes_gs += result;\n"
13304 									  "}\n"
13305 									  "\n";
13306 	static const GLchar* vs = "#version 430 core\n"
13307 							  "#extension GL_ARB_enhanced_layouts : require\n"
13308 							  "\n"
13309 							  "in  vec4 in_vs;\n"
13310 							  "out vec4 vs_tcs;\n"
13311 							  "\n"
13312 							  "void main()\n"
13313 							  "{\n"
13314 							  "    vs_tcs = in_vs;\n"
13315 							  "}\n"
13316 							  "\n";
13317 	static const GLchar* vs_tested = "#version 430 core\n"
13318 									 "#extension GL_ARB_enhanced_layouts : require\n"
13319 									 "\n"
13320 									 "STRUCT_DEFINITION"
13321 									 "\n"
13322 									 "VARIABLE_DEFINITION"
13323 									 "\n"
13324 									 "in  vec4 in_vs;\n"
13325 									 "out vec4 vs_tcs;\n"
13326 									 "\n"
13327 									 "void main()\n"
13328 									 "{\n"
13329 									 "    vec4 result = in_vs;\n"
13330 									 "\n"
13331 									 "VARIABLE_USE"
13332 									 "\n"
13333 									 "    vs_tcs += result;\n"
13334 									 "}\n"
13335 									 "\n";
13336 
13337 	std::string   source;
13338 	testCase&	 test_case		 = m_test_cases[test_case_index];
13339 	const GLchar* var_definition  = input_var;
13340 	const GLchar* var_use		  = Utils::Shader::VERTEX == test_case.m_stage ? input_use : "\n";
13341 	const GLchar* array			  = "";
13342 	const GLchar* index			  = "";
13343 
13344 	if (!test_case.m_is_input)
13345 	{
13346 		var_definition = output_var;
13347 		var_use		   = output_use;
13348 	}
13349 
13350 	if (test_case.m_stage == stage)
13351 	{
13352 		size_t position = 0;
13353 		size_t temp		= 0;
13354 
13355 		switch (stage)
13356 		{
13357 		case Utils::Shader::FRAGMENT:
13358 			source = fs_tested;
13359 			break;
13360 		case Utils::Shader::GEOMETRY:
13361 			source = gs_tested;
13362 			array  = test_case.m_is_input ? "[]" : "";
13363 			index  = test_case.m_is_input ? "[0]" : "";
13364 			break;
13365 		case Utils::Shader::TESS_CTRL:
13366 			source = tcs_tested;
13367 			array  = "[]";
13368 			index  = "[gl_InvocationID]";
13369 			break;
13370 		case Utils::Shader::TESS_EVAL:
13371 			source = tes_tested;
13372 			array  = test_case.m_is_input ? "[]" : "";
13373 			index  = test_case.m_is_input ? "[0]" : "";
13374 			break;
13375 		case Utils::Shader::VERTEX:
13376 			source = vs_tested;
13377 			break;
13378 		default:
13379 			TCU_FAIL("Invalid enum");
13380 		}
13381 
13382 		Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source);
13383 		temp = position;
13384 		Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source);
13385 		position = temp;
13386 		Utils::replaceToken("ARRAY", position, array, source);
13387 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13388 
13389 		Utils::replaceAllTokens("INDEX", index, source);
13390 	}
13391 	else
13392 	{
13393 		switch (stage)
13394 		{
13395 		case Utils::Shader::FRAGMENT:
13396 			source = fs;
13397 			break;
13398 		case Utils::Shader::GEOMETRY:
13399 			source = gs;
13400 			break;
13401 		case Utils::Shader::TESS_CTRL:
13402 			source = tcs;
13403 			break;
13404 		case Utils::Shader::TESS_EVAL:
13405 			source = tes;
13406 			break;
13407 		case Utils::Shader::VERTEX:
13408 			source = vs;
13409 			break;
13410 		default:
13411 			TCU_FAIL("Invalid enum");
13412 		}
13413 	}
13414 
13415 	return source;
13416 }
13417 
13418 /** Get description of test case
13419  *
13420  * @param test_case_index Index of test case
13421  *
13422  * @return Test case description
13423  **/
13424 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index)
13425 {
13426 	std::stringstream stream;
13427 	testCase&		  test_case = m_test_cases[test_case_index];
13428 
13429 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13430 
13431 	if (true == test_case.m_is_input)
13432 	{
13433 		stream << "input";
13434 	}
13435 	else
13436 	{
13437 		stream << "output";
13438 	}
13439 
13440 	return stream.str();
13441 }
13442 
13443 /** Get number of test cases
13444  *
13445  * @return Number of test cases
13446  **/
13447 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber()
13448 {
13449 	return static_cast<GLuint>(m_test_cases.size());
13450 }
13451 
13452 /** Selects if "compute" stage is relevant for test
13453  *
13454  * @param ignored
13455  *
13456  * @return false
13457  **/
13458 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */)
13459 {
13460 	return false;
13461 }
13462 
13463 /** Prepare all test cases
13464  *
13465  **/
13466 void VaryingStructureMemberLocationTest::testInit()
13467 {
13468 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13469 	{
13470 		if (Utils::Shader::COMPUTE == stage)
13471 		{
13472 			continue;
13473 		}
13474 
13475 		testCase test_case_in  = { true, (Utils::Shader::STAGES)stage };
13476 		testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
13477 
13478 		/* It is a compile-time error to declare a struct as a VS input */
13479 		if (Utils::Shader::VERTEX != stage)
13480 		{
13481 			m_test_cases.push_back(test_case_in);
13482 		}
13483 
13484 		if (Utils::Shader::FRAGMENT != stage)
13485 		{
13486 			m_test_cases.push_back(test_case_out);
13487 		}
13488 	}
13489 }
13490 
13491 /** Constructor
13492  *
13493  * @param context Test framework context
13494  **/
13495 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context& context)
13496 	: TextureTestBase(context, "varying_block_locations",
13497 					  "Test verifies that locations are respected when blocks are used as in and out ")
13498 {
13499 }
13500 
13501 /** Prepare code snippet that will pass in variables to out variables
13502  *
13503  * @param ignored
13504  * @param varying_passthrough Collection of connections between in and out variables
13505  * @param stage               Shader stage
13506  *
13507  * @return Code that pass in variables to next stage
13508  **/
13509 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */,
13510 													  Utils::VaryingPassthrough& varying_passthrough,
13511 													  Utils::Shader::STAGES		 stage)
13512 {
13513 	std::string result;
13514 
13515 	if (Utils::Shader::VERTEX != stage)
13516 	{
13517 		result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13518 	}
13519 	else
13520 	{
13521 		result = "vs_tcs_block.third  = vs_in_third;\n"
13522 				 "    vs_tcs_block.fourth = vs_in_fourth;\n"
13523 				 "    vs_tcs_block.fifth  = vs_in_fifth;\n";
13524 	}
13525 
13526 	return result;
13527 }
13528 
13529 /** Get interface of program
13530  *
13531  * @param ignored
13532  * @param program_interface   Interface of program
13533  * @param varying_passthrough Collection of connections between in and out variables
13534  **/
13535 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */,
13536 													Utils::ProgramInterface&   program_interface,
13537 													Utils::VaryingPassthrough& varying_passthrough)
13538 {
13539 	Utils::ShaderInterface& si   = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13540 	const Utils::Type		vec4 = Utils::Type::vec4;
13541 
13542 	/* Prepare data */
13543 	m_third_data  = vec4.GenerateData();
13544 	m_fourth_data = vec4.GenerateData();
13545 	m_fifth_data  = vec4.GenerateData();
13546 
13547 	/* Memory layout is different from location layout */
13548 	const GLuint fifth_offset  = 0u;
13549 	const GLuint third_offset  = static_cast<GLuint>(fifth_offset + m_fifth_data.size());
13550 	const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size());
13551 
13552 	m_data.resize(fourth_offset + m_fourth_data.size());
13553 	GLubyte* ptr = (GLubyte*)&m_data[0];
13554 	memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size());
13555 	memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size());
13556 	memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size());
13557 
13558 	Utils::Interface* block = program_interface.Block("vs_tcs_Block");
13559 
13560 	block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */,
13561 				  0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */);
13562 
13563 	block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4,
13564 				  false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */);
13565 
13566 	block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */,
13567 				  0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */);
13568 
13569 	si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block,
13570 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
13571 			  m_data.size() /* data_size */);
13572 
13573 	si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */,
13574 			 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */,
13575 			 (GLvoid*)&m_third_data[0] /* data */, m_third_data.size() /* data_size */);
13576 
13577 	si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */,
13578 			 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */,
13579 			 (GLvoid*)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */);
13580 
13581 	si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */,
13582 			 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */,
13583 			 (GLvoid*)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */);
13584 
13585 	program_interface.CloneVertexInterface(varying_passthrough);
13586 }
13587 
13588 /** Selects if "compute" stage is relevant for test
13589  *
13590  * @param ignored
13591  *
13592  * @return false
13593  **/
13594 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13595 {
13596 	return false;
13597 }
13598 
13599 /** This test should be run with separable programs
13600  *
13601  * @param ignored
13602  *
13603  * @return true
13604  **/
13605 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13606 {
13607 	return false;
13608 }
13609 
13610 /** Constructor
13611  *
13612  * @param context Test framework context
13613  **/
13614 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context& context)
13615 	: NegativeTestBase(
13616 		  context, "varying_block_member_locations",
13617 		  "Test verifies that compilation error is reported when not all members of block are qualified with location")
13618 {
13619 }
13620 
13621 /** Source for given test case and stage
13622  *
13623  * @param test_case_index Index of test case
13624  * @param stage           Shader stage
13625  *
13626  * @return Shader source
13627  **/
13628 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13629 {
13630 	static const GLchar* block_definition_all = "Goku {\n"
13631 												"    layout (location = 2) vec4 gohan;\n"
13632 												"    layout (location = 4) vec4 goten;\n"
13633 												"    layout (location = 6) vec4 chichi;\n"
13634 												"} gokuARRAY;\n";
13635 	static const GLchar* block_definition_one = "Goku {\n"
13636 												"    vec4 gohan;\n"
13637 #if DEBUG_NEG_REMOVE_ERROR
13638 												"    /* layout (location = 4) */ vec4 goten;\n"
13639 #else
13640 												"    layout (location = 4) vec4 goten;\n"
13641 #endif /* DEBUG_NEG_REMOVE_ERROR */
13642 												"    vec4 chichi;\n"
13643 												"} gokuARRAY;\n";
13644 	static const GLchar* input_use  = "    result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n";
13645 	static const GLchar* output_use = "    gokuINDEX.gohan  = result / 2;\n"
13646 									  "    gokuINDEX.goten  = result / 4 - gokuINDEX.gohan;\n"
13647 									  "    gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n";
13648 	static const GLchar* fs = "#version 430 core\n"
13649 							  "#extension GL_ARB_enhanced_layouts : require\n"
13650 							  "\n"
13651 							  "in  vec4 gs_fs;\n"
13652 							  "out vec4 fs_out;\n"
13653 							  "\n"
13654 							  "void main()\n"
13655 							  "{\n"
13656 							  "    fs_out = gs_fs;\n"
13657 							  "}\n"
13658 							  "\n";
13659 	static const GLchar* fs_tested = "#version 430 core\n"
13660 									 "#extension GL_ARB_enhanced_layouts : require\n"
13661 									 "\n"
13662 									 "DIRECTION BLOCK_DEFINITION"
13663 									 "\n"
13664 									 "in  vec4 gs_fs;\n"
13665 									 "out vec4 fs_out;\n"
13666 									 "\n"
13667 									 "void main()\n"
13668 									 "{\n"
13669 									 "    vec4 result = gs_fs;\n"
13670 									 "\n"
13671 									 "VARIABLE_USE"
13672 									 "\n"
13673 									 "    fs_out = result;\n"
13674 									 "}\n"
13675 									 "\n";
13676 	static const GLchar* gs = "#version 430 core\n"
13677 							  "#extension GL_ARB_enhanced_layouts : require\n"
13678 							  "\n"
13679 							  "layout(points)                           in;\n"
13680 							  "layout(triangle_strip, max_vertices = 4) out;\n"
13681 							  "\n"
13682 							  "in  vec4 tes_gs[];\n"
13683 							  "out vec4 gs_fs;\n"
13684 							  "\n"
13685 							  "void main()\n"
13686 							  "{\n"
13687 							  "    gs_fs = tes_gs[0];\n"
13688 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13689 							  "    EmitVertex();\n"
13690 							  "    gs_fs = tes_gs[0];\n"
13691 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13692 							  "    EmitVertex();\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 							  "}\n"
13700 							  "\n";
13701 	static const GLchar* gs_tested = "#version 430 core\n"
13702 									 "#extension GL_ARB_enhanced_layouts : require\n"
13703 									 "\n"
13704 									 "layout(points)                           in;\n"
13705 									 "layout(triangle_strip, max_vertices = 4) out;\n"
13706 									 "\n"
13707 									 "DIRECTION BLOCK_DEFINITION"
13708 									 "\n"
13709 									 "in  vec4 tes_gs[];\n"
13710 									 "out vec4 gs_fs;\n"
13711 									 "\n"
13712 									 "void main()\n"
13713 									 "{\n"
13714 									 "    vec4 result = tes_gs[0];\n"
13715 									 "\n"
13716 									 "VARIABLE_USE"
13717 									 "\n"
13718 									 "    gs_fs = result;\n"
13719 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13720 									 "    EmitVertex();\n"
13721 									 "    gs_fs = result;\n"
13722 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13723 									 "    EmitVertex();\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 									 "}\n"
13731 									 "\n";
13732 	static const GLchar* tcs = "#version 430 core\n"
13733 							   "#extension GL_ARB_enhanced_layouts : require\n"
13734 							   "\n"
13735 							   "layout(vertices = 1) out;\n"
13736 							   "\n"
13737 							   "in  vec4 vs_tcs[];\n"
13738 							   "out vec4 tcs_tes[];\n"
13739 							   "\n"
13740 							   "void main()\n"
13741 							   "{\n"
13742 							   "\n"
13743 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13744 							   "\n"
13745 							   "    gl_TessLevelOuter[0] = 1.0;\n"
13746 							   "    gl_TessLevelOuter[1] = 1.0;\n"
13747 							   "    gl_TessLevelOuter[2] = 1.0;\n"
13748 							   "    gl_TessLevelOuter[3] = 1.0;\n"
13749 							   "    gl_TessLevelInner[0] = 1.0;\n"
13750 							   "    gl_TessLevelInner[1] = 1.0;\n"
13751 							   "}\n"
13752 							   "\n";
13753 	static const GLchar* tcs_tested = "#version 430 core\n"
13754 									  "#extension GL_ARB_enhanced_layouts : require\n"
13755 									  "\n"
13756 									  "layout(vertices = 1) out;\n"
13757 									  "\n"
13758 									  "DIRECTION BLOCK_DEFINITION"
13759 									  "\n"
13760 									  "in  vec4 vs_tcs[];\n"
13761 									  "out vec4 tcs_tes[];\n"
13762 									  "\n"
13763 									  "void main()\n"
13764 									  "{\n"
13765 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
13766 									  "\n"
13767 									  "VARIABLE_USE"
13768 									  "\n"
13769 									  "    tcs_tes[gl_InvocationID] = result;\n"
13770 									  "\n"
13771 									  "    gl_TessLevelOuter[0] = 1.0;\n"
13772 									  "    gl_TessLevelOuter[1] = 1.0;\n"
13773 									  "    gl_TessLevelOuter[2] = 1.0;\n"
13774 									  "    gl_TessLevelOuter[3] = 1.0;\n"
13775 									  "    gl_TessLevelInner[0] = 1.0;\n"
13776 									  "    gl_TessLevelInner[1] = 1.0;\n"
13777 									  "}\n"
13778 									  "\n";
13779 	static const GLchar* tes = "#version 430 core\n"
13780 							   "#extension GL_ARB_enhanced_layouts : require\n"
13781 							   "\n"
13782 							   "layout(isolines, point_mode) in;\n"
13783 							   "\n"
13784 							   "in  vec4 tcs_tes[];\n"
13785 							   "out vec4 tes_gs;\n"
13786 							   "\n"
13787 							   "void main()\n"
13788 							   "{\n"
13789 							   "    tes_gs = tcs_tes[0];\n"
13790 							   "}\n"
13791 							   "\n";
13792 	static const GLchar* tes_tested = "#version 430 core\n"
13793 									  "#extension GL_ARB_enhanced_layouts : require\n"
13794 									  "\n"
13795 									  "layout(isolines, point_mode) in;\n"
13796 									  "\n"
13797 									  "DIRECTION BLOCK_DEFINITION"
13798 									  "\n"
13799 									  "in  vec4 tcs_tes[];\n"
13800 									  "out vec4 tes_gs;\n"
13801 									  "\n"
13802 									  "void main()\n"
13803 									  "{\n"
13804 									  "    vec4 result = tcs_tes[0];\n"
13805 									  "\n"
13806 									  "VARIABLE_USE"
13807 									  "\n"
13808 									  "    tes_gs = result;\n"
13809 									  "}\n"
13810 									  "\n";
13811 	static const GLchar* vs = "#version 430 core\n"
13812 							  "#extension GL_ARB_enhanced_layouts : require\n"
13813 							  "\n"
13814 							  "in  vec4 in_vs;\n"
13815 							  "out vec4 vs_tcs;\n"
13816 							  "\n"
13817 							  "void main()\n"
13818 							  "{\n"
13819 							  "    vs_tcs = in_vs;\n"
13820 							  "}\n"
13821 							  "\n";
13822 	static const GLchar* vs_tested = "#version 430 core\n"
13823 									 "#extension GL_ARB_enhanced_layouts : require\n"
13824 									 "\n"
13825 									 "DIRECTION BLOCK_DEFINITION"
13826 									 "\n"
13827 									 "in  vec4 in_vs;\n"
13828 									 "out vec4 vs_tcs;\n"
13829 									 "\n"
13830 									 "void main()\n"
13831 									 "{\n"
13832 									 "    vec4 result = in_vs;\n"
13833 									 "\n"
13834 									 "VARIABLE_USE"
13835 									 "\n"
13836 									 "    vs_tcs = result;\n"
13837 									 "}\n"
13838 									 "\n";
13839 
13840 	const GLchar* array					= "";
13841 	const GLchar* direction				= "in";
13842 	const GLchar* index					= "";
13843 	std::string   source;
13844 	testCase&	 test_case = m_test_cases[test_case_index];
13845 	const GLchar* var_use	= Utils::Shader::VERTEX == test_case.m_stage ? input_use : "\n";
13846 	const GLchar* definition = test_case.m_qualify_all ? block_definition_all : block_definition_one;
13847 
13848 	if (!test_case.m_is_input)
13849 	{
13850 		direction = "out";
13851 		var_use   = output_use;
13852 	}
13853 
13854 	if (test_case.m_stage == stage)
13855 	{
13856 		size_t position = 0;
13857 		size_t temp		= 0;
13858 
13859 		switch (stage)
13860 		{
13861 		case Utils::Shader::FRAGMENT:
13862 			source = fs_tested;
13863 			break;
13864 		case Utils::Shader::GEOMETRY:
13865 			source = gs_tested;
13866 			array  = test_case.m_is_input ? "[]" : "";
13867 			index  = test_case.m_is_input ? "[0]" : "";
13868 			break;
13869 		case Utils::Shader::TESS_CTRL:
13870 			source = tcs_tested;
13871 			array  = "[]";
13872 			index  = "[gl_InvocationID]";
13873 			break;
13874 		case Utils::Shader::TESS_EVAL:
13875 			source = tes_tested;
13876 			array  = test_case.m_is_input ? "[]" : "";
13877 			index  = test_case.m_is_input ? "[0]" : "";
13878 			break;
13879 		case Utils::Shader::VERTEX:
13880 			source = vs_tested;
13881 			break;
13882 		default:
13883 			TCU_FAIL("Invalid enum");
13884 		}
13885 
13886 		Utils::replaceToken("DIRECTION", position, direction, source);
13887 		temp = position;
13888 		Utils::replaceToken("BLOCK_DEFINITION", position, definition, source);
13889 		position = temp;
13890 		Utils::replaceToken("ARRAY", position, array, source);
13891 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13892 
13893 		Utils::replaceAllTokens("INDEX", index, source);
13894 	}
13895 	else
13896 	{
13897 		switch (stage)
13898 		{
13899 		case Utils::Shader::FRAGMENT:
13900 			source = fs;
13901 			break;
13902 		case Utils::Shader::GEOMETRY:
13903 			source = gs;
13904 			break;
13905 		case Utils::Shader::TESS_CTRL:
13906 			source = tcs;
13907 			break;
13908 		case Utils::Shader::TESS_EVAL:
13909 			source = tes;
13910 			break;
13911 		case Utils::Shader::VERTEX:
13912 			source = vs;
13913 			break;
13914 		default:
13915 			TCU_FAIL("Invalid enum");
13916 		}
13917 	}
13918 
13919 	return source;
13920 }
13921 
13922 /** Get description of test case
13923  *
13924  * @param test_case_index Index of test case
13925  *
13926  * @return Test case description
13927  **/
13928 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index)
13929 {
13930 	std::stringstream stream;
13931 	testCase&		  test_case = m_test_cases[test_case_index];
13932 
13933 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13934 
13935 	if (true == test_case.m_is_input)
13936 	{
13937 		stream << "input";
13938 	}
13939 	else
13940 	{
13941 		stream << "output";
13942 	}
13943 
13944 	if (true == test_case.m_qualify_all)
13945 	{
13946 		stream << ", all members qualified";
13947 	}
13948 	else
13949 	{
13950 		stream << ", not all members qualified";
13951 	}
13952 
13953 	return stream.str();
13954 }
13955 
13956 /** Get number of test cases
13957  *
13958  * @return Number of test cases
13959  **/
13960 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber()
13961 {
13962 	return static_cast<GLuint>(m_test_cases.size());
13963 }
13964 
13965 /** Selects if "compute" stage is relevant for test
13966  *
13967  * @param ignored
13968  *
13969  * @return false
13970  **/
13971 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13972 {
13973 	return false;
13974 }
13975 
13976 /** Selects if compilation failure is expected result
13977  *
13978  * @param test_case_index Index of test case
13979  *
13980  * @return false when all members are qualified, true otherwise
13981  **/
13982 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index)
13983 {
13984 	return (true != m_test_cases[test_case_index].m_qualify_all);
13985 }
13986 
13987 /** Prepare all test cases
13988  *
13989  **/
13990 void VaryingBlockMemberLocationsTest::testInit()
13991 {
13992 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13993 	{
13994 		if (Utils::Shader::COMPUTE == stage)
13995 		{
13996 			continue;
13997 		}
13998 
13999 		testCase test_case_in_all  = { true, true, (Utils::Shader::STAGES)stage };
14000 		testCase test_case_in_one  = { true, false, (Utils::Shader::STAGES)stage };
14001 		testCase test_case_out_all = { false, true, (Utils::Shader::STAGES)stage };
14002 		testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage };
14003 
14004 		if (Utils::Shader::VERTEX != stage)
14005 		{
14006 			m_test_cases.push_back(test_case_in_all);
14007 			m_test_cases.push_back(test_case_in_one);
14008 		}
14009 
14010 		if (Utils::Shader::FRAGMENT != stage)
14011 		{
14012 			m_test_cases.push_back(test_case_out_all);
14013 			m_test_cases.push_back(test_case_out_one);
14014 		}
14015 	}
14016 }
14017 
14018 /** Constructor
14019  *
14020  * @param context Test framework context
14021  **/
14022 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context& context)
14023 	: NegativeTestBase(
14024 		  context, "varying_block_automatic_member_locations",
14025 		  "Test verifies that compiler assigns subsequent locations to block members, even if this causes errors")
14026 {
14027 }
14028 
14029 /** Source for given test case and stage
14030  *
14031  * @param test_case_index Index of test case
14032  * @param stage           Shader stage
14033  *
14034  * @return Shader source
14035  **/
14036 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint				test_case_index,
14037 																	  Utils::Shader::STAGES stage)
14038 {
14039 	static const GLchar* block_definition = "layout (location = 2) DIRECTION DBZ {\n"
14040 											"    vec4 goku;\n"
14041 											"    vec4 gohan[4];\n"
14042 											"    vec4 goten;\n"
14043 #if DEBUG_NEG_REMOVE_ERROR
14044 											"    /* layout (location = 1) */ vec4 chichi;\n"
14045 #else
14046 											"    layout (location = 1) vec4 chichi;\n"
14047 #endif /* DEBUG_NEG_REMOVE_ERROR */
14048 											"    vec4 pan;\n"
14049 											"} dbzARRAY;\n";
14050 	static const GLchar* input_use = "    result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + "
14051 									 "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + "
14052 									 "dbzINDEX.pan;\n";
14053 	static const GLchar* output_use = "    dbzINDEX.goku     = result;\n"
14054 									  "    dbzINDEX.gohan[0] = result / 2;\n"
14055 									  "    dbzINDEX.gohan[1] = result / 2.25;\n"
14056 									  "    dbzINDEX.gohan[2] = result / 2.5;\n"
14057 									  "    dbzINDEX.gohan[3] = result / 2.75;\n"
14058 									  "    dbzINDEX.goten    = result / 4  - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - "
14059 									  "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n"
14060 									  "    dbzINDEX.chichi   = result / 8  - dbzINDEX.goten;\n"
14061 									  "    dbzINDEX.pan      = result / 16 - dbzINDEX.chichi;\n";
14062 	static const GLchar* fs = "#version 430 core\n"
14063 							  "#extension GL_ARB_enhanced_layouts : require\n"
14064 							  "\n"
14065 							  "in  vec4 gs_fs;\n"
14066 							  "out vec4 fs_out;\n"
14067 							  "\n"
14068 							  "void main()\n"
14069 							  "{\n"
14070 							  "    fs_out = gs_fs;\n"
14071 							  "}\n"
14072 							  "\n";
14073 	static const GLchar* fs_tested = "#version 430 core\n"
14074 									 "#extension GL_ARB_enhanced_layouts : require\n"
14075 									 "\n"
14076 									 "BLOCK_DEFINITION"
14077 									 "\n"
14078 									 "in  vec4 gs_fs;\n"
14079 									 "out vec4 fs_out;\n"
14080 									 "\n"
14081 									 "void main()\n"
14082 									 "{\n"
14083 									 "    vec4 result = gs_fs;\n"
14084 									 "\n"
14085 									 "VARIABLE_USE"
14086 									 "\n"
14087 									 "    fs_out += result;\n"
14088 									 "}\n"
14089 									 "\n";
14090 	static const GLchar* gs = "#version 430 core\n"
14091 							  "#extension GL_ARB_enhanced_layouts : require\n"
14092 							  "\n"
14093 							  "layout(points)                           in;\n"
14094 							  "layout(triangle_strip, max_vertices = 4) out;\n"
14095 							  "\n"
14096 							  "in  vec4 tes_gs[];\n"
14097 							  "out vec4 gs_fs;\n"
14098 							  "\n"
14099 							  "void main()\n"
14100 							  "{\n"
14101 							  "    gs_fs = tes_gs[0];\n"
14102 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14103 							  "    EmitVertex();\n"
14104 							  "    gs_fs = tes_gs[0];\n"
14105 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14106 							  "    EmitVertex();\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 							  "}\n"
14114 							  "\n";
14115 	static const GLchar* gs_tested = "#version 430 core\n"
14116 									 "#extension GL_ARB_enhanced_layouts : require\n"
14117 									 "\n"
14118 									 "layout(points)                           in;\n"
14119 									 "layout(triangle_strip, max_vertices = 4) out;\n"
14120 									 "\n"
14121 									 "BLOCK_DEFINITION"
14122 									 "\n"
14123 									 "in  vec4 tes_gs[];\n"
14124 									 "out vec4 gs_fs;\n"
14125 									 "\n"
14126 									 "void main()\n"
14127 									 "{\n"
14128 									 "    vec4 result = tes_gs[0];\n"
14129 									 "\n"
14130 									 "VARIABLE_USE"
14131 									 "\n"
14132 									 "    gs_fs = result;\n"
14133 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14134 									 "    EmitVertex();\n"
14135 									 "    gs_fs = result;\n"
14136 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14137 									 "    EmitVertex();\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 									 "}\n"
14145 									 "\n";
14146 	static const GLchar* tcs = "#version 430 core\n"
14147 							   "#extension GL_ARB_enhanced_layouts : require\n"
14148 							   "\n"
14149 							   "layout(vertices = 1) out;\n"
14150 							   "\n"
14151 							   "in  vec4 vs_tcs[];\n"
14152 							   "out vec4 tcs_tes[];\n"
14153 							   "\n"
14154 							   "void main()\n"
14155 							   "{\n"
14156 							   "\n"
14157 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14158 							   "\n"
14159 							   "    gl_TessLevelOuter[0] = 1.0;\n"
14160 							   "    gl_TessLevelOuter[1] = 1.0;\n"
14161 							   "    gl_TessLevelOuter[2] = 1.0;\n"
14162 							   "    gl_TessLevelOuter[3] = 1.0;\n"
14163 							   "    gl_TessLevelInner[0] = 1.0;\n"
14164 							   "    gl_TessLevelInner[1] = 1.0;\n"
14165 							   "}\n"
14166 							   "\n";
14167 	static const GLchar* tcs_tested = "#version 430 core\n"
14168 									  "#extension GL_ARB_enhanced_layouts : require\n"
14169 									  "\n"
14170 									  "layout(vertices = 1) out;\n"
14171 									  "\n"
14172 									  "BLOCK_DEFINITION"
14173 									  "\n"
14174 									  "in  vec4 vs_tcs[];\n"
14175 									  "out vec4 tcs_tes[];\n"
14176 									  "\n"
14177 									  "void main()\n"
14178 									  "{\n"
14179 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
14180 									  "\n"
14181 									  "VARIABLE_USE"
14182 									  "\n"
14183 									  "    tcs_tes[gl_InvocationID] = result;\n"
14184 									  "\n"
14185 									  "    gl_TessLevelOuter[0] = 1.0;\n"
14186 									  "    gl_TessLevelOuter[1] = 1.0;\n"
14187 									  "    gl_TessLevelOuter[2] = 1.0;\n"
14188 									  "    gl_TessLevelOuter[3] = 1.0;\n"
14189 									  "    gl_TessLevelInner[0] = 1.0;\n"
14190 									  "    gl_TessLevelInner[1] = 1.0;\n"
14191 									  "}\n"
14192 									  "\n";
14193 	static const GLchar* tes = "#version 430 core\n"
14194 							   "#extension GL_ARB_enhanced_layouts : require\n"
14195 							   "\n"
14196 							   "layout(isolines, point_mode) in;\n"
14197 							   "\n"
14198 							   "in  vec4 tcs_tes[];\n"
14199 							   "out vec4 tes_gs;\n"
14200 							   "\n"
14201 							   "void main()\n"
14202 							   "{\n"
14203 							   "    tes_gs = tcs_tes[0];\n"
14204 							   "}\n"
14205 							   "\n";
14206 	static const GLchar* tes_tested = "#version 430 core\n"
14207 									  "#extension GL_ARB_enhanced_layouts : require\n"
14208 									  "\n"
14209 									  "layout(isolines, point_mode) in;\n"
14210 									  "\n"
14211 									  "BLOCK_DEFINITION"
14212 									  "\n"
14213 									  "in  vec4 tcs_tes[];\n"
14214 									  "out vec4 tes_gs;\n"
14215 									  "\n"
14216 									  "void main()\n"
14217 									  "{\n"
14218 									  "    vec4 result = tcs_tes[0];\n"
14219 									  "\n"
14220 									  "VARIABLE_USE"
14221 									  "\n"
14222 									  "    tes_gs += result;\n"
14223 									  "}\n"
14224 									  "\n";
14225 	static const GLchar* vs = "#version 430 core\n"
14226 							  "#extension GL_ARB_enhanced_layouts : require\n"
14227 							  "\n"
14228 							  "in  vec4 in_vs;\n"
14229 							  "out vec4 vs_tcs;\n"
14230 							  "\n"
14231 							  "void main()\n"
14232 							  "{\n"
14233 							  "    vs_tcs = in_vs;\n"
14234 							  "}\n"
14235 							  "\n";
14236 	static const GLchar* vs_tested = "#version 430 core\n"
14237 									 "#extension GL_ARB_enhanced_layouts : require\n"
14238 									 "\n"
14239 									 "BLOCK_DEFINITION"
14240 									 "\n"
14241 									 "in  vec4 in_vs;\n"
14242 									 "out vec4 vs_tcs;\n"
14243 									 "\n"
14244 									 "void main()\n"
14245 									 "{\n"
14246 									 "    vec4 result = in_vs;\n"
14247 									 "\n"
14248 									 "VARIABLE_USE"
14249 									 "\n"
14250 									 "    vs_tcs += result;\n"
14251 									 "}\n"
14252 									 "\n";
14253 
14254 	const GLchar* array		= "";
14255 	const GLchar* direction = "in";
14256 	const GLchar* index		= "";
14257 	std::string   source;
14258 	testCase&	 test_case = m_test_cases[test_case_index];
14259 	const GLchar* var_use   = Utils::Shader::VERTEX == test_case.m_stage ? input_use : "\n";
14260 
14261 	if (!test_case.m_is_input)
14262 	{
14263 		direction = "out";
14264 		var_use   = output_use;
14265 	}
14266 
14267 	if (test_case.m_stage == stage)
14268 	{
14269 		size_t position = 0;
14270 
14271 		switch (stage)
14272 		{
14273 		case Utils::Shader::FRAGMENT:
14274 			source = fs_tested;
14275 			break;
14276 		case Utils::Shader::GEOMETRY:
14277 			source = gs_tested;
14278 			array  = test_case.m_is_input ? "[]" : "";
14279 			index  = test_case.m_is_input ? "[0]" : "";
14280 			break;
14281 		case Utils::Shader::TESS_CTRL:
14282 			source = tcs_tested;
14283 			array  = "[]";
14284 			index  = "[gl_InvocationID]";
14285 			break;
14286 		case Utils::Shader::TESS_EVAL:
14287 			source = tes_tested;
14288 			array  = test_case.m_is_input ? "[]" : "";
14289 			index  = test_case.m_is_input ? "[0]" : "";
14290 			break;
14291 		case Utils::Shader::VERTEX:
14292 			source = vs_tested;
14293 			break;
14294 		default:
14295 			TCU_FAIL("Invalid enum");
14296 		}
14297 
14298 		Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source);
14299 		position = 0;
14300 		Utils::replaceToken("DIRECTION", position, direction, source);
14301 		Utils::replaceToken("ARRAY", position, array, source);
14302 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14303 
14304 		Utils::replaceAllTokens("INDEX", index, source);
14305 	}
14306 	else
14307 	{
14308 		switch (stage)
14309 		{
14310 		case Utils::Shader::FRAGMENT:
14311 			source = fs;
14312 			break;
14313 		case Utils::Shader::GEOMETRY:
14314 			source = gs;
14315 			break;
14316 		case Utils::Shader::TESS_CTRL:
14317 			source = tcs;
14318 			break;
14319 		case Utils::Shader::TESS_EVAL:
14320 			source = tes;
14321 			break;
14322 		case Utils::Shader::VERTEX:
14323 			source = vs;
14324 			break;
14325 		default:
14326 			TCU_FAIL("Invalid enum");
14327 		}
14328 	}
14329 
14330 	return source;
14331 }
14332 
14333 /** Get description of test case
14334  *
14335  * @param test_case_index Index of test case
14336  *
14337  * @return Test case description
14338  **/
14339 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index)
14340 {
14341 	std::stringstream stream;
14342 	testCase&		  test_case = m_test_cases[test_case_index];
14343 
14344 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
14345 
14346 	if (true == test_case.m_is_input)
14347 	{
14348 		stream << "input";
14349 	}
14350 	else
14351 	{
14352 		stream << "output";
14353 	}
14354 
14355 	return stream.str();
14356 }
14357 
14358 /** Get number of test cases
14359  *
14360  * @return Number of test cases
14361  **/
14362 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber()
14363 {
14364 	return static_cast<GLuint>(m_test_cases.size());
14365 }
14366 
14367 /** Selects if "compute" stage is relevant for test
14368  *
14369  * @param ignored
14370  *
14371  * @return false
14372  **/
14373 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
14374 {
14375 	return false;
14376 }
14377 
14378 /** Prepare all test cases
14379  *
14380  **/
14381 void VaryingBlockAutomaticMemberLocationsTest::testInit()
14382 {
14383 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14384 	{
14385 		if (Utils::Shader::COMPUTE == stage)
14386 		{
14387 			continue;
14388 		}
14389 
14390 		testCase test_case_in  = { true, (Utils::Shader::STAGES)stage };
14391 		testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
14392 
14393 		if (Utils::Shader::VERTEX != stage)
14394 		{
14395 			m_test_cases.push_back(test_case_in);
14396 		}
14397 
14398 		if (Utils::Shader::FRAGMENT != stage)
14399 		{
14400 			m_test_cases.push_back(test_case_out);
14401 		}
14402 	}
14403 }
14404 
14405 /** Constructor
14406  *
14407  * @param context Test framework context
14408  **/
14409 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context& context)
14410 	: NegativeTestBase(context, "varying_location_limit",
14411 					   "Test verifies that compiler reports error when location qualifier exceeds limits")
14412 {
14413 }
14414 
14415 /** Source for given test case and stage
14416  *
14417  * @param test_case_index Index of test case
14418  * @param stage           Shader stage
14419  *
14420  * @return Shader source
14421  **/
14422 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
14423 {
14424 #if DEBUG_NEG_REMOVE_ERROR
14425 	static const GLchar* var_definition = "layout (location = LAST /* + 1 */) FLAT DIRECTION TYPE gokuARRAY;\n";
14426 #else
14427 	static const GLchar* var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n";
14428 #endif /* DEBUG_NEG_REMOVE_ERROR */
14429 	static const GLchar* input_use		= "    if (TYPE(0) == gokuINDEX)\n"
14430 									 "    {\n"
14431 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
14432 									 "    }\n";
14433 	static const GLchar* output_use = "    gokuINDEX = TYPE(0);\n"
14434 									  "    if (vec4(0) == result)\n"
14435 									  "    {\n"
14436 									  "        gokuINDEX = TYPE(1);\n"
14437 									  "    }\n";
14438 	static const GLchar* fs = "#version 430 core\n"
14439 							  "#extension GL_ARB_enhanced_layouts : require\n"
14440 							  "\n"
14441 							  "in  vec4 gs_fs;\n"
14442 							  "out vec4 fs_out;\n"
14443 							  "\n"
14444 							  "void main()\n"
14445 							  "{\n"
14446 							  "    fs_out = gs_fs;\n"
14447 							  "}\n"
14448 							  "\n";
14449 	static const GLchar* fs_tested = "#version 430 core\n"
14450 									 "#extension GL_ARB_enhanced_layouts : require\n"
14451 									 "\n"
14452 									 "VAR_DEFINITION"
14453 									 "\n"
14454 									 "in  vec4 gs_fs;\n"
14455 									 "out vec4 fs_out;\n"
14456 									 "\n"
14457 									 "void main()\n"
14458 									 "{\n"
14459 									 "    vec4 result = gs_fs;\n"
14460 									 "\n"
14461 									 "VARIABLE_USE"
14462 									 "\n"
14463 									 "    fs_out += result;\n"
14464 									 "}\n"
14465 									 "\n";
14466 	static const GLchar* gs = "#version 430 core\n"
14467 							  "#extension GL_ARB_enhanced_layouts : require\n"
14468 							  "\n"
14469 							  "layout(points)                           in;\n"
14470 							  "layout(triangle_strip, max_vertices = 4) out;\n"
14471 							  "\n"
14472 							  "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
14473 							  "in  vec4 tes_gs[];\n"
14474 							  "out vec4 gs_fs;\n"
14475 							  "\n"
14476 							  "void main()\n"
14477 							  "{\n"
14478 							  "    gs_fs = tes_gs[0];\n"
14479 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14480 							  "    EmitVertex();\n"
14481 							  "    gs_fs = tes_gs[0];\n"
14482 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14483 							  "    EmitVertex();\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 							  "}\n"
14491 							  "\n";
14492 	static const GLchar* gs_tested = "#version 430 core\n"
14493 									 "#extension GL_ARB_enhanced_layouts : require\n"
14494 									 "\n"
14495 									 "layout(points)                           in;\n"
14496 									 "layout(triangle_strip, max_vertices = 4) out;\n"
14497 									 "\n"
14498 									 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
14499 									 "VAR_DEFINITION"
14500 									 "\n"
14501 									 "in  vec4 tes_gs[];\n"
14502 									 "out vec4 gs_fs;\n"
14503 									 "\n"
14504 									 "void main()\n"
14505 									 "{\n"
14506 									 "    vec4 result = tes_gs[0];\n"
14507 									 "\n"
14508 									 "VARIABLE_USE"
14509 									 "\n"
14510 									 "    gs_fs = result;\n"
14511 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14512 									 "    EmitVertex();\n"
14513 									 "    gs_fs = result;\n"
14514 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14515 									 "    EmitVertex();\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 									 "}\n"
14523 									 "\n";
14524 	static const GLchar* tcs = "#version 430 core\n"
14525 							   "#extension GL_ARB_enhanced_layouts : require\n"
14526 							   "\n"
14527 							   "layout(vertices = 1) out;\n"
14528 							   "\n"
14529 							   "in  vec4 vs_tcs[];\n"
14530 							   "out vec4 tcs_tes[];\n"
14531 							   "\n"
14532 							   "void main()\n"
14533 							   "{\n"
14534 							   "\n"
14535 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14536 							   "\n"
14537 							   "    gl_TessLevelOuter[0] = 1.0;\n"
14538 							   "    gl_TessLevelOuter[1] = 1.0;\n"
14539 							   "    gl_TessLevelOuter[2] = 1.0;\n"
14540 							   "    gl_TessLevelOuter[3] = 1.0;\n"
14541 							   "    gl_TessLevelInner[0] = 1.0;\n"
14542 							   "    gl_TessLevelInner[1] = 1.0;\n"
14543 							   "}\n"
14544 							   "\n";
14545 	static const GLchar* tcs_tested = "#version 430 core\n"
14546 									  "#extension GL_ARB_enhanced_layouts : require\n"
14547 									  "\n"
14548 									  "layout(vertices = 1) out;\n"
14549 									  "\n"
14550 									  "VAR_DEFINITION"
14551 									  "\n"
14552 									  "in  vec4 vs_tcs[];\n"
14553 									  "out vec4 tcs_tes[];\n"
14554 									  "\n"
14555 									  "void main()\n"
14556 									  "{\n"
14557 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
14558 									  "\n"
14559 									  "VARIABLE_USE"
14560 									  "\n"
14561 									  "    tcs_tes[gl_InvocationID] = result;\n"
14562 									  "\n"
14563 									  "    gl_TessLevelOuter[0] = 1.0;\n"
14564 									  "    gl_TessLevelOuter[1] = 1.0;\n"
14565 									  "    gl_TessLevelOuter[2] = 1.0;\n"
14566 									  "    gl_TessLevelOuter[3] = 1.0;\n"
14567 									  "    gl_TessLevelInner[0] = 1.0;\n"
14568 									  "    gl_TessLevelInner[1] = 1.0;\n"
14569 									  "}\n"
14570 									  "\n";
14571 	static const GLchar* tes = "#version 430 core\n"
14572 							   "#extension GL_ARB_enhanced_layouts : require\n"
14573 							   "\n"
14574 							   "layout(isolines, point_mode) in;\n"
14575 							   "\n"
14576 							   "in  vec4 tcs_tes[];\n"
14577 							   "out vec4 tes_gs;\n"
14578 							   "\n"
14579 							   "void main()\n"
14580 							   "{\n"
14581 							   "    tes_gs = tcs_tes[0];\n"
14582 							   "}\n"
14583 							   "\n";
14584 	static const GLchar* tes_tested = "#version 430 core\n"
14585 									  "#extension GL_ARB_enhanced_layouts : require\n"
14586 									  "\n"
14587 									  "layout(isolines, point_mode) in;\n"
14588 									  "\n"
14589 									  "VAR_DEFINITION"
14590 									  "\n"
14591 									  "in  vec4 tcs_tes[];\n"
14592 									  "out vec4 tes_gs;\n"
14593 									  "\n"
14594 									  "void main()\n"
14595 									  "{\n"
14596 									  "    vec4 result = tcs_tes[0];\n"
14597 									  "\n"
14598 									  "VARIABLE_USE"
14599 									  "\n"
14600 									  "    tes_gs += result;\n"
14601 									  "}\n"
14602 									  "\n";
14603 	static const GLchar* vs = "#version 430 core\n"
14604 							  "#extension GL_ARB_enhanced_layouts : require\n"
14605 							  "\n"
14606 							  "in  vec4 in_vs;\n"
14607 							  "out vec4 vs_tcs;\n"
14608 							  "\n"
14609 							  "void main()\n"
14610 							  "{\n"
14611 							  "    vs_tcs = in_vs;\n"
14612 							  "}\n"
14613 							  "\n";
14614 	static const GLchar* vs_tested = "#version 430 core\n"
14615 									 "#extension GL_ARB_enhanced_layouts : require\n"
14616 									 "\n"
14617 									 "VAR_DEFINITION"
14618 									 "\n"
14619 									 "in  vec4 in_vs;\n"
14620 									 "out vec4 vs_tcs;\n"
14621 									 "\n"
14622 									 "void main()\n"
14623 									 "{\n"
14624 									 "    vec4 result = in_vs;\n"
14625 									 "\n"
14626 									 "VARIABLE_USE"
14627 									 "\n"
14628 									 "    vs_tcs += result;\n"
14629 									 "}\n"
14630 									 "\n";
14631 
14632 	std::string source;
14633 	testCase&   test_case = m_test_cases[test_case_index];
14634 	size_t		  position   = 0;
14635 	const GLchar* per_vertex = !isSeparable(test_case_index) ? "" : "out gl_PerVertex {\n"
14636 																	"vec4 gl_Position;\n"
14637 																	"};\n"
14638 																	"\n";
14639 
14640 	if (test_case.m_stage == stage)
14641 	{
14642 		const GLchar*			 array = "";
14643 		GLchar					 buffer[16];
14644 		const GLchar*			 direction = "in ";
14645 		const GLchar*			 flat	  = "";
14646 		const GLchar*			 index	 = "";
14647 		GLuint					 last	  = getLastInputLocation(stage, test_case.m_type, 0, true);
14648 		const GLchar*			 type_name = test_case.m_type.GetGLSLTypeName();
14649 		Utils::Variable::STORAGE storage   = Utils::Variable::VARYING_INPUT;
14650 		const GLchar*			 var_use   = input_use;
14651 
14652 		if (false == test_case.m_is_input)
14653 		{
14654 			direction = "out";
14655 			last	  = getLastOutputLocation(stage, test_case.m_type, 0, true);
14656 			storage   = Utils::Variable::VARYING_OUTPUT;
14657 			var_use   = output_use;
14658 		}
14659 
14660 		if (isFlatRequired(stage, test_case.m_type, storage))
14661 		{
14662 			flat = "flat";
14663 		}
14664 
14665 		sprintf(buffer, "%d", last);
14666 
14667 		switch (stage)
14668 		{
14669 		case Utils::Shader::FRAGMENT:
14670 			source = fs_tested;
14671 			break;
14672 		case Utils::Shader::GEOMETRY:
14673 			source = gs_tested;
14674 			array  = test_case.m_is_input ? "[]" : "";
14675 			index  = test_case.m_is_input ? "[0]" : "";
14676 			Utils::replaceToken("PERVERTEX", position, per_vertex, source);
14677 			break;
14678 		case Utils::Shader::TESS_CTRL:
14679 			source = tcs_tested;
14680 			array  = "[]";
14681 			index  = "[gl_InvocationID]";
14682 			break;
14683 		case Utils::Shader::TESS_EVAL:
14684 			source = tes_tested;
14685 			array  = test_case.m_is_input ? "[]" : "";
14686 			index  = test_case.m_is_input ? "[0]" : "";
14687 			break;
14688 		case Utils::Shader::VERTEX:
14689 			source = vs_tested;
14690 			break;
14691 		default:
14692 			TCU_FAIL("Invalid enum");
14693 		}
14694 
14695 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
14696 		position = 0;
14697 		Utils::replaceToken("LAST", position, buffer, source);
14698 		Utils::replaceToken("FLAT", position, flat, source);
14699 		Utils::replaceToken("DIRECTION", position, direction, source);
14700 		Utils::replaceToken("ARRAY", position, array, source);
14701 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14702 
14703 		Utils::replaceAllTokens("TYPE", type_name, source);
14704 		Utils::replaceAllTokens("INDEX", index, source);
14705 	}
14706 	else
14707 	{
14708 		switch (stage)
14709 		{
14710 		case Utils::Shader::FRAGMENT:
14711 			source = fs;
14712 			break;
14713 		case Utils::Shader::GEOMETRY:
14714 			source = gs;
14715 			Utils::replaceToken("PERVERTEX", position, per_vertex, source);
14716 			break;
14717 		case Utils::Shader::TESS_CTRL:
14718 			source = tcs;
14719 			break;
14720 		case Utils::Shader::TESS_EVAL:
14721 			source = tes;
14722 			break;
14723 		case Utils::Shader::VERTEX:
14724 			source = vs;
14725 			break;
14726 		default:
14727 			TCU_FAIL("Invalid enum");
14728 		}
14729 	}
14730 
14731 	return source;
14732 }
14733 
14734 /** Get description of test case
14735  *
14736  * @param test_case_index Index of test case
14737  *
14738  * @return Test case description
14739  **/
14740 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index)
14741 {
14742 	std::stringstream stream;
14743 	testCase&		  test_case = m_test_cases[test_case_index];
14744 
14745 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
14746 		   << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
14747 
14748 	if (true == test_case.m_is_input)
14749 	{
14750 		stream << "input";
14751 	}
14752 	else
14753 	{
14754 		stream << "output";
14755 	}
14756 
14757 	return stream.str();
14758 }
14759 
14760 /** Get number of test cases
14761  *
14762  * @return Number of test cases
14763  **/
14764 GLuint VaryingLocationLimitTest::getTestCaseNumber()
14765 {
14766 	return static_cast<GLuint>(m_test_cases.size());
14767 }
14768 
14769 /** Selects if "compute" stage is relevant for test
14770  *
14771  * @param ignored
14772  *
14773  * @return false
14774  **/
14775 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */)
14776 {
14777 	return false;
14778 }
14779 
14780 /** Selects if the test case should use a separable program
14781  *
14782  * @param test_case_index Id of test case
14783  *
14784  * @return whether the test should use separable programs or not
14785  **/
14786 bool VaryingLocationLimitTest::isSeparable(const GLuint test_case_index)
14787 {
14788 	const testCase& test_case = m_test_cases[test_case_index];
14789 
14790 	return test_case.m_is_input && test_case.m_stage != Utils::Shader::VERTEX;
14791 }
14792 
14793 /** Prepare all test cases
14794  *
14795  **/
14796 void VaryingLocationLimitTest::testInit()
14797 {
14798 	const GLuint n_types = getTypesNumber();
14799 
14800 	for (GLuint i = 0; i < n_types; ++i)
14801 	{
14802 		const Utils::Type& type = getType(i);
14803 
14804 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14805 		{
14806 			if (Utils::Shader::COMPUTE == stage)
14807 			{
14808 				continue;
14809 			}
14810 
14811 			testCase test_case_in  = { true, type, (Utils::Shader::STAGES)stage };
14812 			testCase test_case_out = { false, type, (Utils::Shader::STAGES)stage };
14813 
14814 			m_test_cases.push_back(test_case_in);
14815 
14816 			if (Utils::Shader::FRAGMENT != stage)
14817 			{
14818 				m_test_cases.push_back(test_case_out);
14819 			}
14820 		}
14821 	}
14822 }
14823 
14824 /** Constructor
14825  *
14826  * @param context Test framework context
14827  **/
14828 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context)
14829 	: VaryingLocationsTest(context, "varying_components",
14830 						   "Test verifies that input and output components are respected")
14831 {
14832 }
14833 
14834 /** Constructor
14835  *
14836  * @param context          Test framework context
14837  * @param test_name        Name of test
14838  * @param test_description Description of test
14839  **/
14840 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context, const glw::GLchar* test_name,
14841 											 const glw::GLchar* test_description)
14842 	: VaryingLocationsTest(context, test_name, test_description)
14843 {
14844 }
14845 
14846 /** Get interface of program
14847  *
14848  * @param test_case_index     Test case
14849  * @param program_interface   Interface of program
14850  * @param varying_passthrough Collection of connections between in and out variables
14851  **/
14852 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
14853 												Utils::VaryingPassthrough& varying_passthrough)
14854 {
14855 	GLuint				   array_length = getArrayLength();
14856 	const testCase&		   test_case	= m_test_cases[test_case_index];
14857 	const Utils::Type	  vector_type  = Utils::Type::GetType(test_case.m_type, 1, 4);
14858 	Utils::ShaderInterface si			= program_interface.GetShaderInterface(Utils::Shader::VERTEX);
14859 
14860 	/* Zero means no array, however we still need at least 1 slot of data */
14861 	if (0 == array_length)
14862 	{
14863 		array_length += 1;
14864 	}
14865 
14866 	/* Generate data */
14867 	const std::vector<GLubyte>& data	  = vector_type.GenerateDataPacked();
14868 	const size_t				data_size = data.size();
14869 
14870 	/* Prepare data for variables */
14871 	m_data.resize(array_length * data_size);
14872 
14873 	GLubyte*	   dst = &m_data[0];
14874 	const GLubyte* src = &data[0];
14875 
14876 	for (GLuint i = 0; i < array_length; ++i)
14877 	{
14878 		memcpy(dst + data_size * i, src, data_size);
14879 	}
14880 
14881 	/* Prepare interface for each stage */
14882 	prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough);
14883 	prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough);
14884 	prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough);
14885 	prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough);
14886 	prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough);
14887 }
14888 
14889 /** Get type name
14890  *
14891  * @param test_case_index Index of test case
14892  *
14893  * @return Name of type test in test_case_index
14894  **/
14895 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index)
14896 {
14897 	std::string name;
14898 
14899 	const testCase& test_case = m_test_cases[test_case_index];
14900 
14901 	name = "Type: ";
14902 
14903 	switch (test_case.m_type)
14904 	{
14905 	case Utils::Type::Double:
14906 		name.append(Utils::Type::_double.GetGLSLTypeName());
14907 		break;
14908 	case Utils::Type::Float:
14909 		name.append(Utils::Type::_float.GetGLSLTypeName());
14910 		break;
14911 	case Utils::Type::Int:
14912 		name.append(Utils::Type::_int.GetGLSLTypeName());
14913 		break;
14914 	case Utils::Type::Uint:
14915 		name.append(Utils::Type::uint.GetGLSLTypeName());
14916 		break;
14917 	}
14918 
14919 	name.append(", layout: ");
14920 
14921 	switch (test_case.m_layout)
14922 	{
14923 	case G64VEC2:
14924 		name.append("G64VEC2");
14925 		break;
14926 	case G64SCALAR_G64SCALAR:
14927 		name.append("G64SCALAR_G64SCALAR");
14928 		break;
14929 	case GVEC4:
14930 		name.append("GVEC4");
14931 		break;
14932 	case SCALAR_GVEC3:
14933 		name.append("SCALAR_GVEC3");
14934 		break;
14935 	case GVEC3_SCALAR:
14936 		name.append("GVEC3_SCALAR");
14937 		break;
14938 	case GVEC2_GVEC2:
14939 		name.append("GVEC2_GVEC2");
14940 		break;
14941 	case GVEC2_SCALAR_SCALAR:
14942 		name.append("GVEC2_SCALAR_SCALAR");
14943 		break;
14944 	case SCALAR_GVEC2_SCALAR:
14945 		name.append("SCALAR_GVEC2_SCALAR");
14946 		break;
14947 	case SCALAR_SCALAR_GVEC2:
14948 		name.append("SCALAR_SCALAR_GVEC2");
14949 		break;
14950 	case SCALAR_SCALAR_SCALAR_SCALAR:
14951 		name.append("SCALAR_SCALAR_SCALAR_SCALAR");
14952 		break;
14953 	}
14954 
14955 	return name;
14956 }
14957 
14958 /** Returns number of types to test
14959  *
14960  * @return Number of types
14961  **/
14962 glw::GLuint VaryingComponentsTest::getTestCaseNumber()
14963 {
14964 	return static_cast<GLuint>(m_test_cases.size());
14965 }
14966 
14967 /* Prepare test cases */
14968 void VaryingComponentsTest::testInit()
14969 {
14970 	m_test_cases.push_back(testCase(G64VEC2, Utils::Type::Double));
14971 	m_test_cases.push_back(testCase(G64SCALAR_G64SCALAR, Utils::Type::Double));
14972 
14973 	m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float));
14974 	m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float));
14975 	m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float));
14976 	m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float));
14977 	m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float));
14978 	m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float));
14979 	m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float));
14980 	m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float));
14981 
14982 	m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int));
14983 	m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int));
14984 	m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int));
14985 	m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int));
14986 	m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int));
14987 	m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int));
14988 	m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int));
14989 	m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int));
14990 
14991 	m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint));
14992 	m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint));
14993 	m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint));
14994 	m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint));
14995 	m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint));
14996 	m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint));
14997 	m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint));
14998 	m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint));
14999 }
15000 
15001 /** Inform that test use components
15002  *
15003  * @param ignored
15004  *
15005  * @return true
15006  **/
15007 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */)
15008 {
15009 	return true;
15010 }
15011 
15012 /** Get length of arrays that should be used during test
15013  *
15014  * @return 0u - no array at all
15015  **/
15016 GLuint VaryingComponentsTest::getArrayLength()
15017 {
15018 	return 0;
15019 }
15020 
15021 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location)
15022 {
15023 	std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location);
15024 
15025 	globals.append("const uint comp_x = 0u;\n"
15026 				   "const uint comp_y = 1u;\n"
15027 				   "const uint comp_z = 2u;\n"
15028 				   "const uint comp_w = 3u;\n");
15029 
15030 	return globals;
15031 }
15032 
15033 /**
15034  *
15035  **/
15036 std::string VaryingComponentsTest::prepareName(const glw::GLchar* name, glw::GLint location, glw::GLint component,
15037 											   Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15038 {
15039 	GLchar		  buffer[16];
15040 	std::string   result   = "PREFIXNAME_lLOCATION_cCOMPONENT";
15041 	size_t		  position = 0;
15042 	const GLchar* prefix   = Utils::ProgramInterface::GetStagePrefix(stage, storage);
15043 
15044 	Utils::replaceToken("PREFIX", position, prefix, result);
15045 	Utils::replaceToken("NAME", position, name, result);
15046 
15047 	sprintf(buffer, "%d", location);
15048 	Utils::replaceToken("LOCATION", position, buffer, result);
15049 
15050 	sprintf(buffer, "%d", component);
15051 	Utils::replaceToken("COMPONENT", position, buffer, result);
15052 
15053 	return result;
15054 }
15055 
15056 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar* location, const glw::GLchar* component,
15057 													 const glw::GLchar* interpolation)
15058 {
15059 	size_t		position   = 0;
15060 	std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION";
15061 
15062 	Utils::replaceToken("LOCATION", position, location, qualifiers);
15063 	Utils::replaceToken("COMPONENT", position, component, qualifiers);
15064 	Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers);
15065 
15066 	return qualifiers;
15067 }
15068 
15069 /**
15070  *
15071  **/
15072 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& vector_type,
15073 											   Utils::ProgramInterface& program_interface, const testCase& test_case,
15074 											   Utils::VaryingPassthrough& varying_passthrough)
15075 {
15076 	const GLuint			array_length = getArrayLength();
15077 	const Utils::Type&		basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */);
15078 	descriptor				desc_in[8];
15079 	descriptor				desc_out[8];
15080 	const GLuint			first_in_loc  = 0;
15081 	const GLuint			first_out_loc = 0;
15082 	const GLchar*			interpolation = "";
15083 	const GLuint			last_in_loc   = getLastInputLocation(stage, vector_type, array_length, false);
15084 	GLuint					last_out_loc  = 0;
15085 	GLuint					n_desc		  = 0;
15086 	Utils::ShaderInterface& si			  = program_interface.GetShaderInterface(stage);
15087 
15088 	/* Select interpolation */
15089 	if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage))
15090 	{
15091 		interpolation = " flat";
15092 	}
15093 
15094 	if (Utils::Shader::FRAGMENT != stage)
15095 	{
15096 		last_out_loc = getLastOutputLocation(stage, vector_type, array_length, false);
15097 	}
15098 
15099 	switch (test_case.m_layout)
15100 	{
15101 	case G64VEC2:
15102 		n_desc = 2;
15103 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "g64vec2");
15104 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "g64vec2");
15105 
15106 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "g64vec2");
15107 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "g64vec2");
15108 		break;
15109 
15110 	case G64SCALAR_G64SCALAR:
15111 		n_desc = 4;
15112 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "g64scalar");
15113 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "g64scalar");
15114 		desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "g64scalar");
15115 		desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "g64scalar");
15116 
15117 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "g64scalar");
15118 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "g64scalar");
15119 		desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "g64scalar");
15120 		desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "g64scalar");
15121 		break;
15122 	case GVEC4:
15123 		n_desc = 2;
15124 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4");
15125 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4");
15126 
15127 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4");
15128 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4");
15129 		break;
15130 	case SCALAR_GVEC3:
15131 		n_desc = 4;
15132 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15133 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15134 		desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3");
15135 		desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3");
15136 
15137 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15138 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15139 		desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3");
15140 		desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3");
15141 		break;
15142 	case GVEC3_SCALAR:
15143 		n_desc = 4;
15144 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3");
15145 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3");
15146 		desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15147 		desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15148 
15149 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3");
15150 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3");
15151 		desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15152 		desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15153 		break;
15154 	case GVEC2_GVEC2:
15155 		n_desc = 4;
15156 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15157 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15158 		desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15159 		desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15160 
15161 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
15162 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15163 		desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15164 		desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15165 		break;
15166 	case GVEC2_SCALAR_SCALAR:
15167 		n_desc = 6;
15168 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15169 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15170 		desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15171 		desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15172 		desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15173 		desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15174 
15175 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
15176 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15177 		desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15178 		desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15179 		desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15180 		desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15181 		break;
15182 	case SCALAR_GVEC2_SCALAR:
15183 		n_desc = 6;
15184 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15185 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15186 		desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2");
15187 		desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2");
15188 		desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15189 		desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15190 
15191 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15192 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15193 		desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2");
15194 		desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2");
15195 		desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15196 		desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15197 		break;
15198 	case SCALAR_SCALAR_GVEC2:
15199 		n_desc = 6;
15200 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15201 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15202 		desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15203 		desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15204 		desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15205 		desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15206 
15207 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15208 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15209 		desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15210 		desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15211 		desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15212 		desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15213 		break;
15214 	case SCALAR_SCALAR_SCALAR_SCALAR:
15215 		n_desc = 8;
15216 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15217 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15218 		desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15219 		desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15220 		desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15221 		desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15222 		desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15223 		desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15224 
15225 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15226 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15227 		desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15228 		desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15229 		desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15230 		desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15231 		desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15232 		desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15233 		break;
15234 	}
15235 
15236 	for (GLuint i = 0; i < n_desc; ++i)
15237 	{
15238 		const descriptor& in_desc = desc_in[i];
15239 
15240 		Utils::Variable* in =
15241 			prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT);
15242 
15243 		if (Utils::Shader::FRAGMENT != stage)
15244 		{
15245 			const descriptor& out_desc = desc_out[i];
15246 
15247 			Utils::Variable* out =
15248 				prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT);
15249 
15250 			varying_passthrough.Add(stage, in, out);
15251 		}
15252 	}
15253 
15254 	si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
15255 }
15256 
15257 /**
15258  *
15259  **/
15260 Utils::Variable* VaryingComponentsTest::prepareVarying(const Utils::Type& basic_type, const descriptor& desc,
15261 													   const GLchar* interpolation, Utils::ShaderInterface& si,
15262 													   Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15263 {
15264 	const GLuint	   array_length   = getArrayLength();
15265 	const GLuint	   component_size = Utils::Type::_float.GetSize();
15266 	const std::string& name			  = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage);
15267 	const GLuint	   offset		  = desc.m_component * component_size;
15268 	const std::string& qual			  = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation);
15269 	const GLuint	   size			  = desc.m_n_rows * basic_type.GetSize();
15270 	const Utils::Type& type			  = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows);
15271 	Utils::Variable*   var			  = 0;
15272 
15273 	if (Utils::Variable::VARYING_INPUT == storage)
15274 	{
15275 		var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15276 					   desc.m_location /* expected_location */, type, /* built_in_type */
15277 					   GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15278 					   offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15279 	}
15280 	else
15281 	{
15282 		var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15283 						desc.m_location /* expected_location */, type, /* built_in_type */
15284 						GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15285 						offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15286 	}
15287 
15288 	return var;
15289 }
15290 
15291 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar* component_str,
15292 											   glw::GLint location, const glw::GLchar* location_str, glw::GLuint n_rows,
15293 											   const glw::GLchar* name)
15294 {
15295 	m_component		= component;
15296 	m_component_str = component_str;
15297 	m_location		= location;
15298 	m_location_str  = location_str;
15299 	m_n_rows		= n_rows;
15300 	m_name			= name;
15301 }
15302 
15303 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type)
15304 	: m_layout(layout), m_type(type)
15305 {
15306 }
15307 
15308 /** Constructor
15309  *
15310  * @param context Test framework context
15311  **/
15312 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context& context)
15313 	: VaryingComponentsTest(context, "varying_array_components",
15314 							"Test verifies that input and output components are respected for arrays")
15315 {
15316 }
15317 
15318 /** Get length of arrays that should be used during test
15319  *
15320  * @return 4u
15321  **/
15322 GLuint VaryingArrayComponentsTest::getArrayLength()
15323 {
15324 	return 4u;
15325 }
15326 
15327 /** Constructor
15328  *
15329  * @param context Test framework context
15330  **/
15331 VaryingInvalidValueComponentTest::VaryingInvalidValueComponentTest(deqp::Context& context)
15332 	: NegativeTestBase(context, "varying_invalid_value_component", "Test verifies that compiler reports error when "
15333 																   "using an invalid value in the component "
15334 																   "qualification for a specific type")
15335 {
15336 }
15337 
15338 /** Source for given test case and stage
15339  *
15340  * @param test_case_index Index of test case
15341  * @param stage           Shader stage
15342  *
15343  * @return Shader source
15344  **/
15345 std::string VaryingInvalidValueComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15346 {
15347 #if DEBUG_NEG_REMOVE_ERROR
15348 	static const GLchar* var_definition_arr =
15349 		"layout (location = 1 /*, component = COMPONENT */) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15350 	static const GLchar* var_definition_one =
15351 		"layout (location = 1 /*, component = COMPONENT */) FLAT DIRECTION TYPE gokuARRAY;\n";
15352 #else
15353 	static const GLchar* var_definition_arr =
15354 		"layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15355 	static const GLchar* var_definition_one =
15356 		"layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
15357 #endif /* DEBUG_NEG_REMOVE_ERROR */
15358 	static const GLchar* input_use_arr = "    if (TYPE(0) == gokuINDEX[0])\n"
15359 										 "    {\n"
15360 										 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15361 										 "    }\n";
15362 	static const GLchar* input_use_one = "    if (TYPE(0) == gokuINDEX)\n"
15363 										 "    {\n"
15364 										 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15365 										 "    }\n";
15366 	static const GLchar* output_use_arr = "    gokuINDEX[0] = TYPE(0);\n"
15367 										  "    if (vec4(0) == result)\n"
15368 										  "    {\n"
15369 										  "        gokuINDEX[0] = TYPE(1);\n"
15370 										  "    }\n";
15371 	static const GLchar* output_use_one = "    gokuINDEX = TYPE(0);\n"
15372 										  "    if (vec4(0) == result)\n"
15373 										  "    {\n"
15374 										  "        gokuINDEX = TYPE(1);\n"
15375 										  "    }\n";
15376 	static const GLchar* fs = "#version 430 core\n"
15377 							  "#extension GL_ARB_enhanced_layouts : require\n"
15378 							  "\n"
15379 							  "in  vec4 gs_fs;\n"
15380 							  "out vec4 fs_out;\n"
15381 							  "\n"
15382 							  "void main()\n"
15383 							  "{\n"
15384 							  "    fs_out = gs_fs;\n"
15385 							  "}\n"
15386 							  "\n";
15387 	static const GLchar* fs_tested = "#version 430 core\n"
15388 									 "#extension GL_ARB_enhanced_layouts : require\n"
15389 									 "\n"
15390 									 "VAR_DEFINITION"
15391 									 "\n"
15392 									 "in  vec4 gs_fs;\n"
15393 									 "out vec4 fs_out;\n"
15394 									 "\n"
15395 									 "void main()\n"
15396 									 "{\n"
15397 									 "    vec4 result = gs_fs;\n"
15398 									 "\n"
15399 									 "VARIABLE_USE"
15400 									 "\n"
15401 									 "    fs_out += result;\n"
15402 									 "}\n"
15403 									 "\n";
15404 	static const GLchar* gs = "#version 430 core\n"
15405 							  "#extension GL_ARB_enhanced_layouts : require\n"
15406 							  "\n"
15407 							  "layout(points)                           in;\n"
15408 							  "layout(triangle_strip, max_vertices = 4) out;\n"
15409 							  "\n"
15410 							  "in  vec4 tes_gs[];\n"
15411 							  "out vec4 gs_fs;\n"
15412 							  "\n"
15413 							  "void main()\n"
15414 							  "{\n"
15415 							  "    gs_fs = tes_gs[0];\n"
15416 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15417 							  "    EmitVertex();\n"
15418 							  "    gs_fs = tes_gs[0];\n"
15419 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15420 							  "    EmitVertex();\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 							  "}\n"
15428 							  "\n";
15429 	static const GLchar* gs_tested = "#version 430 core\n"
15430 									 "#extension GL_ARB_enhanced_layouts : require\n"
15431 									 "\n"
15432 									 "layout(points)                           in;\n"
15433 									 "layout(triangle_strip, max_vertices = 4) out;\n"
15434 									 "\n"
15435 									 "VAR_DEFINITION"
15436 									 "\n"
15437 									 "in  vec4 tes_gs[];\n"
15438 									 "out vec4 gs_fs;\n"
15439 									 "\n"
15440 									 "void main()\n"
15441 									 "{\n"
15442 									 "    vec4 result = tes_gs[0];\n"
15443 									 "\n"
15444 									 "VARIABLE_USE"
15445 									 "\n"
15446 									 "    gs_fs = result;\n"
15447 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15448 									 "    EmitVertex();\n"
15449 									 "    gs_fs = result;\n"
15450 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15451 									 "    EmitVertex();\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 									 "}\n"
15459 									 "\n";
15460 	static const GLchar* tcs = "#version 430 core\n"
15461 							   "#extension GL_ARB_enhanced_layouts : require\n"
15462 							   "\n"
15463 							   "layout(vertices = 1) out;\n"
15464 							   "\n"
15465 							   "in  vec4 vs_tcs[];\n"
15466 							   "out vec4 tcs_tes[];\n"
15467 							   "\n"
15468 							   "void main()\n"
15469 							   "{\n"
15470 							   "\n"
15471 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15472 							   "\n"
15473 							   "    gl_TessLevelOuter[0] = 1.0;\n"
15474 							   "    gl_TessLevelOuter[1] = 1.0;\n"
15475 							   "    gl_TessLevelOuter[2] = 1.0;\n"
15476 							   "    gl_TessLevelOuter[3] = 1.0;\n"
15477 							   "    gl_TessLevelInner[0] = 1.0;\n"
15478 							   "    gl_TessLevelInner[1] = 1.0;\n"
15479 							   "}\n"
15480 							   "\n";
15481 	static const GLchar* tcs_tested = "#version 430 core\n"
15482 									  "#extension GL_ARB_enhanced_layouts : require\n"
15483 									  "\n"
15484 									  "layout(vertices = 1) out;\n"
15485 									  "\n"
15486 									  "VAR_DEFINITION"
15487 									  "\n"
15488 									  "in  vec4 vs_tcs[];\n"
15489 									  "out vec4 tcs_tes[];\n"
15490 									  "\n"
15491 									  "void main()\n"
15492 									  "{\n"
15493 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
15494 									  "\n"
15495 									  "VARIABLE_USE"
15496 									  "\n"
15497 									  "    tcs_tes[gl_InvocationID] = result;\n"
15498 									  "\n"
15499 									  "    gl_TessLevelOuter[0] = 1.0;\n"
15500 									  "    gl_TessLevelOuter[1] = 1.0;\n"
15501 									  "    gl_TessLevelOuter[2] = 1.0;\n"
15502 									  "    gl_TessLevelOuter[3] = 1.0;\n"
15503 									  "    gl_TessLevelInner[0] = 1.0;\n"
15504 									  "    gl_TessLevelInner[1] = 1.0;\n"
15505 									  "}\n"
15506 									  "\n";
15507 	static const GLchar* tes = "#version 430 core\n"
15508 							   "#extension GL_ARB_enhanced_layouts : require\n"
15509 							   "\n"
15510 							   "layout(isolines, point_mode) in;\n"
15511 							   "\n"
15512 							   "in  vec4 tcs_tes[];\n"
15513 							   "out vec4 tes_gs;\n"
15514 							   "\n"
15515 							   "void main()\n"
15516 							   "{\n"
15517 							   "    tes_gs = tcs_tes[0];\n"
15518 							   "}\n"
15519 							   "\n";
15520 	static const GLchar* tes_tested = "#version 430 core\n"
15521 									  "#extension GL_ARB_enhanced_layouts : require\n"
15522 									  "\n"
15523 									  "layout(isolines, point_mode) in;\n"
15524 									  "\n"
15525 									  "VAR_DEFINITION"
15526 									  "\n"
15527 									  "in  vec4 tcs_tes[];\n"
15528 									  "out vec4 tes_gs;\n"
15529 									  "\n"
15530 									  "void main()\n"
15531 									  "{\n"
15532 									  "    vec4 result = tcs_tes[0];\n"
15533 									  "\n"
15534 									  "VARIABLE_USE"
15535 									  "\n"
15536 									  "    tes_gs += result;\n"
15537 									  "}\n"
15538 									  "\n";
15539 	static const GLchar* vs = "#version 430 core\n"
15540 							  "#extension GL_ARB_enhanced_layouts : require\n"
15541 							  "\n"
15542 							  "in  vec4 in_vs;\n"
15543 							  "out vec4 vs_tcs;\n"
15544 							  "\n"
15545 							  "void main()\n"
15546 							  "{\n"
15547 							  "    vs_tcs = in_vs;\n"
15548 							  "}\n"
15549 							  "\n";
15550 	static const GLchar* vs_tested = "#version 430 core\n"
15551 									 "#extension GL_ARB_enhanced_layouts : require\n"
15552 									 "\n"
15553 									 "VAR_DEFINITION"
15554 									 "\n"
15555 									 "in  vec4 in_vs;\n"
15556 									 "out vec4 vs_tcs;\n"
15557 									 "\n"
15558 									 "void main()\n"
15559 									 "{\n"
15560 									 "    vec4 result = in_vs;\n"
15561 									 "\n"
15562 									 "VARIABLE_USE"
15563 									 "\n"
15564 									 "    vs_tcs += result;\n"
15565 									 "}\n"
15566 									 "\n";
15567 
15568 	std::string source;
15569 	testCase&   test_case = m_test_cases[test_case_index];
15570 
15571 	if (test_case.m_stage == stage)
15572 	{
15573 		const GLchar* array = "";
15574 		GLchar		  buffer[16];
15575 		const GLchar* var_definition = 0;
15576 		const GLchar*			 direction		= "in";
15577 		const GLchar* index			 = "";
15578 		size_t		  position		 = 0;
15579 		const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15580 		const GLchar* var_use   = 0;
15581 		Utils::Variable::STORAGE storage   = Utils::Variable::VARYING_INPUT;
15582 		const GLchar*			 flat	  = "";
15583 
15584 		if (false == test_case.m_is_input)
15585 		{
15586 			direction = "out";
15587 			storage   = Utils::Variable::VARYING_OUTPUT;
15588 
15589 			if (false == test_case.m_is_array)
15590 			{
15591 				var_definition = var_definition_one;
15592 				var_use		   = output_use_one;
15593 			}
15594 			else
15595 			{
15596 				var_definition = var_definition_arr;
15597 				var_use		   = output_use_arr;
15598 			}
15599 		}
15600 		else
15601 		{
15602 			if (false == test_case.m_is_array)
15603 			{
15604 				var_definition = var_definition_one;
15605 				var_use		   = Utils::Shader::VERTEX == stage ? input_use_one : "\n";
15606 			}
15607 			else
15608 			{
15609 				var_definition = var_definition_arr;
15610 				var_use		   = Utils::Shader::VERTEX == stage ? input_use_arr : "\n";
15611 			}
15612 		}
15613 
15614 		if (isFlatRequired(stage, test_case.m_type, storage, true))
15615 		{
15616 			flat = "flat";
15617 		}
15618 
15619 		sprintf(buffer, "%d", test_case.m_component);
15620 
15621 		switch (stage)
15622 		{
15623 		case Utils::Shader::FRAGMENT:
15624 			source = fs_tested;
15625 			break;
15626 		case Utils::Shader::GEOMETRY:
15627 			source = gs_tested;
15628 			array  = test_case.m_is_input ? "[]" : "";
15629 			index  = test_case.m_is_input ? "[0]" : "";
15630 			break;
15631 		case Utils::Shader::TESS_CTRL:
15632 			source = tcs_tested;
15633 			array  = "[]";
15634 			index  = "[gl_InvocationID]";
15635 			break;
15636 		case Utils::Shader::TESS_EVAL:
15637 			source = tes_tested;
15638 			array  = test_case.m_is_input ? "[]" : "";
15639 			index  = test_case.m_is_input ? "[0]" : "";
15640 			break;
15641 		case Utils::Shader::VERTEX:
15642 			source = vs_tested;
15643 			break;
15644 		default:
15645 			TCU_FAIL("Invalid enum");
15646 		}
15647 
15648 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15649 		position = 0;
15650 		Utils::replaceToken("COMPONENT", position, buffer, source);
15651 		Utils::replaceToken("FLAT", position, flat, source);
15652 		Utils::replaceToken("DIRECTION", position, direction, source);
15653 		Utils::replaceToken("ARRAY", position, array, source);
15654 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15655 
15656 		Utils::replaceAllTokens("TYPE", type_name, source);
15657 		Utils::replaceAllTokens("INDEX", index, source);
15658 	}
15659 	else
15660 	{
15661 		switch (stage)
15662 		{
15663 		case Utils::Shader::FRAGMENT:
15664 			source = fs;
15665 			break;
15666 		case Utils::Shader::GEOMETRY:
15667 			source = gs;
15668 			break;
15669 		case Utils::Shader::TESS_CTRL:
15670 			source = tcs;
15671 			break;
15672 		case Utils::Shader::TESS_EVAL:
15673 			source = tes;
15674 			break;
15675 		case Utils::Shader::VERTEX:
15676 			source = vs;
15677 			break;
15678 		default:
15679 			TCU_FAIL("Invalid enum");
15680 		}
15681 	}
15682 
15683 	return source;
15684 }
15685 
15686 /** Get description of test case
15687  *
15688  * @param test_case_index Index of test case
15689  *
15690  * @return Test case description
15691  **/
15692 std::string VaryingInvalidValueComponentTest::getTestCaseName(GLuint test_case_index)
15693 {
15694 	std::stringstream stream;
15695 	testCase&		  test_case = m_test_cases[test_case_index];
15696 
15697 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15698 		   << " type: " << test_case.m_type.GetGLSLTypeName();
15699 
15700 	if (true == test_case.m_is_array)
15701 	{
15702 		stream << "[1]";
15703 	}
15704 
15705 	stream << ", direction: ";
15706 
15707 	if (true == test_case.m_is_input)
15708 	{
15709 		stream << "input";
15710 	}
15711 	else
15712 	{
15713 		stream << "output";
15714 	}
15715 
15716 	stream << ", component: " << test_case.m_component;
15717 
15718 	return stream.str();
15719 }
15720 
15721 /** Get number of test cases
15722  *
15723  * @return Number of test cases
15724  **/
15725 GLuint VaryingInvalidValueComponentTest::getTestCaseNumber()
15726 {
15727 	return static_cast<GLuint>(m_test_cases.size());
15728 }
15729 
15730 /** Selects if "compute" stage is relevant for test
15731  *
15732  * @param ignored
15733  *
15734  * @return false
15735  **/
15736 bool VaryingInvalidValueComponentTest::isComputeRelevant(GLuint /* test_case_index */)
15737 {
15738 	return false;
15739 }
15740 
15741 /** Prepare all test cases
15742  *
15743  **/
15744 void VaryingInvalidValueComponentTest::testInit()
15745 {
15746 	const GLuint n_types = getTypesNumber();
15747 
15748 	for (GLuint i = 0; i < n_types; ++i)
15749 	{
15750 		const Utils::Type&		   type				= getType(i);
15751 		const std::vector<GLuint>& valid_components = type.GetValidComponents();
15752 
15753 		if (valid_components.empty())
15754 		{
15755 			continue;
15756 		}
15757 
15758 		std::vector<GLuint> every_component(4, 0);
15759 		every_component[1] = 1;
15760 		every_component[2] = 2;
15761 		every_component[3] = 3;
15762 		std::vector<GLuint> invalid_components;
15763 
15764 		std::set_symmetric_difference(every_component.begin(), every_component.end(), valid_components.begin(),
15765 									  valid_components.end(), back_inserter(invalid_components));
15766 
15767 		for (std::vector<GLuint>::const_iterator it_invalid_components = invalid_components.begin();
15768 			 it_invalid_components != invalid_components.end(); ++it_invalid_components)
15769 		{
15770 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15771 			{
15772 				if (Utils::Shader::COMPUTE == stage)
15773 				{
15774 					continue;
15775 				}
15776 
15777 				testCase test_case_in_arr = { *it_invalid_components, true, true, (Utils::Shader::STAGES)stage, type };
15778 				testCase test_case_in_one = { *it_invalid_components, true, false, (Utils::Shader::STAGES)stage, type };
15779 				testCase test_case_out_arr = { *it_invalid_components, false, true, (Utils::Shader::STAGES)stage,
15780 											   type };
15781 				testCase test_case_out_one = { *it_invalid_components, false, false, (Utils::Shader::STAGES)stage,
15782 											   type };
15783 
15784 				m_test_cases.push_back(test_case_in_arr);
15785 				m_test_cases.push_back(test_case_in_one);
15786 
15787 				if (Utils::Shader::FRAGMENT != stage)
15788 				{
15789 					m_test_cases.push_back(test_case_out_arr);
15790 					m_test_cases.push_back(test_case_out_one);
15791 				}
15792 			}
15793 		}
15794 	}
15795 }
15796 
15797 /** Constructor
15798  *
15799  * @param context Test framework context
15800  **/
15801 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context& context)
15802 	: NegativeTestBase(context, "varying_exceeding_components",
15803 					   "Test verifies that compiler reports error when component qualifier exceeds limits")
15804 {
15805 }
15806 
15807 /** Source for given test case and stage
15808  *
15809  * @param test_case_index Index of test case
15810  * @param stage           Shader stage
15811  *
15812  * @return Shader source
15813  **/
15814 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15815 {
15816 #if DEBUG_NEG_REMOVE_ERROR
15817 	static const GLchar* var_definition_arr =
15818 		"layout (location = 1 /*, component = 4 */) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15819 	static const GLchar* var_definition_one =
15820 		"layout (location = 1 /*, component = 4 */) FLAT DIRECTION TYPE gokuARRAY;\n";
15821 #else
15822 	static const GLchar* var_definition_arr =
15823 		"layout (location = 1, component = 4) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15824 	static const GLchar* var_definition_one = "layout (location = 1, component = 4) FLAT DIRECTION TYPE gokuARRAY;\n";
15825 #endif /* DEBUG_NEG_REMOVE_ERROR */
15826 	static const GLchar* input_use_arr = "    if (TYPE(0) == gokuINDEX[0])\n"
15827 										 "    {\n"
15828 										 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15829 										 "    }\n";
15830 	static const GLchar* input_use_one = "    if (TYPE(0) == gokuINDEX)\n"
15831 										 "    {\n"
15832 										 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15833 										 "    }\n";
15834 	static const GLchar* output_use_arr = "    gokuINDEX[0] = TYPE(0);\n"
15835 										  "    if (vec4(0) == result)\n"
15836 										  "    {\n"
15837 										  "        gokuINDEX[0] = TYPE(1);\n"
15838 										  "    }\n";
15839 	static const GLchar* output_use_one = "    gokuINDEX = TYPE(0);\n"
15840 										  "    if (vec4(0) == result)\n"
15841 										  "    {\n"
15842 										  "        gokuINDEX = TYPE(1);\n"
15843 										  "    }\n";
15844 	static const GLchar* fs = "#version 430 core\n"
15845 							  "#extension GL_ARB_enhanced_layouts : require\n"
15846 							  "\n"
15847 							  "in  vec4 gs_fs;\n"
15848 							  "out vec4 fs_out;\n"
15849 							  "\n"
15850 							  "void main()\n"
15851 							  "{\n"
15852 							  "    fs_out = gs_fs;\n"
15853 							  "}\n"
15854 							  "\n";
15855 	static const GLchar* fs_tested = "#version 430 core\n"
15856 									 "#extension GL_ARB_enhanced_layouts : require\n"
15857 									 "\n"
15858 									 "VAR_DEFINITION"
15859 									 "\n"
15860 									 "in  vec4 gs_fs;\n"
15861 									 "out vec4 fs_out;\n"
15862 									 "\n"
15863 									 "void main()\n"
15864 									 "{\n"
15865 									 "    vec4 result = gs_fs;\n"
15866 									 "\n"
15867 									 "VARIABLE_USE"
15868 									 "\n"
15869 									 "    fs_out += result;\n"
15870 									 "}\n"
15871 									 "\n";
15872 	static const GLchar* gs = "#version 430 core\n"
15873 							  "#extension GL_ARB_enhanced_layouts : require\n"
15874 							  "\n"
15875 							  "layout(points)                           in;\n"
15876 							  "layout(triangle_strip, max_vertices = 4) out;\n"
15877 							  "\n"
15878 							  "in  vec4 tes_gs[];\n"
15879 							  "out vec4 gs_fs;\n"
15880 							  "\n"
15881 							  "void main()\n"
15882 							  "{\n"
15883 							  "    gs_fs = tes_gs[0];\n"
15884 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15885 							  "    EmitVertex();\n"
15886 							  "    gs_fs = tes_gs[0];\n"
15887 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15888 							  "    EmitVertex();\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 							  "}\n"
15896 							  "\n";
15897 	static const GLchar* gs_tested = "#version 430 core\n"
15898 									 "#extension GL_ARB_enhanced_layouts : require\n"
15899 									 "\n"
15900 									 "layout(points)                           in;\n"
15901 									 "layout(triangle_strip, max_vertices = 4) out;\n"
15902 									 "\n"
15903 									 "VAR_DEFINITION"
15904 									 "\n"
15905 									 "in  vec4 tes_gs[];\n"
15906 									 "out vec4 gs_fs;\n"
15907 									 "\n"
15908 									 "void main()\n"
15909 									 "{\n"
15910 									 "    vec4 result = tes_gs[0];\n"
15911 									 "\n"
15912 									 "VARIABLE_USE"
15913 									 "\n"
15914 									 "    gs_fs = result;\n"
15915 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15916 									 "    EmitVertex();\n"
15917 									 "    gs_fs = result;\n"
15918 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15919 									 "    EmitVertex();\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 									 "}\n"
15927 									 "\n";
15928 	static const GLchar* tcs = "#version 430 core\n"
15929 							   "#extension GL_ARB_enhanced_layouts : require\n"
15930 							   "\n"
15931 							   "layout(vertices = 1) out;\n"
15932 							   "\n"
15933 							   "in  vec4 vs_tcs[];\n"
15934 							   "out vec4 tcs_tes[];\n"
15935 							   "\n"
15936 							   "void main()\n"
15937 							   "{\n"
15938 							   "\n"
15939 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15940 							   "\n"
15941 							   "    gl_TessLevelOuter[0] = 1.0;\n"
15942 							   "    gl_TessLevelOuter[1] = 1.0;\n"
15943 							   "    gl_TessLevelOuter[2] = 1.0;\n"
15944 							   "    gl_TessLevelOuter[3] = 1.0;\n"
15945 							   "    gl_TessLevelInner[0] = 1.0;\n"
15946 							   "    gl_TessLevelInner[1] = 1.0;\n"
15947 							   "}\n"
15948 							   "\n";
15949 	static const GLchar* tcs_tested = "#version 430 core\n"
15950 									  "#extension GL_ARB_enhanced_layouts : require\n"
15951 									  "\n"
15952 									  "layout(vertices = 1) out;\n"
15953 									  "\n"
15954 									  "VAR_DEFINITION"
15955 									  "\n"
15956 									  "in  vec4 vs_tcs[];\n"
15957 									  "out vec4 tcs_tes[];\n"
15958 									  "\n"
15959 									  "void main()\n"
15960 									  "{\n"
15961 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
15962 									  "\n"
15963 									  "VARIABLE_USE"
15964 									  "\n"
15965 									  "    tcs_tes[gl_InvocationID] = result;\n"
15966 									  "\n"
15967 									  "    gl_TessLevelOuter[0] = 1.0;\n"
15968 									  "    gl_TessLevelOuter[1] = 1.0;\n"
15969 									  "    gl_TessLevelOuter[2] = 1.0;\n"
15970 									  "    gl_TessLevelOuter[3] = 1.0;\n"
15971 									  "    gl_TessLevelInner[0] = 1.0;\n"
15972 									  "    gl_TessLevelInner[1] = 1.0;\n"
15973 									  "}\n"
15974 									  "\n";
15975 	static const GLchar* tes = "#version 430 core\n"
15976 							   "#extension GL_ARB_enhanced_layouts : require\n"
15977 							   "\n"
15978 							   "layout(isolines, point_mode) in;\n"
15979 							   "\n"
15980 							   "in  vec4 tcs_tes[];\n"
15981 							   "out vec4 tes_gs;\n"
15982 							   "\n"
15983 							   "void main()\n"
15984 							   "{\n"
15985 							   "    tes_gs = tcs_tes[0];\n"
15986 							   "}\n"
15987 							   "\n";
15988 	static const GLchar* tes_tested = "#version 430 core\n"
15989 									  "#extension GL_ARB_enhanced_layouts : require\n"
15990 									  "\n"
15991 									  "layout(isolines, point_mode) in;\n"
15992 									  "\n"
15993 									  "VAR_DEFINITION"
15994 									  "\n"
15995 									  "in  vec4 tcs_tes[];\n"
15996 									  "out vec4 tes_gs;\n"
15997 									  "\n"
15998 									  "void main()\n"
15999 									  "{\n"
16000 									  "    vec4 result = tcs_tes[0];\n"
16001 									  "\n"
16002 									  "VARIABLE_USE"
16003 									  "\n"
16004 									  "    tes_gs += result;\n"
16005 									  "}\n"
16006 									  "\n";
16007 	static const GLchar* vs = "#version 430 core\n"
16008 							  "#extension GL_ARB_enhanced_layouts : require\n"
16009 							  "\n"
16010 							  "in  vec4 in_vs;\n"
16011 							  "out vec4 vs_tcs;\n"
16012 							  "\n"
16013 							  "void main()\n"
16014 							  "{\n"
16015 							  "    vs_tcs = in_vs;\n"
16016 							  "}\n"
16017 							  "\n";
16018 	static const GLchar* vs_tested = "#version 430 core\n"
16019 									 "#extension GL_ARB_enhanced_layouts : require\n"
16020 									 "\n"
16021 									 "VAR_DEFINITION"
16022 									 "\n"
16023 									 "in  vec4 in_vs;\n"
16024 									 "out vec4 vs_tcs;\n"
16025 									 "\n"
16026 									 "void main()\n"
16027 									 "{\n"
16028 									 "    vec4 result = in_vs;\n"
16029 									 "\n"
16030 									 "VARIABLE_USE"
16031 									 "\n"
16032 									 "    vs_tcs += result;\n"
16033 									 "}\n"
16034 									 "\n";
16035 
16036 	std::string source;
16037 	testCase&   test_case = m_test_cases[test_case_index];
16038 
16039 	if (test_case.m_stage == stage)
16040 	{
16041 		const GLchar*			 array			= "";
16042 		const GLchar*			 var_definition = 0;
16043 		const GLchar*			 direction		= "in";
16044 		const GLchar*			 index			= "";
16045 		size_t					 position		= 0;
16046 		const GLchar*			 type_name		= test_case.m_type.GetGLSLTypeName();
16047 		const GLchar*			 var_use		= 0;
16048 		Utils::Variable::STORAGE storage		= Utils::Variable::VARYING_INPUT;
16049 		const GLchar*			 flat			= "";
16050 
16051 		if (false == test_case.m_is_input)
16052 		{
16053 			direction = "out";
16054 			storage   = Utils::Variable::VARYING_OUTPUT;
16055 
16056 			if (false == test_case.m_is_array)
16057 			{
16058 				var_definition = var_definition_one;
16059 				var_use		   = output_use_one;
16060 			}
16061 			else
16062 			{
16063 				var_definition = var_definition_arr;
16064 				var_use		   = output_use_arr;
16065 			}
16066 		}
16067 		else
16068 		{
16069 			if (false == test_case.m_is_array)
16070 			{
16071 				var_definition = var_definition_one;
16072 				var_use		   = Utils::Shader::VERTEX == stage ? input_use_one : "\n";
16073 			}
16074 			else
16075 			{
16076 				var_definition = var_definition_arr;
16077 				var_use		   = Utils::Shader::VERTEX == stage ? input_use_arr : "\n";
16078 			}
16079 		}
16080 
16081 		if (isFlatRequired(stage, test_case.m_type, storage, true))
16082 		{
16083 			flat = "flat";
16084 		}
16085 
16086 		switch (stage)
16087 		{
16088 		case Utils::Shader::FRAGMENT:
16089 			source = fs_tested;
16090 			break;
16091 		case Utils::Shader::GEOMETRY:
16092 			source = gs_tested;
16093 			array  = test_case.m_is_input ? "[]" : "";
16094 			index  = test_case.m_is_input ? "[0]" : "";
16095 			break;
16096 		case Utils::Shader::TESS_CTRL:
16097 			source = tcs_tested;
16098 			array  = "[]";
16099 			index  = "[gl_InvocationID]";
16100 			break;
16101 		case Utils::Shader::TESS_EVAL:
16102 			source = tes_tested;
16103 			array  = test_case.m_is_input ? "[]" : "";
16104 			index  = test_case.m_is_input ? "[0]" : "";
16105 			break;
16106 		case Utils::Shader::VERTEX:
16107 			source = vs_tested;
16108 			break;
16109 		default:
16110 			TCU_FAIL("Invalid enum");
16111 		}
16112 
16113 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16114 		position = 0;
16115 		Utils::replaceToken("FLAT", position, flat, source);
16116 		Utils::replaceToken("DIRECTION", position, direction, source);
16117 		Utils::replaceToken("ARRAY", position, array, source);
16118 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16119 
16120 		Utils::replaceAllTokens("TYPE", type_name, source);
16121 		Utils::replaceAllTokens("INDEX", index, source);
16122 	}
16123 	else
16124 	{
16125 		switch (stage)
16126 		{
16127 		case Utils::Shader::FRAGMENT:
16128 			source = fs;
16129 			break;
16130 		case Utils::Shader::GEOMETRY:
16131 			source = gs;
16132 			break;
16133 		case Utils::Shader::TESS_CTRL:
16134 			source = tcs;
16135 			break;
16136 		case Utils::Shader::TESS_EVAL:
16137 			source = tes;
16138 			break;
16139 		case Utils::Shader::VERTEX:
16140 			source = vs;
16141 			break;
16142 		default:
16143 			TCU_FAIL("Invalid enum");
16144 		}
16145 	}
16146 
16147 	return source;
16148 }
16149 
16150 /** Get description of test case
16151  *
16152  * @param test_case_index Index of test case
16153  *
16154  * @return Test case description
16155  **/
16156 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index)
16157 {
16158 	std::stringstream stream;
16159 	testCase&		  test_case = m_test_cases[test_case_index];
16160 
16161 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16162 		   << " type: " << test_case.m_type.GetGLSLTypeName();
16163 
16164 	if (true == test_case.m_is_array)
16165 	{
16166 		stream << "[1]";
16167 	}
16168 
16169 	stream << ", direction: ";
16170 
16171 	if (true == test_case.m_is_input)
16172 	{
16173 		stream << "input";
16174 	}
16175 	else
16176 	{
16177 		stream << "output";
16178 	}
16179 
16180 	return stream.str();
16181 }
16182 
16183 /** Get number of test cases
16184  *
16185  * @return Number of test cases
16186  **/
16187 GLuint VaryingExceedingComponentsTest::getTestCaseNumber()
16188 {
16189 	return static_cast<GLuint>(m_test_cases.size());
16190 }
16191 
16192 /** Selects if "compute" stage is relevant for test
16193  *
16194  * @param ignored
16195  *
16196  * @return false
16197  **/
16198 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */)
16199 {
16200 	return false;
16201 }
16202 
16203 /** Prepare all test cases
16204  *
16205  **/
16206 void VaryingExceedingComponentsTest::testInit()
16207 {
16208 	const GLuint		n_types					  = getTypesNumber();
16209 
16210 	for (GLuint i = 0; i < n_types; ++i)
16211 	{
16212 		const Utils::Type&		   type				= getType(i);
16213 		const std::vector<GLuint>& valid_components = type.GetValidComponents();
16214 
16215 		if (valid_components.empty())
16216 		{
16217 			continue;
16218 		}
16219 
16220 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16221 		{
16222 			if (Utils::Shader::COMPUTE == stage)
16223 			{
16224 				continue;
16225 			}
16226 
16227 			testCase test_case_in_arr  = { true, true, (Utils::Shader::STAGES)stage, type };
16228 			testCase test_case_in_one  = { true, false, (Utils::Shader::STAGES)stage, type };
16229 			testCase test_case_out_arr = { false, true, (Utils::Shader::STAGES)stage, type };
16230 			testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage, type };
16231 
16232 			m_test_cases.push_back(test_case_in_arr);
16233 			m_test_cases.push_back(test_case_in_one);
16234 
16235 			if (Utils::Shader::FRAGMENT != stage)
16236 			{
16237 				m_test_cases.push_back(test_case_out_arr);
16238 				m_test_cases.push_back(test_case_out_one);
16239 			}
16240 		}
16241 	}
16242 }
16243 
16244 /** Constructor
16245  *
16246  * @param context Test framework context
16247  **/
16248 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context& context)
16249 	: NegativeTestBase(context, "varying_component_without_location",
16250 					   "Test verifies that compiler reports error when component qualifier is used without location")
16251 {
16252 }
16253 
16254 /** Source for given test case and stage
16255  *
16256  * @param test_case_index Index of test case
16257  * @param stage           Shader stage
16258  *
16259  * @return Shader source
16260  **/
16261 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16262 {
16263 #if DEBUG_NEG_REMOVE_ERROR
16264 	static const GLchar* var_definition = "/* layout (component = COMPONENT) */ FLAT DIRECTION TYPE gokuARRAY;\n";
16265 #else
16266 	static const GLchar* var_definition = "layout (component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
16267 #endif /* DEBUG_NEG_REMOVE_ERROR */
16268 	static const GLchar* input_use		= "    if (TYPE(0) == gokuINDEX)\n"
16269 									 "    {\n"
16270 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
16271 									 "    }\n";
16272 	static const GLchar* output_use = "    gokuINDEX = TYPE(0);\n"
16273 									  "    if (vec4(0) == result)\n"
16274 									  "    {\n"
16275 									  "        gokuINDEX = TYPE(1);\n"
16276 									  "    }\n";
16277 	static const GLchar* fs = "#version 430 core\n"
16278 							  "#extension GL_ARB_enhanced_layouts : require\n"
16279 							  "\n"
16280 							  "in  vec4 gs_fs;\n"
16281 							  "out vec4 fs_out;\n"
16282 							  "\n"
16283 							  "void main()\n"
16284 							  "{\n"
16285 							  "    fs_out = gs_fs;\n"
16286 							  "}\n"
16287 							  "\n";
16288 	static const GLchar* fs_tested = "#version 430 core\n"
16289 									 "#extension GL_ARB_enhanced_layouts : require\n"
16290 									 "\n"
16291 									 "VAR_DEFINITION"
16292 									 "\n"
16293 									 "in  vec4 gs_fs;\n"
16294 									 "out vec4 fs_out;\n"
16295 									 "\n"
16296 									 "void main()\n"
16297 									 "{\n"
16298 									 "    vec4 result = gs_fs;\n"
16299 									 "\n"
16300 									 "VARIABLE_USE"
16301 									 "\n"
16302 									 "    fs_out = result;\n"
16303 									 "}\n"
16304 									 "\n";
16305 	static const GLchar* gs = "#version 430 core\n"
16306 							  "#extension GL_ARB_enhanced_layouts : require\n"
16307 							  "\n"
16308 							  "layout(points)                           in;\n"
16309 							  "layout(triangle_strip, max_vertices = 4) out;\n"
16310 							  "\n"
16311 							  "in  vec4 tes_gs[];\n"
16312 							  "out vec4 gs_fs;\n"
16313 							  "\n"
16314 							  "void main()\n"
16315 							  "{\n"
16316 							  "    gs_fs = tes_gs[0];\n"
16317 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16318 							  "    EmitVertex();\n"
16319 							  "    gs_fs = tes_gs[0];\n"
16320 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16321 							  "    EmitVertex();\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 							  "}\n"
16329 							  "\n";
16330 	static const GLchar* gs_tested = "#version 430 core\n"
16331 									 "#extension GL_ARB_enhanced_layouts : require\n"
16332 									 "\n"
16333 									 "layout(points)                           in;\n"
16334 									 "layout(triangle_strip, max_vertices = 4) out;\n"
16335 									 "\n"
16336 									 "VAR_DEFINITION"
16337 									 "\n"
16338 									 "in  vec4 tes_gs[];\n"
16339 									 "out vec4 gs_fs;\n"
16340 									 "\n"
16341 									 "void main()\n"
16342 									 "{\n"
16343 									 "    vec4 result = tes_gs[0];\n"
16344 									 "\n"
16345 									 "VARIABLE_USE"
16346 									 "\n"
16347 									 "    gs_fs = result;\n"
16348 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16349 									 "    EmitVertex();\n"
16350 									 "    gs_fs = result;\n"
16351 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16352 									 "    EmitVertex();\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 									 "}\n"
16360 									 "\n";
16361 	static const GLchar* tcs = "#version 430 core\n"
16362 							   "#extension GL_ARB_enhanced_layouts : require\n"
16363 							   "\n"
16364 							   "layout(vertices = 1) out;\n"
16365 							   "\n"
16366 							   "in  vec4 vs_tcs[];\n"
16367 							   "out vec4 tcs_tes[];\n"
16368 							   "\n"
16369 							   "void main()\n"
16370 							   "{\n"
16371 							   "\n"
16372 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16373 							   "\n"
16374 							   "    gl_TessLevelOuter[0] = 1.0;\n"
16375 							   "    gl_TessLevelOuter[1] = 1.0;\n"
16376 							   "    gl_TessLevelOuter[2] = 1.0;\n"
16377 							   "    gl_TessLevelOuter[3] = 1.0;\n"
16378 							   "    gl_TessLevelInner[0] = 1.0;\n"
16379 							   "    gl_TessLevelInner[1] = 1.0;\n"
16380 							   "}\n"
16381 							   "\n";
16382 	static const GLchar* tcs_tested = "#version 430 core\n"
16383 									  "#extension GL_ARB_enhanced_layouts : require\n"
16384 									  "\n"
16385 									  "layout(vertices = 1) out;\n"
16386 									  "\n"
16387 									  "VAR_DEFINITION"
16388 									  "\n"
16389 									  "in  vec4 vs_tcs[];\n"
16390 									  "out vec4 tcs_tes[];\n"
16391 									  "\n"
16392 									  "void main()\n"
16393 									  "{\n"
16394 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
16395 									  "\n"
16396 									  "VARIABLE_USE"
16397 									  "\n"
16398 									  "    tcs_tes[gl_InvocationID] = result;\n"
16399 									  "\n"
16400 									  "    gl_TessLevelOuter[0] = 1.0;\n"
16401 									  "    gl_TessLevelOuter[1] = 1.0;\n"
16402 									  "    gl_TessLevelOuter[2] = 1.0;\n"
16403 									  "    gl_TessLevelOuter[3] = 1.0;\n"
16404 									  "    gl_TessLevelInner[0] = 1.0;\n"
16405 									  "    gl_TessLevelInner[1] = 1.0;\n"
16406 									  "}\n"
16407 									  "\n";
16408 	static const GLchar* tes = "#version 430 core\n"
16409 							   "#extension GL_ARB_enhanced_layouts : require\n"
16410 							   "\n"
16411 							   "layout(isolines, point_mode) in;\n"
16412 							   "\n"
16413 							   "in  vec4 tcs_tes[];\n"
16414 							   "out vec4 tes_gs;\n"
16415 							   "\n"
16416 							   "void main()\n"
16417 							   "{\n"
16418 							   "    tes_gs = tcs_tes[0];\n"
16419 							   "}\n"
16420 							   "\n";
16421 	static const GLchar* tes_tested = "#version 430 core\n"
16422 									  "#extension GL_ARB_enhanced_layouts : require\n"
16423 									  "\n"
16424 									  "layout(isolines, point_mode) in;\n"
16425 									  "\n"
16426 									  "VAR_DEFINITION"
16427 									  "\n"
16428 									  "in  vec4 tcs_tes[];\n"
16429 									  "out vec4 tes_gs;\n"
16430 									  "\n"
16431 									  "void main()\n"
16432 									  "{\n"
16433 									  "    vec4 result = tcs_tes[0];\n"
16434 									  "\n"
16435 									  "VARIABLE_USE"
16436 									  "\n"
16437 									  "    tes_gs = result;\n"
16438 									  "}\n"
16439 									  "\n";
16440 	static const GLchar* vs = "#version 430 core\n"
16441 							  "#extension GL_ARB_enhanced_layouts : require\n"
16442 							  "\n"
16443 							  "in  vec4 in_vs;\n"
16444 							  "out vec4 vs_tcs;\n"
16445 							  "\n"
16446 							  "void main()\n"
16447 							  "{\n"
16448 							  "    vs_tcs = in_vs;\n"
16449 							  "}\n"
16450 							  "\n";
16451 	static const GLchar* vs_tested = "#version 430 core\n"
16452 									 "#extension GL_ARB_enhanced_layouts : require\n"
16453 									 "\n"
16454 									 "VAR_DEFINITION"
16455 									 "\n"
16456 									 "in  vec4 in_vs;\n"
16457 									 "out vec4 vs_tcs;\n"
16458 									 "\n"
16459 									 "void main()\n"
16460 									 "{\n"
16461 									 "    vec4 result = in_vs;\n"
16462 									 "\n"
16463 									 "VARIABLE_USE"
16464 									 "\n"
16465 									 "    vs_tcs = result;\n"
16466 									 "}\n"
16467 									 "\n";
16468 
16469 	std::string source;
16470 	testCase&   test_case = m_test_cases[test_case_index];
16471 
16472 	if (test_case.m_stage == stage)
16473 	{
16474 		const GLchar* array = "";
16475 		GLchar		  buffer[16];
16476 		const GLchar*			 direction = "in";
16477 		const GLchar* index		= "";
16478 		size_t		  position  = 0;
16479 		const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16480 		const GLchar*			 var_use   = Utils::Shader::VERTEX == stage ? input_use : "\n";
16481 		Utils::Variable::STORAGE storage   = Utils::Variable::VARYING_INPUT;
16482 		const GLchar*			 flat	  = "";
16483 
16484 		if (false == test_case.m_is_input)
16485 		{
16486 			direction = "out";
16487 			storage   = Utils::Variable::VARYING_OUTPUT;
16488 			var_use   = output_use;
16489 		}
16490 
16491 		if (isFlatRequired(stage, test_case.m_type, storage, true))
16492 		{
16493 			flat = "flat";
16494 		}
16495 
16496 		sprintf(buffer, "%d", test_case.m_component);
16497 
16498 		switch (stage)
16499 		{
16500 		case Utils::Shader::FRAGMENT:
16501 			source = fs_tested;
16502 			break;
16503 		case Utils::Shader::GEOMETRY:
16504 			source = gs_tested;
16505 			array  = test_case.m_is_input ? "[]" : "";
16506 			index  = test_case.m_is_input ? "[0]" : "";
16507 			break;
16508 		case Utils::Shader::TESS_CTRL:
16509 			source = tcs_tested;
16510 			array  = "[]";
16511 			index  = "[gl_InvocationID]";
16512 			break;
16513 		case Utils::Shader::TESS_EVAL:
16514 			source = tes_tested;
16515 			array  = test_case.m_is_input ? "[]" : "";
16516 			index  = test_case.m_is_input ? "[0]" : "";
16517 			break;
16518 		case Utils::Shader::VERTEX:
16519 			source = vs_tested;
16520 			break;
16521 		default:
16522 			TCU_FAIL("Invalid enum");
16523 		}
16524 
16525 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16526 		position = 0;
16527 		Utils::replaceToken("COMPONENT", position, buffer, source);
16528 		Utils::replaceToken("FLAT", position, flat, source);
16529 		Utils::replaceToken("DIRECTION", position, direction, source);
16530 		Utils::replaceToken("ARRAY", position, array, source);
16531 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16532 
16533 		Utils::replaceAllTokens("TYPE", type_name, source);
16534 		Utils::replaceAllTokens("INDEX", index, source);
16535 	}
16536 	else
16537 	{
16538 		switch (stage)
16539 		{
16540 		case Utils::Shader::FRAGMENT:
16541 			source = fs;
16542 			break;
16543 		case Utils::Shader::GEOMETRY:
16544 			source = gs;
16545 			break;
16546 		case Utils::Shader::TESS_CTRL:
16547 			source = tcs;
16548 			break;
16549 		case Utils::Shader::TESS_EVAL:
16550 			source = tes;
16551 			break;
16552 		case Utils::Shader::VERTEX:
16553 			source = vs;
16554 			break;
16555 		default:
16556 			TCU_FAIL("Invalid enum");
16557 		}
16558 	}
16559 
16560 	return source;
16561 }
16562 
16563 /** Get description of test case
16564  *
16565  * @param test_case_index Index of test case
16566  *
16567  * @return Test case description
16568  **/
16569 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index)
16570 {
16571 	std::stringstream stream;
16572 	testCase&		  test_case = m_test_cases[test_case_index];
16573 
16574 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16575 		   << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
16576 
16577 	if (true == test_case.m_is_input)
16578 	{
16579 		stream << "input";
16580 	}
16581 	else
16582 	{
16583 		stream << "output";
16584 	}
16585 
16586 	stream << ", component: " << test_case.m_component;
16587 
16588 	return stream.str();
16589 }
16590 
16591 /** Get number of test cases
16592  *
16593  * @return Number of test cases
16594  **/
16595 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber()
16596 {
16597 	return static_cast<GLuint>(m_test_cases.size());
16598 }
16599 
16600 /** Selects if "compute" stage is relevant for test
16601  *
16602  * @param ignored
16603  *
16604  * @return false
16605  **/
16606 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */)
16607 {
16608 	return false;
16609 }
16610 
16611 /** Prepare all test cases
16612  *
16613  **/
16614 void VaryingComponentWithoutLocationTest::testInit()
16615 {
16616 	const GLuint		n_types					  = getTypesNumber();
16617 
16618 	for (GLuint i = 0; i < n_types; ++i)
16619 	{
16620 		const Utils::Type&		   type				= getType(i);
16621 		const std::vector<GLuint>& valid_components = type.GetValidComponents();
16622 
16623 		if (valid_components.empty())
16624 		{
16625 			continue;
16626 		}
16627 
16628 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16629 		{
16630 			if (Utils::Shader::COMPUTE == stage)
16631 			{
16632 				continue;
16633 			}
16634 
16635 			testCase test_case_in  = { valid_components.back(), true, (Utils::Shader::STAGES)stage, type };
16636 			testCase test_case_out = { valid_components.back(), false, (Utils::Shader::STAGES)stage, type };
16637 
16638 			m_test_cases.push_back(test_case_in);
16639 
16640 			if (Utils::Shader::FRAGMENT != stage)
16641 			{
16642 				m_test_cases.push_back(test_case_out);
16643 			}
16644 		}
16645 	}
16646 }
16647 
16648 /** Constructor
16649  *
16650  * @param context Test framework context
16651  **/
16652 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context& context)
16653 	: NegativeTestBase(context, "varying_component_of_invalid_type",
16654 					   "Test verifies that compiler reports error when component qualifier is used for invalid type")
16655 {
16656 }
16657 
16658 /** Source for given test case and stage
16659  *
16660  * @param test_case_index Index of test case
16661  * @param stage           Shader stage
16662  *
16663  * @return Shader source
16664  **/
16665 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16666 {
16667 	static const GLchar* block_definition_arr = "layout (location = 1COMPONENT) DIRECTION Goku {\n"
16668 												"    FLAT TYPE member;\n"
16669 												"} gokuARRAY[1];\n";
16670 	static const GLchar* block_definition_one = "layout (location = 1COMPONENT) DIRECTION Goku {\n"
16671 												"    FLAT TYPE member;\n"
16672 												"} gokuARRAY;\n";
16673 	static const GLchar* matrix_dvec3_dvec4_definition_arr =
16674 		"layout (location = 1COMPONENT) FLAT DIRECTION TYPE gokuARRAY[1];\n";
16675 	static const GLchar* matrix_dvec3_dvec4_definition_one =
16676 		"layout (location = 1COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
16677 	static const GLchar* struct_definition_arr = "struct Goku {\n"
16678 												 "    TYPE member;\n"
16679 												 "};\n"
16680 												 "\n"
16681 												 "layout (location = 1COMPONENT) FLAT DIRECTION Goku gokuARRAY[1];\n";
16682 	static const GLchar* struct_definition_one = "struct Goku {\n"
16683 												 "    TYPE member;\n"
16684 												 "};\n"
16685 												 "\n"
16686 												 "layout (location = 1COMPONENT) FLAT DIRECTION Goku gokuARRAY;\n";
16687 	static const GLchar* matrix_dvec3_dvec4_input_use_arr = "    if (TYPE(0) == gokuINDEX[0])\n"
16688 															"    {\n"
16689 															"        result += vec4(1, 0.5, 0.25, 0.125);\n"
16690 															"    }\n";
16691 	static const GLchar* matrix_dvec3_dvec4_input_use_one = "    if (TYPE(0) == gokuINDEX)\n"
16692 															"    {\n"
16693 															"        result += vec4(1, 0.5, 0.25, 0.125);\n"
16694 															"    }\n";
16695 	static const GLchar* matrix_dvec3_dvec4_output_use_arr = "    gokuINDEX[0] = TYPE(0);\n"
16696 															 "    if (vec4(0) == result)\n"
16697 															 "    {\n"
16698 															 "        gokuINDEX[0] = TYPE(1);\n"
16699 															 "    }\n";
16700 	static const GLchar* matrix_dvec3_dvec4_output_use_one = "    gokuINDEX = TYPE(0);\n"
16701 															 "    if (vec4(0) == result)\n"
16702 															 "    {\n"
16703 															 "        gokuINDEX = TYPE(1);\n"
16704 															 "    }\n";
16705 	static const GLchar* member_input_use_arr = "    if (TYPE(0) == gokuINDEX[0].member)\n"
16706 												"    {\n"
16707 												"        result += vec4(1, 0.5, 0.25, 0.125);\n"
16708 												"    }\n";
16709 	static const GLchar* member_input_use_one = "    if (TYPE(0) == gokuINDEX.member)\n"
16710 												"    {\n"
16711 												"        result += vec4(1, 0.5, 0.25, 0.125);\n"
16712 												"    }\n";
16713 	static const GLchar* member_output_use_arr = "    gokuINDEX[0].member = TYPE(0);\n"
16714 												 "    if (vec4(0) == result)\n"
16715 												 "    {\n"
16716 												 "        gokuINDEX[0].member = TYPE(1);\n"
16717 												 "    }\n";
16718 	static const GLchar* member_output_use_one = "    gokuINDEX.member = TYPE(0);\n"
16719 												 "    if (vec4(0) == result)\n"
16720 												 "    {\n"
16721 												 "        gokuINDEX.member = TYPE(1);\n"
16722 												 "    }\n";
16723 	static const GLchar* fs = "#version 430 core\n"
16724 							  "#extension GL_ARB_enhanced_layouts : require\n"
16725 							  "\n"
16726 							  "in  vec4 gs_fs;\n"
16727 							  "out vec4 fs_out;\n"
16728 							  "\n"
16729 							  "void main()\n"
16730 							  "{\n"
16731 							  "    fs_out = gs_fs;\n"
16732 							  "}\n"
16733 							  "\n";
16734 	static const GLchar* fs_tested = "#version 430 core\n"
16735 									 "#extension GL_ARB_enhanced_layouts : require\n"
16736 									 "\n"
16737 									 "VAR_DEFINITION"
16738 									 "\n"
16739 									 "in  vec4 gs_fs;\n"
16740 									 "out vec4 fs_out;\n"
16741 									 "\n"
16742 									 "void main()\n"
16743 									 "{\n"
16744 									 "    vec4 result = gs_fs;\n"
16745 									 "\n"
16746 									 "VARIABLE_USE"
16747 									 "\n"
16748 									 "    fs_out += result;\n"
16749 									 "}\n"
16750 									 "\n";
16751 	static const GLchar* gs = "#version 430 core\n"
16752 							  "#extension GL_ARB_enhanced_layouts : require\n"
16753 							  "\n"
16754 							  "layout(points)                           in;\n"
16755 							  "layout(triangle_strip, max_vertices = 4) out;\n"
16756 							  "\n"
16757 							  "in  vec4 tes_gs[];\n"
16758 							  "out vec4 gs_fs;\n"
16759 							  "\n"
16760 							  "void main()\n"
16761 							  "{\n"
16762 							  "    gs_fs = tes_gs[0];\n"
16763 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16764 							  "    EmitVertex();\n"
16765 							  "    gs_fs = tes_gs[0];\n"
16766 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16767 							  "    EmitVertex();\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 							  "}\n"
16775 							  "\n";
16776 	static const GLchar* gs_tested = "#version 430 core\n"
16777 									 "#extension GL_ARB_enhanced_layouts : require\n"
16778 									 "\n"
16779 									 "layout(points)                           in;\n"
16780 									 "layout(triangle_strip, max_vertices = 4) out;\n"
16781 									 "\n"
16782 									 "VAR_DEFINITION"
16783 									 "\n"
16784 									 "in  vec4 tes_gs[];\n"
16785 									 "out vec4 gs_fs;\n"
16786 									 "\n"
16787 									 "void main()\n"
16788 									 "{\n"
16789 									 "    vec4 result = tes_gs[0];\n"
16790 									 "\n"
16791 									 "VARIABLE_USE"
16792 									 "\n"
16793 									 "    gs_fs = result;\n"
16794 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16795 									 "    EmitVertex();\n"
16796 									 "    gs_fs = result;\n"
16797 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16798 									 "    EmitVertex();\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 									 "}\n"
16806 									 "\n";
16807 	static const GLchar* tcs = "#version 430 core\n"
16808 							   "#extension GL_ARB_enhanced_layouts : require\n"
16809 							   "\n"
16810 							   "layout(vertices = 1) out;\n"
16811 							   "\n"
16812 							   "in  vec4 vs_tcs[];\n"
16813 							   "out vec4 tcs_tes[];\n"
16814 							   "\n"
16815 							   "void main()\n"
16816 							   "{\n"
16817 							   "\n"
16818 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16819 							   "\n"
16820 							   "    gl_TessLevelOuter[0] = 1.0;\n"
16821 							   "    gl_TessLevelOuter[1] = 1.0;\n"
16822 							   "    gl_TessLevelOuter[2] = 1.0;\n"
16823 							   "    gl_TessLevelOuter[3] = 1.0;\n"
16824 							   "    gl_TessLevelInner[0] = 1.0;\n"
16825 							   "    gl_TessLevelInner[1] = 1.0;\n"
16826 							   "}\n"
16827 							   "\n";
16828 	static const GLchar* tcs_tested = "#version 430 core\n"
16829 									  "#extension GL_ARB_enhanced_layouts : require\n"
16830 									  "\n"
16831 									  "layout(vertices = 1) out;\n"
16832 									  "\n"
16833 									  "VAR_DEFINITION"
16834 									  "\n"
16835 									  "in  vec4 vs_tcs[];\n"
16836 									  "out vec4 tcs_tes[];\n"
16837 									  "\n"
16838 									  "void main()\n"
16839 									  "{\n"
16840 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
16841 									  "\n"
16842 									  "VARIABLE_USE"
16843 									  "\n"
16844 									  "    tcs_tes[gl_InvocationID] = result;\n"
16845 									  "\n"
16846 									  "    gl_TessLevelOuter[0] = 1.0;\n"
16847 									  "    gl_TessLevelOuter[1] = 1.0;\n"
16848 									  "    gl_TessLevelOuter[2] = 1.0;\n"
16849 									  "    gl_TessLevelOuter[3] = 1.0;\n"
16850 									  "    gl_TessLevelInner[0] = 1.0;\n"
16851 									  "    gl_TessLevelInner[1] = 1.0;\n"
16852 									  "}\n"
16853 									  "\n";
16854 	static const GLchar* tes = "#version 430 core\n"
16855 							   "#extension GL_ARB_enhanced_layouts : require\n"
16856 							   "\n"
16857 							   "layout(isolines, point_mode) in;\n"
16858 							   "\n"
16859 							   "in  vec4 tcs_tes[];\n"
16860 							   "out vec4 tes_gs;\n"
16861 							   "\n"
16862 							   "void main()\n"
16863 							   "{\n"
16864 							   "    tes_gs = tcs_tes[0];\n"
16865 							   "}\n"
16866 							   "\n";
16867 	static const GLchar* tes_tested = "#version 430 core\n"
16868 									  "#extension GL_ARB_enhanced_layouts : require\n"
16869 									  "\n"
16870 									  "layout(isolines, point_mode) in;\n"
16871 									  "\n"
16872 									  "VAR_DEFINITION"
16873 									  "\n"
16874 									  "in  vec4 tcs_tes[];\n"
16875 									  "out vec4 tes_gs;\n"
16876 									  "\n"
16877 									  "void main()\n"
16878 									  "{\n"
16879 									  "    vec4 result = tcs_tes[0];\n"
16880 									  "\n"
16881 									  "VARIABLE_USE"
16882 									  "\n"
16883 									  "    tes_gs += result;\n"
16884 									  "}\n"
16885 									  "\n";
16886 	static const GLchar* vs = "#version 430 core\n"
16887 							  "#extension GL_ARB_enhanced_layouts : require\n"
16888 							  "\n"
16889 							  "in  vec4 in_vs;\n"
16890 							  "out vec4 vs_tcs;\n"
16891 							  "\n"
16892 							  "void main()\n"
16893 							  "{\n"
16894 							  "    vs_tcs = in_vs;\n"
16895 							  "}\n"
16896 							  "\n";
16897 	static const GLchar* vs_tested = "#version 430 core\n"
16898 									 "#extension GL_ARB_enhanced_layouts : require\n"
16899 									 "\n"
16900 									 "VAR_DEFINITION"
16901 									 "\n"
16902 									 "in  vec4 in_vs;\n"
16903 									 "out vec4 vs_tcs;\n"
16904 									 "\n"
16905 									 "void main()\n"
16906 									 "{\n"
16907 									 "    vec4 result = in_vs;\n"
16908 									 "\n"
16909 									 "VARIABLE_USE"
16910 									 "\n"
16911 									 "    vs_tcs += result;\n"
16912 									 "}\n"
16913 									 "\n";
16914 
16915 	std::string source;
16916 	testCase&   test_case = m_test_cases[test_case_index];
16917 
16918 	if (test_case.m_stage == stage)
16919 	{
16920 		const GLchar* array = "";
16921 		GLchar					 buffer[32];
16922 		const GLchar* var_definition = 0;
16923 		const GLchar* direction		 = "in ";
16924 		const GLchar* index			 = "";
16925 		size_t		  position		 = 0;
16926 		const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16927 		const GLchar* var_use   = 0;
16928 		Utils::Variable::STORAGE storage   = Utils::Variable::VARYING_INPUT;
16929 		const GLchar*			 flat	  = "";
16930 
16931 		if (false == test_case.m_is_input)
16932 		{
16933 			direction = "out";
16934 			storage   = Utils::Variable::VARYING_OUTPUT;
16935 
16936 			if (false == test_case.m_is_array)
16937 			{
16938 				switch (test_case.m_case)
16939 				{
16940 				case BLOCK:
16941 					var_definition = block_definition_one;
16942 					var_use		   = member_output_use_one;
16943 					break;
16944 				case MATRIX:
16945 				case DVEC3_DVEC4:
16946 					var_definition = matrix_dvec3_dvec4_definition_one;
16947 					var_use		   = matrix_dvec3_dvec4_output_use_one;
16948 					break;
16949 				case STRUCT:
16950 					var_definition = struct_definition_one;
16951 					var_use		   = member_output_use_one;
16952 					break;
16953 				default:
16954 					TCU_FAIL("Invalid enum");
16955 				}
16956 			}
16957 			else
16958 			{
16959 				switch (test_case.m_case)
16960 				{
16961 				case BLOCK:
16962 					var_definition = block_definition_arr;
16963 					var_use		   = member_output_use_arr;
16964 					break;
16965 				case MATRIX:
16966 				case DVEC3_DVEC4:
16967 					var_definition = matrix_dvec3_dvec4_definition_arr;
16968 					var_use		   = matrix_dvec3_dvec4_output_use_arr;
16969 					break;
16970 				case STRUCT:
16971 					var_definition = struct_definition_arr;
16972 					var_use		   = member_output_use_arr;
16973 					break;
16974 				default:
16975 					TCU_FAIL("Invalid enum");
16976 				}
16977 			}
16978 		}
16979 		else
16980 		{
16981 			if (false == test_case.m_is_array)
16982 			{
16983 				switch (test_case.m_case)
16984 				{
16985 				case BLOCK:
16986 					var_definition = block_definition_one;
16987 					var_use		   = Utils::Shader::VERTEX == stage ? member_input_use_one : "\n";
16988 					break;
16989 				case MATRIX:
16990 				case DVEC3_DVEC4:
16991 					var_definition = matrix_dvec3_dvec4_definition_one;
16992 					var_use		   = Utils::Shader::VERTEX == stage ? matrix_dvec3_dvec4_input_use_one : "\n";
16993 					break;
16994 				case STRUCT:
16995 					var_definition = struct_definition_one;
16996 					var_use		   = Utils::Shader::VERTEX == stage ? member_input_use_one : "\n";
16997 					break;
16998 				default:
16999 					TCU_FAIL("Invalid enum");
17000 				}
17001 			}
17002 			else
17003 			{
17004 				switch (test_case.m_case)
17005 				{
17006 				case BLOCK:
17007 					var_definition = block_definition_arr;
17008 					var_use		   = Utils::Shader::VERTEX == stage ? member_input_use_arr : "\n";
17009 					break;
17010 				case MATRIX:
17011 				case DVEC3_DVEC4:
17012 					var_definition = matrix_dvec3_dvec4_definition_arr;
17013 					var_use		   = Utils::Shader::VERTEX == stage ? matrix_dvec3_dvec4_input_use_arr : "\n";
17014 					break;
17015 				case STRUCT:
17016 					var_definition = struct_definition_arr;
17017 					var_use		   = Utils::Shader::VERTEX == stage ? member_input_use_arr : "\n";
17018 					break;
17019 				default:
17020 					TCU_FAIL("Invalid enum");
17021 				}
17022 			}
17023 		}
17024 
17025 		if (isFlatRequired(stage, test_case.m_type, storage))
17026 		{
17027 			flat = "flat";
17028 		}
17029 
17030 #if DEBUG_NEG_REMOVE_ERROR
17031 		sprintf(buffer, " /* , component = %d */", test_case.m_component);
17032 #else
17033 		sprintf(buffer, ", component = %d", test_case.m_component);
17034 #endif /* DEBUG_NEG_REMOVE_ERROR */
17035 
17036 		switch (stage)
17037 		{
17038 		case Utils::Shader::FRAGMENT:
17039 			source = fs_tested;
17040 			break;
17041 		case Utils::Shader::GEOMETRY:
17042 			source = gs_tested;
17043 			array  = test_case.m_is_input ? "[]" : "";
17044 			index  = test_case.m_is_input ? "[0]" : "";
17045 			break;
17046 		case Utils::Shader::TESS_CTRL:
17047 			source = tcs_tested;
17048 			array  = "[]";
17049 			index  = "[gl_InvocationID]";
17050 			break;
17051 		case Utils::Shader::TESS_EVAL:
17052 			source = tes_tested;
17053 			array  = test_case.m_is_input ? "[]" : "";
17054 			index  = test_case.m_is_input ? "[0]" : "";
17055 			break;
17056 		case Utils::Shader::VERTEX:
17057 			source = vs_tested;
17058 			break;
17059 		default:
17060 			TCU_FAIL("Invalid enum");
17061 		}
17062 
17063 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17064 		position = 0;
17065 		Utils::replaceToken("COMPONENT", position, buffer, source);
17066 		Utils::replaceToken("DIRECTION", position, direction, source);
17067 		Utils::replaceToken("ARRAY", position, array, source);
17068 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17069 
17070 		Utils::replaceAllTokens("FLAT", flat, source);
17071 		Utils::replaceAllTokens("TYPE", type_name, source);
17072 		Utils::replaceAllTokens("INDEX", index, source);
17073 	}
17074 	else
17075 	{
17076 		switch (stage)
17077 		{
17078 		case Utils::Shader::FRAGMENT:
17079 			source = fs;
17080 			break;
17081 		case Utils::Shader::GEOMETRY:
17082 			source = gs;
17083 			break;
17084 		case Utils::Shader::TESS_CTRL:
17085 			source = tcs;
17086 			break;
17087 		case Utils::Shader::TESS_EVAL:
17088 			source = tes;
17089 			break;
17090 		case Utils::Shader::VERTEX:
17091 			source = vs;
17092 			break;
17093 		default:
17094 			TCU_FAIL("Invalid enum");
17095 		}
17096 	}
17097 
17098 	return source;
17099 }
17100 
17101 /** Get description of test case
17102  *
17103  * @param test_case_index Index of test case
17104  *
17105  * @return Test case description
17106  **/
17107 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index)
17108 {
17109 	std::stringstream stream;
17110 	testCase&		  test_case = m_test_cases[test_case_index];
17111 
17112 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17113 		   << " type: " << test_case.m_type.GetGLSLTypeName();
17114 
17115 	if (true == test_case.m_is_array)
17116 	{
17117 		stream << "[1]";
17118 	}
17119 
17120 	stream << ", direction: ";
17121 
17122 	if (true == test_case.m_is_input)
17123 	{
17124 		stream << "input";
17125 	}
17126 	else
17127 	{
17128 		stream << "output";
17129 	}
17130 
17131 	stream << ", component: " << test_case.m_component;
17132 
17133 	return stream.str();
17134 }
17135 
17136 /** Get number of test cases
17137  *
17138  * @return Number of test cases
17139  **/
17140 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber()
17141 {
17142 	return static_cast<GLuint>(m_test_cases.size());
17143 }
17144 
17145 /** Selects if "compute" stage is relevant for test
17146  *
17147  * @param ignored
17148  *
17149  * @return false
17150  **/
17151 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */)
17152 {
17153 	return false;
17154 }
17155 
17156 /** Prepare all test cases
17157  *
17158  **/
17159 void VaryingComponentOfInvalidTypeTest::testInit()
17160 {
17161 	const GLuint		n_types					  = getTypesNumber();
17162 
17163 	for (GLuint i = 0; i < n_types; ++i)
17164 	{
17165 		const Utils::Type& type				= getType(i);
17166 		const std::vector<GLuint>& valid_components = type.GetValidComponents();
17167 
17168 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17169 		{
17170 			if (Utils::Shader::COMPUTE == stage)
17171 			{
17172 				continue;
17173 			}
17174 
17175 			/* matrices */
17176 			if (1 != type.m_n_columns)
17177 			{
17178 				testCase test_case_in_arr  = { MATRIX, 0, true, true, (Utils::Shader::STAGES)stage, type };
17179 				testCase test_case_in_one  = { MATRIX, 0, false, true, (Utils::Shader::STAGES)stage, type };
17180 				testCase test_case_out_arr = { MATRIX, 0, true, false, (Utils::Shader::STAGES)stage, type };
17181 				testCase test_case_out_one = { MATRIX, 0, false, false, (Utils::Shader::STAGES)stage, type };
17182 
17183 				m_test_cases.push_back(test_case_in_arr);
17184 				m_test_cases.push_back(test_case_in_one);
17185 
17186 				if (Utils::Shader::FRAGMENT != stage)
17187 				{
17188 					m_test_cases.push_back(test_case_out_arr);
17189 					m_test_cases.push_back(test_case_out_one);
17190 				}
17191 			}
17192 			else if (Utils::Type::Double == type.m_basic_type && 2 < type.m_n_rows) /* dvec3 and dvec4 */
17193 			{
17194 				testCase test_case_in_arr  = { DVEC3_DVEC4, 0, true, true, (Utils::Shader::STAGES)stage, type };
17195 				testCase test_case_in_one  = { DVEC3_DVEC4, 0, false, true, (Utils::Shader::STAGES)stage, type };
17196 				testCase test_case_out_arr = { DVEC3_DVEC4, 0, true, false, (Utils::Shader::STAGES)stage, type };
17197 				testCase test_case_out_one = { DVEC3_DVEC4, 0, false, false, (Utils::Shader::STAGES)stage, type };
17198 
17199 				m_test_cases.push_back(test_case_in_arr);
17200 				m_test_cases.push_back(test_case_in_one);
17201 
17202 				if (Utils::Shader::FRAGMENT != stage)
17203 				{
17204 					m_test_cases.push_back(test_case_out_arr);
17205 					m_test_cases.push_back(test_case_out_one);
17206 				}
17207 			}
17208 			else
17209 			{
17210 				if (valid_components.empty())
17211 				{
17212 					TCU_FAIL("Unhandled type");
17213 				}
17214 
17215 				for (GLuint c = BLOCK; c < MAX_CASES; ++c)
17216 				{
17217 					testCase test_case_in_arr = { (CASES)c, valid_components.back(),	  true,
17218 												  true,		(Utils::Shader::STAGES)stage, type };
17219 					testCase test_case_in_one = { (CASES)c, valid_components.back(),	  false,
17220 												  true,		(Utils::Shader::STAGES)stage, type };
17221 					testCase test_case_out_arr = { (CASES)c, valid_components.back(),	  true,
17222 												   false,	(Utils::Shader::STAGES)stage, type };
17223 					testCase test_case_out_one = { (CASES)c, valid_components.back(),	  false,
17224 												   false,	(Utils::Shader::STAGES)stage, type };
17225 
17226 					if (Utils::Shader::VERTEX != stage)
17227 					{
17228 						m_test_cases.push_back(test_case_in_arr);
17229 						m_test_cases.push_back(test_case_in_one);
17230 					}
17231 
17232 					if (Utils::Shader::FRAGMENT != stage)
17233 					{
17234 						m_test_cases.push_back(test_case_out_arr);
17235 						m_test_cases.push_back(test_case_out_one);
17236 					}
17237 				}
17238 			}
17239 		}
17240 	}
17241 }
17242 
17243 /** Constructor
17244  *
17245  * @param context Test framework context
17246  **/
17247 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context& context)
17248 	: NegativeTestBase(context, "input_component_aliasing",
17249 					   "Test verifies that compiler reports component aliasing as error")
17250 {
17251 }
17252 
17253 /** Source for given test case and stage
17254  *
17255  * @param test_case_index Index of test case
17256  * @param stage           Shader stage
17257  *
17258  * @return Shader source
17259  **/
17260 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
17261 {
17262 	static const GLchar* var_definition =
17263 		"layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n"
17264 #if DEBUG_NEG_REMOVE_ERROR
17265 		"/* layout (location = 1, component = COMPONENT) */ FLAT in TYPE gotenARRAY;\n";
17266 #else
17267 		"layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n";
17268 #endif /* DEBUG_NEG_REMOVE_ERROR */
17269 	static const GLchar* test_one = "    if (TYPE(0) == gohanINDEX)\n"
17270 									"    {\n"
17271 									"        result += vec4(1, 0.5, 0.25, 0.125);\n"
17272 									"    }\n";
17273 	static const GLchar* fs = "#version 430 core\n"
17274 							  "#extension GL_ARB_enhanced_layouts : require\n"
17275 							  "\n"
17276 							  "in  vec4 gs_fs;\n"
17277 							  "out vec4 fs_out;\n"
17278 							  "\n"
17279 							  "void main()\n"
17280 							  "{\n"
17281 							  "    fs_out = gs_fs;\n"
17282 							  "}\n"
17283 							  "\n";
17284 	static const GLchar* fs_tested = "#version 430 core\n"
17285 									 "#extension GL_ARB_enhanced_layouts : require\n"
17286 									 "\n"
17287 									 "VAR_DEFINITION"
17288 									 "\n"
17289 									 "in  vec4 gs_fs;\n"
17290 									 "out vec4 fs_out;\n"
17291 									 "\n"
17292 									 "void main()\n"
17293 									 "{\n"
17294 									 "    vec4 result = gs_fs;\n"
17295 									 "\n"
17296 									 "VARIABLE_USE"
17297 									 "\n"
17298 									 "    fs_out += result;\n"
17299 									 "}\n"
17300 									 "\n";
17301 	static const GLchar* gs = "#version 430 core\n"
17302 							  "#extension GL_ARB_enhanced_layouts : require\n"
17303 							  "\n"
17304 							  "layout(points)                           in;\n"
17305 							  "layout(triangle_strip, max_vertices = 4) out;\n"
17306 							  "\n"
17307 							  "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan;\n"
17308 							  "\n"
17309 							  "in  vec4 tes_gs[];\n"
17310 							  "out vec4 gs_fs;\n"
17311 							  "\n"
17312 							  "void main()\n"
17313 							  "{\n"
17314 							  "    gohan = TYPE(1);\n"
17315 							  "\n"
17316 							  "    gs_fs = tes_gs[0];\n"
17317 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17318 							  "    EmitVertex();\n"
17319 							  "    gs_fs = tes_gs[0];\n"
17320 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17321 							  "    EmitVertex();\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 							  "}\n"
17329 							  "\n";
17330 	static const GLchar* gs_tested = "#version 430 core\n"
17331 									 "#extension GL_ARB_enhanced_layouts : require\n"
17332 									 "\n"
17333 									 "layout(points)                           in;\n"
17334 									 "layout(triangle_strip, max_vertices = 4) out;\n"
17335 									 "\n"
17336 									 "VAR_DEFINITION"
17337 									 "\n"
17338 									 "in  vec4 tes_gs[];\n"
17339 									 "out vec4 gs_fs;\n"
17340 									 "\n"
17341 									 "void main()\n"
17342 									 "{\n"
17343 									 "    vec4 result = tes_gs[0];\n"
17344 									 "\n"
17345 									 "VARIABLE_USE"
17346 									 "\n"
17347 									 "    gs_fs = result;\n"
17348 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17349 									 "    EmitVertex();\n"
17350 									 "    gs_fs = result;\n"
17351 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17352 									 "    EmitVertex();\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 									 "}\n"
17360 									 "\n";
17361 	static const GLchar* tcs = "#version 430 core\n"
17362 							   "#extension GL_ARB_enhanced_layouts : require\n"
17363 							   "\n"
17364 							   "layout(vertices = 1) out;\n"
17365 							   "\n"
17366 							   "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan[];\n"
17367 							   "\n"
17368 							   "in  vec4 vs_tcs[];\n"
17369 							   "out vec4 tcs_tes[];\n"
17370 							   "\n"
17371 							   "void main()\n"
17372 							   "{\n"
17373 							   "    gohan[gl_InvocationID] = TYPE(1);\n"
17374 							   "\n"
17375 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17376 							   "\n"
17377 							   "    gl_TessLevelOuter[0] = 1.0;\n"
17378 							   "    gl_TessLevelOuter[1] = 1.0;\n"
17379 							   "    gl_TessLevelOuter[2] = 1.0;\n"
17380 							   "    gl_TessLevelOuter[3] = 1.0;\n"
17381 							   "    gl_TessLevelInner[0] = 1.0;\n"
17382 							   "    gl_TessLevelInner[1] = 1.0;\n"
17383 							   "}\n"
17384 							   "\n";
17385 	static const GLchar* tcs_tested = "#version 430 core\n"
17386 									  "#extension GL_ARB_enhanced_layouts : require\n"
17387 									  "\n"
17388 									  "layout(vertices = 1) out;\n"
17389 									  "\n"
17390 									  "VAR_DEFINITION"
17391 									  "\n"
17392 									  "in  vec4 vs_tcs[];\n"
17393 									  "out vec4 tcs_tes[];\n"
17394 									  "\n"
17395 									  "void main()\n"
17396 									  "{\n"
17397 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
17398 									  "\n"
17399 									  "VARIABLE_USE"
17400 									  "\n"
17401 									  "    tcs_tes[gl_InvocationID] = result;\n"
17402 									  "\n"
17403 									  "    gl_TessLevelOuter[0] = 1.0;\n"
17404 									  "    gl_TessLevelOuter[1] = 1.0;\n"
17405 									  "    gl_TessLevelOuter[2] = 1.0;\n"
17406 									  "    gl_TessLevelOuter[3] = 1.0;\n"
17407 									  "    gl_TessLevelInner[0] = 1.0;\n"
17408 									  "    gl_TessLevelInner[1] = 1.0;\n"
17409 									  "}\n"
17410 									  "\n";
17411 	static const GLchar* tes = "#version 430 core\n"
17412 							   "#extension GL_ARB_enhanced_layouts : require\n"
17413 							   "\n"
17414 							   "layout(isolines, point_mode) in;\n"
17415 							   "\n"
17416 							   "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan;\n"
17417 							   "\n"
17418 							   "in  vec4 tcs_tes[];\n"
17419 							   "out vec4 tes_gs;\n"
17420 							   "\n"
17421 							   "void main()\n"
17422 							   "{\n"
17423 							   "    gohan = TYPE(1);\n"
17424 							   "\n"
17425 							   "    tes_gs = tcs_tes[0];\n"
17426 							   "}\n"
17427 							   "\n";
17428 	static const GLchar* tes_tested = "#version 430 core\n"
17429 									  "#extension GL_ARB_enhanced_layouts : require\n"
17430 									  "\n"
17431 									  "layout(isolines, point_mode) in;\n"
17432 									  "\n"
17433 									  "VAR_DEFINITION"
17434 									  "\n"
17435 									  "in  vec4 tcs_tes[];\n"
17436 									  "out vec4 tes_gs;\n"
17437 									  "\n"
17438 									  "void main()\n"
17439 									  "{\n"
17440 									  "    vec4 result = tcs_tes[0];\n"
17441 									  "\n"
17442 									  "VARIABLE_USE"
17443 									  "\n"
17444 									  "    tes_gs += result;\n"
17445 									  "}\n"
17446 									  "\n";
17447 	static const GLchar* vs = "#version 430 core\n"
17448 							  "#extension GL_ARB_enhanced_layouts : require\n"
17449 							  "\n"
17450 							  "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan;\n"
17451 							  "\n"
17452 							  "in  vec4 in_vs;\n"
17453 							  "out vec4 vs_tcs;\n"
17454 							  "\n"
17455 							  "void main()\n"
17456 							  "{\n"
17457 							  "    gohan = TYPE(1);\n"
17458 							  "\n"
17459 							  "    vs_tcs = in_vs;\n"
17460 							  "}\n"
17461 							  "\n";
17462 	static const GLchar* vs_tested = "#version 430 core\n"
17463 									 "#extension GL_ARB_enhanced_layouts : require\n"
17464 									 "\n"
17465 									 "VAR_DEFINITION"
17466 									 "\n"
17467 									 "in  vec4 in_vs;\n"
17468 									 "out vec4 vs_tcs;\n"
17469 									 "\n"
17470 									 "void main()\n"
17471 									 "{\n"
17472 									 "    vec4 result = in_vs;\n"
17473 									 "\n"
17474 									 "VARIABLE_USE"
17475 									 "\n"
17476 									 "    vs_tcs += result;\n"
17477 									 "}\n"
17478 									 "\n";
17479 
17480 	std::string   source;
17481 	testCase&	 test_case = m_test_cases[test_case_index];
17482 	GLchar		  buffer_gohan[16];
17483 	const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
17484 
17485 	sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17486 
17487 	if (test_case.m_stage == stage)
17488 	{
17489 		const GLchar* array = "";
17490 		GLchar		  buffer_goten[16];
17491 		const GLchar* flat		  = "";
17492 		const GLchar* index		  = "";
17493 		size_t		  position	= 0;
17494 		const GLchar* var_use   = test_one;
17495 
17496 		if (isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT, true))
17497 		{
17498 			flat = "flat";
17499 		}
17500 
17501 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
17502 
17503 		switch (stage)
17504 		{
17505 		case Utils::Shader::FRAGMENT:
17506 			source = fs_tested;
17507 			break;
17508 		case Utils::Shader::GEOMETRY:
17509 			source = gs_tested;
17510 			array  = "[]";
17511 			index  = "[0]";
17512 			break;
17513 		case Utils::Shader::TESS_CTRL:
17514 			source = tcs_tested;
17515 			array  = "[]";
17516 			index  = "[gl_InvocationID]";
17517 			break;
17518 		case Utils::Shader::TESS_EVAL:
17519 			source = tes_tested;
17520 			array  = "[]";
17521 			index  = "[0]";
17522 			break;
17523 		case Utils::Shader::VERTEX:
17524 			source = vs_tested;
17525 			break;
17526 		default:
17527 			TCU_FAIL("Invalid enum");
17528 		}
17529 
17530 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17531 		position = 0;
17532 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17533 		Utils::replaceToken("ARRAY", position, array, source);
17534 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17535 		Utils::replaceToken("ARRAY", position, array, source);
17536 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17537 
17538 		Utils::replaceAllTokens("FLAT", flat, source);
17539 		Utils::replaceAllTokens("TYPE", type_name, source);
17540 		Utils::replaceAllTokens("INDEX", index, source);
17541 	}
17542 	else
17543 	{
17544 		const GLchar* flat = "";
17545 
17546 		if (isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_OUTPUT, true))
17547 		{
17548 			flat = "flat";
17549 		}
17550 
17551 		switch (stage)
17552 		{
17553 		case Utils::Shader::FRAGMENT:
17554 			source = fs;
17555 			break;
17556 		case Utils::Shader::GEOMETRY:
17557 			source = gs;
17558 			break;
17559 		case Utils::Shader::TESS_CTRL:
17560 			source = tcs;
17561 			break;
17562 		case Utils::Shader::TESS_EVAL:
17563 			source = tes;
17564 			break;
17565 		case Utils::Shader::VERTEX:
17566 			source = vs;
17567 			break;
17568 		default:
17569 			TCU_FAIL("Invalid enum");
17570 		}
17571 
17572 		Utils::replaceAllTokens("FLAT", flat, source);
17573 		Utils::replaceAllTokens("COMPONENT", buffer_gohan, source);
17574 		Utils::replaceAllTokens("TYPE", type_name, source);
17575 	}
17576 
17577 	return source;
17578 }
17579 
17580 /** Get description of test case
17581  *
17582  * @param test_case_index Index of test case
17583  *
17584  * @return Test case description
17585  **/
17586 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17587 {
17588 	std::stringstream stream;
17589 	testCase&		  test_case = m_test_cases[test_case_index];
17590 
17591 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17592 		   << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17593 		   << " & " << test_case.m_component_goten;
17594 
17595 	return stream.str();
17596 }
17597 
17598 /** Get number of test cases
17599  *
17600  * @return Number of test cases
17601  **/
17602 GLuint InputComponentAliasingTest::getTestCaseNumber()
17603 {
17604 	return static_cast<GLuint>(m_test_cases.size());
17605 }
17606 
17607 /** Selects if "compute" stage is relevant for test
17608  *
17609  * @param ignored
17610  *
17611  * @return false
17612  **/
17613 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
17614 {
17615 	return false;
17616 }
17617 
17618 /** Selects if compilation failure is expected result
17619  *
17620  * @param test_case_index Index of test case
17621  *
17622  * @return false for VS that use only single variable, true otherwise
17623  **/
17624 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index)
17625 {
17626 	testCase& test_case = m_test_cases[test_case_index];
17627 
17628 	return (Utils::Shader::VERTEX != test_case.m_stage);
17629 }
17630 
17631 /** Prepare all test cases
17632  *
17633  **/
17634 void InputComponentAliasingTest::testInit()
17635 {
17636 	const GLuint		n_types					  = getTypesNumber();
17637 
17638 	for (GLuint i = 0; i < n_types; ++i)
17639 	{
17640 		const Utils::Type& type						 = getType(i);
17641 		const std::vector<GLuint>& valid_components			 = type.GetValidComponents();
17642 
17643 		if (valid_components.empty())
17644 		{
17645 			continue;
17646 		}
17647 
17648 		for (std::vector<GLuint>::const_iterator it_gohan = valid_components.begin();
17649 			 it_gohan != valid_components.end(); ++it_gohan)
17650 		{
17651 			const GLuint max_component = *it_gohan + type.GetNumComponents();
17652 			for (std::vector<GLuint>::const_iterator it_goten = it_gohan;
17653 				 it_goten != valid_components.end() && max_component > *it_goten; ++it_goten)
17654 			{
17655 				for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17656 				{
17657 					/* Skip compute shader */
17658 					if (Utils::Shader::COMPUTE == stage)
17659 					{
17660 						continue;
17661 					}
17662 
17663 					testCase test_case = { *it_gohan, *it_goten, (Utils::Shader::STAGES)stage, type };
17664 
17665 					m_test_cases.push_back(test_case);
17666 				}
17667 			}
17668 		}
17669 	}
17670 }
17671 
17672 /** Constructor
17673  *
17674  * @param context Test framework context
17675  **/
17676 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context& context)
17677 	: NegativeTestBase(context, "output_component_aliasing",
17678 					   "Test verifies that compiler reports component aliasing as error")
17679 {
17680 }
17681 
17682 /** Source for given test case and stage
17683  *
17684  * @param test_case_index Index of test case
17685  * @param stage           Shader stage
17686  *
17687  * @return Shader source
17688  **/
17689 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
17690 {
17691 	static const GLchar* var_definition =
17692 		"layout (location = 1, component = COMPONENT) FLAT out TYPE gohanARRAY;\n"
17693 #if DEBUG_NEG_REMOVE_ERROR
17694 		"/* layout (location = 1, component = COMPONENT) */ FLAT out TYPE gotenARRAY;\n";
17695 #else
17696 		"layout (location = 1, component = COMPONENT) FLAT out TYPE gotenARRAY;\n";
17697 #endif /* DEBUG_NEG_REMOVE_ERROR */
17698 	static const GLchar* l_test = "    gohanINDEX = TYPE(1);\n"
17699 								  "    gotenINDEX = TYPE(0);\n";
17700 	static const GLchar* fs = "#version 430 core\n"
17701 							  "#extension GL_ARB_enhanced_layouts : require\n"
17702 							  "\n"
17703 							  "in  vec4 gs_fs;\n"
17704 							  "out vec4 fs_out;\n"
17705 							  "\n"
17706 							  "void main()\n"
17707 							  "{\n"
17708 							  "    fs_out = gs_fs;\n"
17709 							  "}\n"
17710 							  "\n";
17711 	static const GLchar* fs_tested = "#version 430 core\n"
17712 									 "#extension GL_ARB_enhanced_layouts : require\n"
17713 									 "\n"
17714 									 "VAR_DEFINITION"
17715 									 "\n"
17716 									 "in  vec4 gs_fs;\n"
17717 									 "out vec4 fs_out;\n"
17718 									 "\n"
17719 									 "void main()\n"
17720 									 "{\n"
17721 									 "    vec4 result = gs_fs;\n"
17722 									 "\n"
17723 									 "VARIABLE_USE"
17724 									 "\n"
17725 									 "    fs_out += result;\n"
17726 									 "}\n"
17727 									 "\n";
17728 	static const GLchar* gs = "#version 430 core\n"
17729 							  "#extension GL_ARB_enhanced_layouts : require\n"
17730 							  "\n"
17731 							  "layout(points)                           in;\n"
17732 							  "layout(triangle_strip, max_vertices = 4) out;\n"
17733 							  "\n"
17734 							  "in  vec4 tes_gs[];\n"
17735 							  "out vec4 gs_fs;\n"
17736 							  "\n"
17737 							  "void main()\n"
17738 							  "{\n"
17739 							  "    gs_fs = tes_gs[0];\n"
17740 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17741 							  "    EmitVertex();\n"
17742 							  "    gs_fs = tes_gs[0];\n"
17743 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17744 							  "    EmitVertex();\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 							  "}\n"
17752 							  "\n";
17753 	static const GLchar* gs_tested = "#version 430 core\n"
17754 									 "#extension GL_ARB_enhanced_layouts : require\n"
17755 									 "\n"
17756 									 "layout(points)                           in;\n"
17757 									 "layout(triangle_strip, max_vertices = 4) out;\n"
17758 									 "\n"
17759 									 "VAR_DEFINITION"
17760 									 "\n"
17761 									 "in  vec4 tes_gs[];\n"
17762 									 "out vec4 gs_fs;\n"
17763 									 "\n"
17764 									 "void main()\n"
17765 									 "{\n"
17766 									 "    vec4 result = tes_gs[0];\n"
17767 									 "\n"
17768 									 "VARIABLE_USE"
17769 									 "\n"
17770 									 "    gs_fs = result;\n"
17771 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17772 									 "    EmitVertex();\n"
17773 									 "    gs_fs = result;\n"
17774 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17775 									 "    EmitVertex();\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 									 "}\n"
17783 									 "\n";
17784 	static const GLchar* tcs = "#version 430 core\n"
17785 							   "#extension GL_ARB_enhanced_layouts : require\n"
17786 							   "\n"
17787 							   "layout(vertices = 1) out;\n"
17788 							   "\n"
17789 							   "in  vec4 vs_tcs[];\n"
17790 							   "out vec4 tcs_tes[];\n"
17791 							   "\n"
17792 							   "void main()\n"
17793 							   "{\n"
17794 							   "\n"
17795 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17796 							   "\n"
17797 							   "    gl_TessLevelOuter[0] = 1.0;\n"
17798 							   "    gl_TessLevelOuter[1] = 1.0;\n"
17799 							   "    gl_TessLevelOuter[2] = 1.0;\n"
17800 							   "    gl_TessLevelOuter[3] = 1.0;\n"
17801 							   "    gl_TessLevelInner[0] = 1.0;\n"
17802 							   "    gl_TessLevelInner[1] = 1.0;\n"
17803 							   "}\n"
17804 							   "\n";
17805 	static const GLchar* tcs_tested = "#version 430 core\n"
17806 									  "#extension GL_ARB_enhanced_layouts : require\n"
17807 									  "\n"
17808 									  "layout(vertices = 1) out;\n"
17809 									  "\n"
17810 									  "VAR_DEFINITION"
17811 									  "\n"
17812 									  "in  vec4 vs_tcs[];\n"
17813 									  "out vec4 tcs_tes[];\n"
17814 									  "\n"
17815 									  "void main()\n"
17816 									  "{\n"
17817 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
17818 									  "\n"
17819 									  "VARIABLE_USE"
17820 									  "\n"
17821 									  "    tcs_tes[gl_InvocationID] = result;\n"
17822 									  "\n"
17823 									  "    gl_TessLevelOuter[0] = 1.0;\n"
17824 									  "    gl_TessLevelOuter[1] = 1.0;\n"
17825 									  "    gl_TessLevelOuter[2] = 1.0;\n"
17826 									  "    gl_TessLevelOuter[3] = 1.0;\n"
17827 									  "    gl_TessLevelInner[0] = 1.0;\n"
17828 									  "    gl_TessLevelInner[1] = 1.0;\n"
17829 									  "}\n"
17830 									  "\n";
17831 	static const GLchar* tes = "#version 430 core\n"
17832 							   "#extension GL_ARB_enhanced_layouts : require\n"
17833 							   "\n"
17834 							   "layout(isolines, point_mode) in;\n"
17835 							   "\n"
17836 							   "in  vec4 tcs_tes[];\n"
17837 							   "out vec4 tes_gs;\n"
17838 							   "\n"
17839 							   "void main()\n"
17840 							   "{\n"
17841 							   "    tes_gs = tcs_tes[0];\n"
17842 							   "}\n"
17843 							   "\n";
17844 	static const GLchar* tes_tested = "#version 430 core\n"
17845 									  "#extension GL_ARB_enhanced_layouts : require\n"
17846 									  "\n"
17847 									  "layout(isolines, point_mode) in;\n"
17848 									  "\n"
17849 									  "VAR_DEFINITION"
17850 									  "\n"
17851 									  "in  vec4 tcs_tes[];\n"
17852 									  "out vec4 tes_gs;\n"
17853 									  "\n"
17854 									  "void main()\n"
17855 									  "{\n"
17856 									  "    vec4 result = tcs_tes[0];\n"
17857 									  "\n"
17858 									  "VARIABLE_USE"
17859 									  "\n"
17860 									  "    tes_gs += result;\n"
17861 									  "}\n"
17862 									  "\n";
17863 	static const GLchar* vs = "#version 430 core\n"
17864 							  "#extension GL_ARB_enhanced_layouts : require\n"
17865 							  "\n"
17866 							  "in  vec4 in_vs;\n"
17867 							  "out vec4 vs_tcs;\n"
17868 							  "\n"
17869 							  "void main()\n"
17870 							  "{\n"
17871 							  "    vs_tcs = in_vs;\n"
17872 							  "}\n"
17873 							  "\n";
17874 	static const GLchar* vs_tested = "#version 430 core\n"
17875 									 "#extension GL_ARB_enhanced_layouts : require\n"
17876 									 "\n"
17877 									 "VAR_DEFINITION"
17878 									 "\n"
17879 									 "in  vec4 in_vs;\n"
17880 									 "out vec4 vs_tcs;\n"
17881 									 "\n"
17882 									 "void main()\n"
17883 									 "{\n"
17884 									 "    vec4 result = in_vs;\n"
17885 									 "\n"
17886 									 "VARIABLE_USE"
17887 									 "\n"
17888 									 "    vs_tcs += result;\n"
17889 									 "}\n"
17890 									 "\n";
17891 
17892 	std::string source;
17893 	testCase&   test_case = m_test_cases[test_case_index];
17894 
17895 	if (test_case.m_stage == stage)
17896 	{
17897 		const GLchar* array = "";
17898 		GLchar		  buffer_gohan[16];
17899 		GLchar		  buffer_goten[16];
17900 		const GLchar* flat	 = "";
17901 		const GLchar* index	= "";
17902 		size_t		  position = 0;
17903 		const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
17904 
17905 		if (isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_OUTPUT))
17906 		{
17907 			flat = "flat";
17908 		}
17909 
17910 		sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17911 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
17912 
17913 		switch (stage)
17914 		{
17915 		case Utils::Shader::FRAGMENT:
17916 			source = fs_tested;
17917 			break;
17918 		case Utils::Shader::GEOMETRY:
17919 			source = gs_tested;
17920 			break;
17921 		case Utils::Shader::TESS_CTRL:
17922 			source = tcs_tested;
17923 			array  = "[]";
17924 			index  = "[gl_InvocationID]";
17925 			break;
17926 		case Utils::Shader::TESS_EVAL:
17927 			source = tes_tested;
17928 			break;
17929 		case Utils::Shader::VERTEX:
17930 			source = vs_tested;
17931 			break;
17932 		default:
17933 			TCU_FAIL("Invalid enum");
17934 		}
17935 
17936 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17937 		position = 0;
17938 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17939 		Utils::replaceToken("FLAT", position, flat, source);
17940 		Utils::replaceToken("ARRAY", position, array, source);
17941 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17942 		Utils::replaceToken("FLAT", position, flat, source);
17943 		Utils::replaceToken("ARRAY", position, array, source);
17944 		Utils::replaceToken("VARIABLE_USE", position, l_test, source);
17945 
17946 		Utils::replaceAllTokens("TYPE", type_name, source);
17947 		Utils::replaceAllTokens("INDEX", index, source);
17948 	}
17949 	else
17950 	{
17951 		switch (stage)
17952 		{
17953 		case Utils::Shader::FRAGMENT:
17954 			source = fs;
17955 			break;
17956 		case Utils::Shader::GEOMETRY:
17957 			source = gs;
17958 			break;
17959 		case Utils::Shader::TESS_CTRL:
17960 			source = tcs;
17961 			break;
17962 		case Utils::Shader::TESS_EVAL:
17963 			source = tes;
17964 			break;
17965 		case Utils::Shader::VERTEX:
17966 			source = vs;
17967 			break;
17968 		default:
17969 			TCU_FAIL("Invalid enum");
17970 		}
17971 	}
17972 
17973 	return source;
17974 }
17975 
17976 /** Get description of test case
17977  *
17978  * @param test_case_index Index of test case
17979  *
17980  * @return Test case description
17981  **/
17982 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17983 {
17984 	std::stringstream stream;
17985 	testCase&		  test_case = m_test_cases[test_case_index];
17986 
17987 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17988 		   << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17989 		   << " & " << test_case.m_component_goten;
17990 
17991 	return stream.str();
17992 }
17993 
17994 /** Get number of test cases
17995  *
17996  * @return Number of test cases
17997  **/
17998 GLuint OutputComponentAliasingTest::getTestCaseNumber()
17999 {
18000 	return static_cast<GLuint>(m_test_cases.size());
18001 }
18002 
18003 /** Selects if "compute" stage is relevant for test
18004  *
18005  * @param ignored
18006  *
18007  * @return false
18008  **/
18009 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
18010 {
18011 	return false;
18012 }
18013 
18014 /** Prepare all test cases
18015  *
18016  **/
18017 void OutputComponentAliasingTest::testInit()
18018 {
18019 	const GLuint		n_types					  = getTypesNumber();
18020 
18021 	for (GLuint i = 0; i < n_types; ++i)
18022 	{
18023 		const Utils::Type&		   type				= getType(i);
18024 		const std::vector<GLuint>& valid_components = type.GetValidComponents();
18025 
18026 		if (valid_components.empty())
18027 		{
18028 			continue;
18029 		}
18030 
18031 		for (std::vector<GLuint>::const_iterator it_gohan = valid_components.begin();
18032 			 it_gohan != valid_components.end(); ++it_gohan)
18033 		{
18034 			const GLuint max_component = *it_gohan + type.GetNumComponents();
18035 			for (std::vector<GLuint>::const_iterator it_goten = it_gohan;
18036 				 it_goten != valid_components.end() && max_component > *it_goten; ++it_goten)
18037 			{
18038 				for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18039 				{
18040 					/* Skip compute shader */
18041 					if (Utils::Shader::COMPUTE == stage)
18042 					{
18043 						continue;
18044 					}
18045 
18046 					if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type))
18047 					{
18048 						continue;
18049 					}
18050 
18051 					testCase test_case = { *it_gohan, *it_goten, (Utils::Shader::STAGES)stage, type };
18052 
18053 					m_test_cases.push_back(test_case);
18054 				}
18055 			}
18056 		}
18057 	}
18058 }
18059 
18060 /** Constructor
18061  *
18062  * @param context Test framework context
18063  **/
18064 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context& context)
18065 	: NegativeTestBase(context, "varying_location_aliasing_with_mixed_types",
18066 					   "Test verifies that compiler reports error when float/int types are mixed at one location")
18067 {
18068 }
18069 
18070 /** Source for given test case and stage
18071  *
18072  * @param test_case_index Index of test case
18073  * @param stage           Shader stage
18074  *
18075  * @return Shader source
18076  **/
18077 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint				 test_case_index,
18078 																	   Utils::Shader::STAGES stage)
18079 {
18080 	static const GLchar* var_definition =
18081 		"layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n"
18082 		"layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n";
18083 	static const GLchar* input_use = "    if ((TYPE(0) == gohanINDEX) &&\n"
18084 									 "        (TYPE(1) == gotenINDEX) )\n"
18085 									 "    {\n"
18086 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
18087 									 "    }\n";
18088 	static const GLchar* output_use = "    gohanINDEX = TYPE(0);\n"
18089 									  "    gotenINDEX = TYPE(1);\n"
18090 									  "    if (vec4(0) == result)\n"
18091 									  "    {\n"
18092 									  "        gohanINDEX = TYPE(1);\n"
18093 									  "        gotenINDEX = TYPE(0);\n"
18094 									  "    }\n";
18095 	static const GLchar* fs = "#version 430 core\n"
18096 							  "#extension GL_ARB_enhanced_layouts : require\n"
18097 							  "\n"
18098 							  "in  vec4 gs_fs;\n"
18099 							  "out vec4 fs_out;\n"
18100 							  "\n"
18101 							  "void main()\n"
18102 							  "{\n"
18103 							  "    fs_out = gs_fs;\n"
18104 							  "}\n"
18105 							  "\n";
18106 	static const GLchar* fs_tested = "#version 430 core\n"
18107 									 "#extension GL_ARB_enhanced_layouts : require\n"
18108 									 "\n"
18109 									 "VAR_DEFINITION"
18110 									 "\n"
18111 									 "in  vec4 gs_fs;\n"
18112 									 "out vec4 fs_out;\n"
18113 									 "\n"
18114 									 "void main()\n"
18115 									 "{\n"
18116 									 "    vec4 result = gs_fs;\n"
18117 									 "\n"
18118 									 "VARIABLE_USE"
18119 									 "\n"
18120 									 "    fs_out += result;\n"
18121 									 "}\n"
18122 									 "\n";
18123 	static const GLchar* gs = "#version 430 core\n"
18124 							  "#extension GL_ARB_enhanced_layouts : require\n"
18125 							  "\n"
18126 							  "layout(points)                           in;\n"
18127 							  "layout(triangle_strip, max_vertices = 4) out;\n"
18128 							  "\n"
18129 							  "in  vec4 tes_gs[];\n"
18130 							  "out vec4 gs_fs;\n"
18131 							  "\n"
18132 							  "void main()\n"
18133 							  "{\n"
18134 							  "    gs_fs = tes_gs[0];\n"
18135 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18136 							  "    EmitVertex();\n"
18137 							  "    gs_fs = tes_gs[0];\n"
18138 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18139 							  "    EmitVertex();\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 							  "}\n"
18147 							  "\n";
18148 	static const GLchar* gs_tested = "#version 430 core\n"
18149 									 "#extension GL_ARB_enhanced_layouts : require\n"
18150 									 "\n"
18151 									 "layout(points)                           in;\n"
18152 									 "layout(triangle_strip, max_vertices = 4) out;\n"
18153 									 "\n"
18154 									 "VAR_DEFINITION"
18155 									 "\n"
18156 									 "in  vec4 tes_gs[];\n"
18157 									 "out vec4 gs_fs;\n"
18158 									 "\n"
18159 									 "void main()\n"
18160 									 "{\n"
18161 									 "    vec4 result = tes_gs[0];\n"
18162 									 "\n"
18163 									 "VARIABLE_USE"
18164 									 "\n"
18165 									 "    gs_fs = result;\n"
18166 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18167 									 "    EmitVertex();\n"
18168 									 "    gs_fs = result;\n"
18169 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18170 									 "    EmitVertex();\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 									 "}\n"
18178 									 "\n";
18179 	static const GLchar* tcs = "#version 430 core\n"
18180 							   "#extension GL_ARB_enhanced_layouts : require\n"
18181 							   "\n"
18182 							   "layout(vertices = 1) out;\n"
18183 							   "\n"
18184 							   "in  vec4 vs_tcs[];\n"
18185 							   "out vec4 tcs_tes[];\n"
18186 							   "\n"
18187 							   "void main()\n"
18188 							   "{\n"
18189 							   "\n"
18190 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18191 							   "\n"
18192 							   "    gl_TessLevelOuter[0] = 1.0;\n"
18193 							   "    gl_TessLevelOuter[1] = 1.0;\n"
18194 							   "    gl_TessLevelOuter[2] = 1.0;\n"
18195 							   "    gl_TessLevelOuter[3] = 1.0;\n"
18196 							   "    gl_TessLevelInner[0] = 1.0;\n"
18197 							   "    gl_TessLevelInner[1] = 1.0;\n"
18198 							   "}\n"
18199 							   "\n";
18200 	static const GLchar* tcs_tested = "#version 430 core\n"
18201 									  "#extension GL_ARB_enhanced_layouts : require\n"
18202 									  "\n"
18203 									  "layout(vertices = 1) out;\n"
18204 									  "\n"
18205 									  "VAR_DEFINITION"
18206 									  "\n"
18207 									  "in  vec4 vs_tcs[];\n"
18208 									  "out vec4 tcs_tes[];\n"
18209 									  "\n"
18210 									  "void main()\n"
18211 									  "{\n"
18212 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
18213 									  "\n"
18214 									  "VARIABLE_USE"
18215 									  "\n"
18216 									  "    tcs_tes[gl_InvocationID] = result;\n"
18217 									  "\n"
18218 									  "    gl_TessLevelOuter[0] = 1.0;\n"
18219 									  "    gl_TessLevelOuter[1] = 1.0;\n"
18220 									  "    gl_TessLevelOuter[2] = 1.0;\n"
18221 									  "    gl_TessLevelOuter[3] = 1.0;\n"
18222 									  "    gl_TessLevelInner[0] = 1.0;\n"
18223 									  "    gl_TessLevelInner[1] = 1.0;\n"
18224 									  "}\n"
18225 									  "\n";
18226 	static const GLchar* tes = "#version 430 core\n"
18227 							   "#extension GL_ARB_enhanced_layouts : require\n"
18228 							   "\n"
18229 							   "layout(isolines, point_mode) in;\n"
18230 							   "\n"
18231 							   "in  vec4 tcs_tes[];\n"
18232 							   "out vec4 tes_gs;\n"
18233 							   "\n"
18234 							   "void main()\n"
18235 							   "{\n"
18236 							   "    tes_gs = tcs_tes[0];\n"
18237 							   "}\n"
18238 							   "\n";
18239 	static const GLchar* tes_tested = "#version 430 core\n"
18240 									  "#extension GL_ARB_enhanced_layouts : require\n"
18241 									  "\n"
18242 									  "layout(isolines, point_mode) in;\n"
18243 									  "\n"
18244 									  "VAR_DEFINITION"
18245 									  "\n"
18246 									  "in  vec4 tcs_tes[];\n"
18247 									  "out vec4 tes_gs;\n"
18248 									  "\n"
18249 									  "void main()\n"
18250 									  "{\n"
18251 									  "    vec4 result = tcs_tes[0];\n"
18252 									  "\n"
18253 									  "VARIABLE_USE"
18254 									  "\n"
18255 									  "    tes_gs += result;\n"
18256 									  "}\n"
18257 									  "\n";
18258 	static const GLchar* vs = "#version 430 core\n"
18259 							  "#extension GL_ARB_enhanced_layouts : require\n"
18260 							  "\n"
18261 							  "in  vec4 in_vs;\n"
18262 							  "out vec4 vs_tcs;\n"
18263 							  "\n"
18264 							  "void main()\n"
18265 							  "{\n"
18266 							  "    vs_tcs = in_vs;\n"
18267 							  "}\n"
18268 							  "\n";
18269 	static const GLchar* vs_tested = "#version 430 core\n"
18270 									 "#extension GL_ARB_enhanced_layouts : require\n"
18271 									 "\n"
18272 									 "VAR_DEFINITION"
18273 									 "\n"
18274 									 "in  vec4 in_vs;\n"
18275 									 "out vec4 vs_tcs;\n"
18276 									 "\n"
18277 									 "void main()\n"
18278 									 "{\n"
18279 									 "    vec4 result = in_vs;\n"
18280 									 "\n"
18281 									 "VARIABLE_USE"
18282 									 "\n"
18283 									 "    vs_tcs += result;\n"
18284 									 "}\n"
18285 									 "\n";
18286 
18287 	std::string source;
18288 	testCase&   test_case = m_test_cases[test_case_index];
18289 
18290 	if (test_case.m_stage == stage)
18291 	{
18292 		const GLchar*			 array = "";
18293 		GLchar					 buffer_gohan[16];
18294 		GLchar					 buffer_goten[16];
18295 		const GLchar*			 direction  = "in ";
18296 		const GLchar*			 flat_gohan = "";
18297 		const GLchar*			 flat_goten = "";
18298 		const GLchar*			 index		= "";
18299 		size_t					 position   = 0;
18300 		size_t					 temp;
18301 		const GLchar*			 type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18302 		const GLchar*			 type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18303 		Utils::Variable::STORAGE storage		 = Utils::Variable::VARYING_INPUT;
18304 		const GLchar*			 var_use		 = Utils::Shader::VERTEX == stage ? input_use : "\n";
18305 
18306 		if (false == test_case.m_is_input)
18307 		{
18308 			direction = "out";
18309 			storage   = Utils::Variable::VARYING_OUTPUT;
18310 			var_use   = output_use;
18311 		}
18312 
18313 		/* If the interpolation qualifier would be different, the test
18314 		 * would fail and we are testing here mixed types, not mixed
18315 		 * interpolation qualifiers.
18316 		 */
18317 		if (isFlatRequired(stage, test_case.m_type_gohan, storage) ||
18318 			isFlatRequired(stage, test_case.m_type_goten, storage))
18319 		{
18320 			flat_gohan = "flat";
18321 			flat_goten = "flat";
18322 		}
18323 
18324 		sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18325 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
18326 
18327 #if DEBUG_NEG_REMOVE_ERROR
18328 		type_goten_name = Utils::Type::GetType(test_case.m_type_gohan.m_basic_type, 1, 1).GetGLSLTypeName();
18329 		if (Utils::Type::Double == test_case.m_type_gohan.m_basic_type)
18330 		{
18331 			sprintf(buffer_goten, "%d", 0 == test_case.m_component_gohan ? 2 : 0);
18332 		}
18333 #endif /* DEBUG_NEG_REMOVE_ERROR */
18334 
18335 		switch (stage)
18336 		{
18337 		case Utils::Shader::FRAGMENT:
18338 			source = fs_tested;
18339 			break;
18340 		case Utils::Shader::GEOMETRY:
18341 			source = gs_tested;
18342 			array  = test_case.m_is_input ? "[]" : "";
18343 			index  = test_case.m_is_input ? "[0]" : "";
18344 			break;
18345 		case Utils::Shader::TESS_CTRL:
18346 			source = tcs_tested;
18347 			array  = "[]";
18348 			index  = "[gl_InvocationID]";
18349 			break;
18350 		case Utils::Shader::TESS_EVAL:
18351 			source = tes_tested;
18352 			array  = test_case.m_is_input ? "[]" : "";
18353 			index  = test_case.m_is_input ? "[0]" : "";
18354 			break;
18355 		case Utils::Shader::VERTEX:
18356 			source = vs_tested;
18357 			break;
18358 		default:
18359 			TCU_FAIL("Invalid enum");
18360 		}
18361 
18362 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18363 		position = 0;
18364 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18365 		Utils::replaceToken("FLAT", position, flat_gohan, source);
18366 		Utils::replaceToken("DIRECTION", position, direction, source);
18367 		Utils::replaceToken("TYPE", position, type_gohan_name, source);
18368 		Utils::replaceToken("ARRAY", position, array, source);
18369 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18370 		Utils::replaceToken("FLAT", position, flat_goten, source);
18371 		Utils::replaceToken("DIRECTION", position, direction, source);
18372 		Utils::replaceToken("TYPE", position, type_goten_name, source);
18373 		Utils::replaceToken("ARRAY", position, array, source);
18374 
18375 		temp = position;
18376 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18377 		position = temp;
18378 		if (!test_case.m_is_input)
18379 		{
18380 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18381 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18382 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18383 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18384 		}
18385 		else if (Utils::Shader::VERTEX == stage)
18386 		{
18387 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18388 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18389 		}
18390 
18391 		Utils::replaceAllTokens("INDEX", index, source);
18392 	}
18393 	else
18394 	{
18395 		switch (stage)
18396 		{
18397 		case Utils::Shader::FRAGMENT:
18398 			source = fs;
18399 			break;
18400 		case Utils::Shader::GEOMETRY:
18401 			source = gs;
18402 			break;
18403 		case Utils::Shader::TESS_CTRL:
18404 			source = tcs;
18405 			break;
18406 		case Utils::Shader::TESS_EVAL:
18407 			source = tes;
18408 			break;
18409 		case Utils::Shader::VERTEX:
18410 			source = vs;
18411 			break;
18412 		default:
18413 			TCU_FAIL("Invalid enum");
18414 		}
18415 	}
18416 
18417 	return source;
18418 }
18419 
18420 /** Get description of test case
18421  *
18422  * @param test_case_index Index of test case
18423  *
18424  * @return Test case description
18425  **/
18426 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index)
18427 {
18428 	std::stringstream stream;
18429 	testCase&		  test_case = m_test_cases[test_case_index];
18430 
18431 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18432 		   << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18433 		   << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18434 
18435 	if (true == test_case.m_is_input)
18436 	{
18437 		stream << "input";
18438 	}
18439 	else
18440 	{
18441 		stream << "output";
18442 	}
18443 
18444 	return stream.str();
18445 }
18446 
18447 /** Get number of test cases
18448  *
18449  * @return Number of test cases
18450  **/
18451 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber()
18452 {
18453 	return static_cast<GLuint>(m_test_cases.size());
18454 }
18455 
18456 /** Selects if "compute" stage is relevant for test
18457  *
18458  * @param ignored
18459  *
18460  * @return false
18461  **/
18462 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */)
18463 {
18464 	return false;
18465 }
18466 
18467 /** Prepare all test cases
18468  *
18469  **/
18470 void VaryingLocationAliasingWithMixedTypesTest::testInit()
18471 {
18472 	const GLuint		n_types					  = getTypesNumber();
18473 
18474 	for (GLuint i = 0; i < n_types; ++i)
18475 	{
18476 		const Utils::Type& type_gohan		   = getType(i);
18477 		const std::vector<GLuint>& valid_components_gohan = type_gohan.GetValidComponents();
18478 
18479 		if (valid_components_gohan.empty())
18480 		{
18481 			continue;
18482 		}
18483 
18484 		for (GLuint j = 0; j < n_types; ++j)
18485 		{
18486 			const Utils::Type& type_goten		   = getType(j);
18487 			const std::vector<GLuint>& valid_components_goten = type_goten.GetValidComponents();
18488 
18489 			if (valid_components_goten.empty())
18490 			{
18491 				continue;
18492 			}
18493 
18494 			/* Skip valid combinations */
18495 			if (Utils::Type::CanTypesShareLocation(type_gohan.m_basic_type, type_goten.m_basic_type))
18496 			{
18497 				continue;
18498 			}
18499 
18500 			for (std::vector<GLuint>::const_iterator it_gohan = valid_components_gohan.begin();
18501 				 it_gohan != valid_components_gohan.end(); ++it_gohan)
18502 			{
18503 				const GLuint min_component = *it_gohan + type_gohan.GetNumComponents();
18504 				for (std::vector<GLuint>::const_iterator it_goten = valid_components_goten.begin();
18505 					 it_goten != valid_components_goten.end(); ++it_goten)
18506 				{
18507 
18508 					if (min_component > *it_goten)
18509 					{
18510 						continue;
18511 					}
18512 
18513 					for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18514 					{
18515 						/* Skip compute shader */
18516 						if (Utils::Shader::COMPUTE == stage)
18517 						{
18518 							continue;
18519 						}
18520 
18521 						if (Utils::Shader::VERTEX != stage)
18522 						{
18523 							testCase test_case_in = { *it_gohan,  *it_goten, true, (Utils::Shader::STAGES)stage,
18524 													  type_gohan, type_goten };
18525 
18526 							m_test_cases.push_back(test_case_in);
18527 						}
18528 
18529 						/* Skip double outputs in fragment shader */
18530 						if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
18531 																   (Utils::Type::Double != type_goten.m_basic_type)))
18532 						{
18533 							testCase test_case_out = { *it_gohan,  *it_goten, false, (Utils::Shader::STAGES)stage,
18534 													   type_gohan, type_goten };
18535 
18536 							m_test_cases.push_back(test_case_out);
18537 						}
18538 					}
18539 				}
18540 			}
18541 		}
18542 	}
18543 }
18544 
18545 /** Constructor
18546  *
18547  * @param context Test framework context
18548  **/
18549 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest(
18550 	deqp::Context& context)
18551 	: NegativeTestBase(
18552 		  context, "varying_location_aliasing_with_mixed_interpolation",
18553 		  "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location")
18554 {
18555 }
18556 
18557 /** Source for given test case and stage
18558  *
18559  * @param test_case_index Index of test case
18560  * @param stage           Shader stage
18561  *
18562  * @return Shader source
18563  **/
18564 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint				 test_case_index,
18565 																			   Utils::Shader::STAGES stage)
18566 {
18567 	static const GLchar* var_definition =
18568 		"layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
18569 		"layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
18570 	static const GLchar* input_use = "    if ((TYPE(0) == gohanINDEX) &&\n"
18571 									 "        (TYPE(1) == gotenINDEX) )\n"
18572 									 "    {\n"
18573 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
18574 									 "    }\n";
18575 	static const GLchar* output_use = "    gohanINDEX = TYPE(0);\n"
18576 									  "    gotenINDEX = TYPE(1);\n"
18577 									  "    if (vec4(0) == result)\n"
18578 									  "    {\n"
18579 									  "        gohanINDEX = TYPE(1);\n"
18580 									  "        gotenINDEX = TYPE(0);\n"
18581 									  "    }\n";
18582 	static const GLchar* fs = "#version 430 core\n"
18583 							  "#extension GL_ARB_enhanced_layouts : require\n"
18584 							  "\n"
18585 							  "in  vec4 gs_fs;\n"
18586 							  "out vec4 fs_out;\n"
18587 							  "\n"
18588 							  "void main()\n"
18589 							  "{\n"
18590 							  "    fs_out = gs_fs;\n"
18591 							  "}\n"
18592 							  "\n";
18593 	static const GLchar* fs_tested = "#version 430 core\n"
18594 									 "#extension GL_ARB_enhanced_layouts : require\n"
18595 									 "\n"
18596 									 "VAR_DEFINITION"
18597 									 "\n"
18598 									 "in  vec4 gs_fs;\n"
18599 									 "out vec4 fs_out;\n"
18600 									 "\n"
18601 									 "void main()\n"
18602 									 "{\n"
18603 									 "    vec4 result = gs_fs;\n"
18604 									 "\n"
18605 									 "VARIABLE_USE"
18606 									 "\n"
18607 									 "    fs_out = result;\n"
18608 									 "}\n"
18609 									 "\n";
18610 	static const GLchar* gs = "#version 430 core\n"
18611 							  "#extension GL_ARB_enhanced_layouts : require\n"
18612 							  "\n"
18613 							  "layout(points)                           in;\n"
18614 							  "layout(triangle_strip, max_vertices = 4) out;\n"
18615 							  "\n"
18616 							  "in  vec4 tes_gs[];\n"
18617 							  "out vec4 gs_fs;\n"
18618 							  "\n"
18619 							  "void main()\n"
18620 							  "{\n"
18621 							  "    gs_fs = tes_gs[0];\n"
18622 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18623 							  "    EmitVertex();\n"
18624 							  "    gs_fs = tes_gs[0];\n"
18625 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18626 							  "    EmitVertex();\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 							  "}\n"
18634 							  "\n";
18635 	static const GLchar* gs_tested = "#version 430 core\n"
18636 									 "#extension GL_ARB_enhanced_layouts : require\n"
18637 									 "\n"
18638 									 "layout(points)                           in;\n"
18639 									 "layout(triangle_strip, max_vertices = 4) out;\n"
18640 									 "\n"
18641 									 "VAR_DEFINITION"
18642 									 "\n"
18643 									 "in  vec4 tes_gs[];\n"
18644 									 "out vec4 gs_fs;\n"
18645 									 "\n"
18646 									 "void main()\n"
18647 									 "{\n"
18648 									 "    vec4 result = tes_gs[0];\n"
18649 									 "\n"
18650 									 "VARIABLE_USE"
18651 									 "\n"
18652 									 "    gs_fs = result;\n"
18653 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18654 									 "    EmitVertex();\n"
18655 									 "    gs_fs = result;\n"
18656 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18657 									 "    EmitVertex();\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 									 "}\n"
18665 									 "\n";
18666 	static const GLchar* tcs = "#version 430 core\n"
18667 							   "#extension GL_ARB_enhanced_layouts : require\n"
18668 							   "\n"
18669 							   "layout(vertices = 1) out;\n"
18670 							   "\n"
18671 							   "in  vec4 vs_tcs[];\n"
18672 							   "out vec4 tcs_tes[];\n"
18673 							   "\n"
18674 							   "void main()\n"
18675 							   "{\n"
18676 							   "\n"
18677 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18678 							   "\n"
18679 							   "    gl_TessLevelOuter[0] = 1.0;\n"
18680 							   "    gl_TessLevelOuter[1] = 1.0;\n"
18681 							   "    gl_TessLevelOuter[2] = 1.0;\n"
18682 							   "    gl_TessLevelOuter[3] = 1.0;\n"
18683 							   "    gl_TessLevelInner[0] = 1.0;\n"
18684 							   "    gl_TessLevelInner[1] = 1.0;\n"
18685 							   "}\n"
18686 							   "\n";
18687 	static const GLchar* tcs_tested = "#version 430 core\n"
18688 									  "#extension GL_ARB_enhanced_layouts : require\n"
18689 									  "\n"
18690 									  "layout(vertices = 1) out;\n"
18691 									  "\n"
18692 									  "VAR_DEFINITION"
18693 									  "\n"
18694 									  "in  vec4 vs_tcs[];\n"
18695 									  "out vec4 tcs_tes[];\n"
18696 									  "\n"
18697 									  "void main()\n"
18698 									  "{\n"
18699 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
18700 									  "\n"
18701 									  "VARIABLE_USE"
18702 									  "\n"
18703 									  "    tcs_tes[gl_InvocationID] = result;\n"
18704 									  "\n"
18705 									  "    gl_TessLevelOuter[0] = 1.0;\n"
18706 									  "    gl_TessLevelOuter[1] = 1.0;\n"
18707 									  "    gl_TessLevelOuter[2] = 1.0;\n"
18708 									  "    gl_TessLevelOuter[3] = 1.0;\n"
18709 									  "    gl_TessLevelInner[0] = 1.0;\n"
18710 									  "    gl_TessLevelInner[1] = 1.0;\n"
18711 									  "}\n"
18712 									  "\n";
18713 	static const GLchar* tes = "#version 430 core\n"
18714 							   "#extension GL_ARB_enhanced_layouts : require\n"
18715 							   "\n"
18716 							   "layout(isolines, point_mode) in;\n"
18717 							   "\n"
18718 							   "in  vec4 tcs_tes[];\n"
18719 							   "out vec4 tes_gs;\n"
18720 							   "\n"
18721 							   "void main()\n"
18722 							   "{\n"
18723 							   "    tes_gs = tcs_tes[0];\n"
18724 							   "}\n"
18725 							   "\n";
18726 	static const GLchar* tes_tested = "#version 430 core\n"
18727 									  "#extension GL_ARB_enhanced_layouts : require\n"
18728 									  "\n"
18729 									  "layout(isolines, point_mode) in;\n"
18730 									  "\n"
18731 									  "VAR_DEFINITION"
18732 									  "\n"
18733 									  "in  vec4 tcs_tes[];\n"
18734 									  "out vec4 tes_gs;\n"
18735 									  "\n"
18736 									  "void main()\n"
18737 									  "{\n"
18738 									  "    vec4 result = tcs_tes[0];\n"
18739 									  "\n"
18740 									  "VARIABLE_USE"
18741 									  "\n"
18742 									  "    tes_gs += result;\n"
18743 									  "}\n"
18744 									  "\n";
18745 	static const GLchar* vs = "#version 430 core\n"
18746 							  "#extension GL_ARB_enhanced_layouts : require\n"
18747 							  "\n"
18748 							  "in  vec4 in_vs;\n"
18749 							  "out vec4 vs_tcs;\n"
18750 							  "\n"
18751 							  "void main()\n"
18752 							  "{\n"
18753 							  "    vs_tcs = in_vs;\n"
18754 							  "}\n"
18755 							  "\n";
18756 	static const GLchar* vs_tested = "#version 430 core\n"
18757 									 "#extension GL_ARB_enhanced_layouts : require\n"
18758 									 "\n"
18759 									 "VAR_DEFINITION"
18760 									 "\n"
18761 									 "in  vec4 in_vs;\n"
18762 									 "out vec4 vs_tcs;\n"
18763 									 "\n"
18764 									 "void main()\n"
18765 									 "{\n"
18766 									 "    vec4 result = in_vs;\n"
18767 									 "\n"
18768 									 "VARIABLE_USE"
18769 									 "\n"
18770 									 "    vs_tcs += result;\n"
18771 									 "}\n"
18772 									 "\n";
18773 
18774 	std::string source;
18775 	testCase&   test_case = m_test_cases[test_case_index];
18776 
18777 	if (test_case.m_stage == stage)
18778 	{
18779 		const GLchar* array = "";
18780 		GLchar		  buffer_gohan[16];
18781 		GLchar		  buffer_goten[16];
18782 		const GLchar* direction = "in ";
18783 		const GLchar* index		= "";
18784 		const GLchar* int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan);
18785 		const GLchar* int_goten = getInterpolationQualifier(test_case.m_interpolation_goten);
18786 #if DEBUG_NEG_REMOVE_ERROR
18787 		if (FLAT == test_case.m_interpolation_goten)
18788 		{
18789 			int_gohan = int_goten;
18790 		}
18791 		else
18792 		{
18793 			int_goten = int_gohan;
18794 		}
18795 #endif /* DEBUG_NEG_REMOVE_ERROR */
18796 		size_t		  position  = 0;
18797 		size_t		  temp;
18798 		const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18799 		const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18800 		const GLchar* var_use		  = Utils::Shader::VERTEX == stage ? input_use : "\n";
18801 
18802 		if (false == test_case.m_is_input)
18803 		{
18804 			direction = "out";
18805 
18806 			var_use = output_use;
18807 		}
18808 
18809 		sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18810 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
18811 
18812 		switch (stage)
18813 		{
18814 		case Utils::Shader::FRAGMENT:
18815 			source = fs_tested;
18816 			break;
18817 		case Utils::Shader::GEOMETRY:
18818 			source = gs_tested;
18819 			array  = test_case.m_is_input ? "[]" : "";
18820 			index  = test_case.m_is_input ? "[0]" : "";
18821 			break;
18822 		case Utils::Shader::TESS_CTRL:
18823 			source = tcs_tested;
18824 			array  = "[]";
18825 			index  = "[gl_InvocationID]";
18826 			break;
18827 		case Utils::Shader::TESS_EVAL:
18828 			source = tes_tested;
18829 			array  = test_case.m_is_input ? "[]" : "";
18830 			index  = test_case.m_is_input ? "[0]" : "";
18831 			break;
18832 		case Utils::Shader::VERTEX:
18833 			source = vs_tested;
18834 			break;
18835 		default:
18836 			TCU_FAIL("Invalid enum");
18837 		}
18838 
18839 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18840 		position = 0;
18841 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18842 		Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18843 		Utils::replaceToken("DIRECTION", position, direction, source);
18844 		Utils::replaceToken("TYPE", position, type_gohan_name, source);
18845 		Utils::replaceToken("ARRAY", position, array, source);
18846 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18847 		Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18848 		Utils::replaceToken("DIRECTION", position, direction, source);
18849 		Utils::replaceToken("TYPE", position, type_goten_name, source);
18850 		Utils::replaceToken("ARRAY", position, array, source);
18851 
18852 		temp = position;
18853 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18854 		position = temp;
18855 		if (!test_case.m_is_input)
18856 		{
18857 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18858 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18859 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18860 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18861 		}
18862 		else if (Utils::Shader::VERTEX == stage)
18863 		{
18864 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18865 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18866 		}
18867 
18868 		Utils::replaceAllTokens("INDEX", index, source);
18869 	}
18870 	else
18871 	{
18872 		switch (stage)
18873 		{
18874 		case Utils::Shader::FRAGMENT:
18875 			source = fs;
18876 			break;
18877 		case Utils::Shader::GEOMETRY:
18878 			source = gs;
18879 			break;
18880 		case Utils::Shader::TESS_CTRL:
18881 			source = tcs;
18882 			break;
18883 		case Utils::Shader::TESS_EVAL:
18884 			source = tes;
18885 			break;
18886 		case Utils::Shader::VERTEX:
18887 			source = vs;
18888 			break;
18889 		default:
18890 			TCU_FAIL("Invalid enum");
18891 		}
18892 	}
18893 
18894 	return source;
18895 }
18896 
18897 /** Get description of test case
18898  *
18899  * @param test_case_index Index of test case
18900  *
18901  * @return Test case description
18902  **/
18903 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index)
18904 {
18905 	std::stringstream stream;
18906 	testCase&		  test_case = m_test_cases[test_case_index];
18907 
18908 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18909 		   << getInterpolationQualifier(test_case.m_interpolation_gohan) << " "
18910 		   << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18911 		   << getInterpolationQualifier(test_case.m_interpolation_goten) << " "
18912 		   << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18913 
18914 	if (true == test_case.m_is_input)
18915 	{
18916 		stream << "input";
18917 	}
18918 	else
18919 	{
18920 		stream << "output";
18921 	}
18922 
18923 	return stream.str();
18924 }
18925 
18926 /** Get number of test cases
18927  *
18928  * @return Number of test cases
18929  **/
18930 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber()
18931 {
18932 	return static_cast<GLuint>(m_test_cases.size());
18933 }
18934 
18935 /** Selects if "compute" stage is relevant for test
18936  *
18937  * @param ignored
18938  *
18939  * @return false
18940  **/
18941 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */)
18942 {
18943 	return false;
18944 }
18945 
18946 /** Prepare all test cases
18947  *
18948  **/
18949 void VaryingLocationAliasingWithMixedInterpolationTest::testInit()
18950 {
18951 	const GLuint		n_types					  = getTypesNumber();
18952 
18953 	for (GLuint i = 0; i < n_types; ++i)
18954 	{
18955 		const Utils::Type& type_gohan		   = getType(i);
18956 		const std::vector<GLuint>& valid_components_gohan = type_gohan.GetValidComponents();
18957 
18958 		if (valid_components_gohan.empty())
18959 		{
18960 			continue;
18961 		}
18962 
18963 		const GLuint gohan = valid_components_gohan.front();
18964 
18965 		for (GLuint j = 0; j < n_types; ++j)
18966 		{
18967 			const Utils::Type& type_goten		   = getType(j);
18968 			const std::vector<GLuint>& valid_components_goten = type_goten.GetValidComponents();
18969 
18970 			if (valid_components_goten.empty())
18971 			{
18972 				continue;
18973 			}
18974 
18975 			/* Just get the highest valid component for goten and
18976 			 * check if we can use it.
18977 			 */
18978 			const GLuint min_component = gohan + type_gohan.GetNumComponents();
18979 			const GLuint goten		   = valid_components_goten.back();
18980 
18981 			if (min_component > goten)
18982 			{
18983 				continue;
18984 			}
18985 
18986 			/* Skip invalid combinations */
18987 			if (!Utils::Type::CanTypesShareLocation(type_gohan.m_basic_type, type_goten.m_basic_type))
18988 			{
18989 				continue;
18990 			}
18991 
18992 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18993 			{
18994 				/* Skip compute shader */
18995 				if (Utils::Shader::COMPUTE == stage)
18996 				{
18997 					continue;
18998 				}
18999 
19000 				for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan)
19001 				{
19002 					for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten)
19003 					{
19004 						/* Skip when both are the same */
19005 						if (int_gohan == int_goten)
19006 						{
19007 							continue;
19008 						}
19009 
19010 						/* Skip inputs in: vertex shader and whenever
19011 						 * flat is mandatory and is not the chosen
19012 						 * one.
19013 						 */
19014 						bool skip_inputs = Utils::Shader::VERTEX == stage;
19015 						skip_inputs |=
19016 							(FLAT != int_gohan && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_gohan,
19017 																 Utils::Variable::VARYING_INPUT));
19018 						skip_inputs |=
19019 							(FLAT != int_goten && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_goten,
19020 																 Utils::Variable::VARYING_INPUT));
19021 
19022 						if (!skip_inputs)
19023 						{
19024 							testCase test_case_in = { gohan,
19025 													  goten,
19026 													  static_cast<INTERPOLATIONS>(int_gohan),
19027 													  static_cast<INTERPOLATIONS>(int_goten),
19028 													  true,
19029 													  static_cast<Utils::Shader::STAGES>(stage),
19030 													  type_gohan,
19031 													  type_goten };
19032 							m_test_cases.push_back(test_case_in);
19033 						}
19034 
19035 						/* Skip outputs in fragment shader and
19036 						 * whenever flat is mandatory and is not the
19037 						 * chosen one.
19038 						 */
19039 						bool skip_outputs = Utils::Shader::FRAGMENT == stage;
19040 						skip_outputs |=
19041 							(FLAT != int_gohan && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_gohan,
19042 																 Utils::Variable::VARYING_OUTPUT));
19043 						skip_outputs |=
19044 							(FLAT != int_goten && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_goten,
19045 																 Utils::Variable::VARYING_OUTPUT));
19046 
19047 						if (!skip_outputs)
19048 						{
19049 							testCase test_case_out = { gohan,
19050 													   goten,
19051 													   static_cast<INTERPOLATIONS>(int_gohan),
19052 													   static_cast<INTERPOLATIONS>(int_goten),
19053 													   false,
19054 													   static_cast<Utils::Shader::STAGES>(stage),
19055 													   type_gohan,
19056 													   type_goten };
19057 							m_test_cases.push_back(test_case_out);
19058 						}
19059 					}
19060 				}
19061 			}
19062 		}
19063 	}
19064 }
19065 
19066 /** Get interpolation qualifier
19067  *
19068  * @param interpolation Enumeration
19069  *
19070  * @return GLSL qualifier
19071  **/
19072 const GLchar* VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation)
19073 {
19074 	const GLchar* result = 0;
19075 
19076 	switch (interpolation)
19077 	{
19078 	case SMOOTH:
19079 		result = "smooth";
19080 		break;
19081 	case FLAT:
19082 		result = "flat";
19083 		break;
19084 	case NO_PERSPECTIVE:
19085 		result = "noperspective";
19086 		break;
19087 	default:
19088 		TCU_FAIL("Invalid enum");
19089 	}
19090 
19091 	return result;
19092 }
19093 
19094 /** Constructor
19095  *
19096  * @param context Test framework context
19097  **/
19098 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(
19099 	deqp::Context& context)
19100 	: NegativeTestBase(
19101 		  context, "varying_location_aliasing_with_mixed_auxiliary_storage",
19102 		  "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location")
19103 {
19104 }
19105 
19106 /** Source for given test case and stage
19107  *
19108  * @param test_case_index Index of test case
19109  * @param stage           Shader stage
19110  *
19111  * @return Shader source
19112  **/
19113 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint				test_case_index,
19114 																				  Utils::Shader::STAGES stage)
19115 {
19116 	static const GLchar* var_definition =
19117 		"layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
19118 		"layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
19119 	static const GLchar* input_use = "    if ((TYPE(0) == gohanINDEX_GOHAN) &&\n"
19120 									 "        (TYPE(1) == gotenINDEX_GOTEN) )\n"
19121 									 "    {\n"
19122 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
19123 									 "    }\n";
19124 	static const GLchar* output_use = "    gohanINDEX_GOHAN = TYPE(0);\n"
19125 									  "    gotenINDEX_GOTEN = TYPE(1);\n"
19126 									  "    if (vec4(0) == result)\n"
19127 									  "    {\n"
19128 									  "        gohanINDEX_GOHAN = TYPE(1);\n"
19129 									  "        gotenINDEX_GOTEN = TYPE(0);\n"
19130 									  "    }\n";
19131 	static const GLchar* fs = "#version 430 core\n"
19132 							  "#extension GL_ARB_enhanced_layouts : require\n"
19133 							  "\n"
19134 							  "in  vec4 gs_fs;\n"
19135 							  "out vec4 fs_out;\n"
19136 							  "\n"
19137 							  "void main()\n"
19138 							  "{\n"
19139 							  "    fs_out = gs_fs;\n"
19140 							  "}\n"
19141 							  "\n";
19142 	static const GLchar* fs_tested = "#version 430 core\n"
19143 									 "#extension GL_ARB_enhanced_layouts : require\n"
19144 									 "\n"
19145 									 "VAR_DEFINITION"
19146 									 "\n"
19147 									 "in  vec4 gs_fs;\n"
19148 									 "out vec4 fs_out;\n"
19149 									 "\n"
19150 									 "void main()\n"
19151 									 "{\n"
19152 									 "    vec4 result = gs_fs;\n"
19153 									 "\n"
19154 									 "VARIABLE_USE"
19155 									 "\n"
19156 									 "    fs_out = result;\n"
19157 									 "}\n"
19158 									 "\n";
19159 	static const GLchar* gs = "#version 430 core\n"
19160 							  "#extension GL_ARB_enhanced_layouts : require\n"
19161 							  "\n"
19162 							  "layout(points)                           in;\n"
19163 							  "layout(triangle_strip, max_vertices = 4) out;\n"
19164 							  "\n"
19165 							  "in  vec4 tes_gs[];\n"
19166 							  "out vec4 gs_fs;\n"
19167 							  "\n"
19168 							  "void main()\n"
19169 							  "{\n"
19170 							  "    gs_fs = tes_gs[0];\n"
19171 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
19172 							  "    EmitVertex();\n"
19173 							  "    gs_fs = tes_gs[0];\n"
19174 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
19175 							  "    EmitVertex();\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 							  "}\n"
19183 							  "\n";
19184 	static const GLchar* gs_tested = "#version 430 core\n"
19185 									 "#extension GL_ARB_enhanced_layouts : require\n"
19186 									 "\n"
19187 									 "layout(points)                           in;\n"
19188 									 "layout(triangle_strip, max_vertices = 4) out;\n"
19189 									 "\n"
19190 									 "VAR_DEFINITION"
19191 									 "\n"
19192 									 "in  vec4 tes_gs[];\n"
19193 									 "out vec4 gs_fs;\n"
19194 									 "\n"
19195 									 "void main()\n"
19196 									 "{\n"
19197 									 "    vec4 result = tes_gs[0];\n"
19198 									 "\n"
19199 									 "VARIABLE_USE"
19200 									 "\n"
19201 									 "    gs_fs = result;\n"
19202 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
19203 									 "    EmitVertex();\n"
19204 									 "    gs_fs = result;\n"
19205 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
19206 									 "    EmitVertex();\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 									 "}\n"
19214 									 "\n";
19215 	static const GLchar* tcs = "#version 430 core\n"
19216 							   "#extension GL_ARB_enhanced_layouts : require\n"
19217 							   "\n"
19218 							   "layout(vertices = 1) out;\n"
19219 							   "\n"
19220 							   "in  vec4 vs_tcs[];\n"
19221 							   "out vec4 tcs_tes[];\n"
19222 							   "\n"
19223 							   "void main()\n"
19224 							   "{\n"
19225 							   "\n"
19226 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
19227 							   "\n"
19228 							   "    gl_TessLevelOuter[0] = 1.0;\n"
19229 							   "    gl_TessLevelOuter[1] = 1.0;\n"
19230 							   "    gl_TessLevelOuter[2] = 1.0;\n"
19231 							   "    gl_TessLevelOuter[3] = 1.0;\n"
19232 							   "    gl_TessLevelInner[0] = 1.0;\n"
19233 							   "    gl_TessLevelInner[1] = 1.0;\n"
19234 							   "}\n"
19235 							   "\n";
19236 	static const GLchar* tcs_tested = "#version 430 core\n"
19237 									  "#extension GL_ARB_enhanced_layouts : require\n"
19238 									  "\n"
19239 									  "layout(vertices = 1) out;\n"
19240 									  "\n"
19241 									  "VAR_DEFINITION"
19242 									  "\n"
19243 									  "in  vec4 vs_tcs[];\n"
19244 									  "out vec4 tcs_tes[];\n"
19245 									  "\n"
19246 									  "void main()\n"
19247 									  "{\n"
19248 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
19249 									  "\n"
19250 									  "VARIABLE_USE"
19251 									  "\n"
19252 									  "    tcs_tes[gl_InvocationID] = result;\n"
19253 									  "\n"
19254 									  "    gl_TessLevelOuter[0] = 1.0;\n"
19255 									  "    gl_TessLevelOuter[1] = 1.0;\n"
19256 									  "    gl_TessLevelOuter[2] = 1.0;\n"
19257 									  "    gl_TessLevelOuter[3] = 1.0;\n"
19258 									  "    gl_TessLevelInner[0] = 1.0;\n"
19259 									  "    gl_TessLevelInner[1] = 1.0;\n"
19260 									  "}\n"
19261 									  "\n";
19262 	static const GLchar* tes = "#version 430 core\n"
19263 							   "#extension GL_ARB_enhanced_layouts : require\n"
19264 							   "\n"
19265 							   "layout(isolines, point_mode) in;\n"
19266 							   "\n"
19267 							   "in  vec4 tcs_tes[];\n"
19268 							   "out vec4 tes_gs;\n"
19269 							   "\n"
19270 							   "void main()\n"
19271 							   "{\n"
19272 							   "    tes_gs = tcs_tes[0];\n"
19273 							   "}\n"
19274 							   "\n";
19275 	static const GLchar* tes_tested = "#version 430 core\n"
19276 									  "#extension GL_ARB_enhanced_layouts : require\n"
19277 									  "\n"
19278 									  "layout(isolines, point_mode) in;\n"
19279 									  "\n"
19280 									  "VAR_DEFINITION"
19281 									  "\n"
19282 									  "in  vec4 tcs_tes[];\n"
19283 									  "out vec4 tes_gs;\n"
19284 									  "\n"
19285 									  "void main()\n"
19286 									  "{\n"
19287 									  "    vec4 result = tcs_tes[0];\n"
19288 									  "\n"
19289 									  "VARIABLE_USE"
19290 									  "\n"
19291 									  "    tes_gs += result;\n"
19292 									  "}\n"
19293 									  "\n";
19294 	static const GLchar* vs = "#version 430 core\n"
19295 							  "#extension GL_ARB_enhanced_layouts : require\n"
19296 							  "\n"
19297 							  "in  vec4 in_vs;\n"
19298 							  "out vec4 vs_tcs;\n"
19299 							  "\n"
19300 							  "void main()\n"
19301 							  "{\n"
19302 							  "    vs_tcs = in_vs;\n"
19303 							  "}\n"
19304 							  "\n";
19305 	static const GLchar* vs_tested = "#version 430 core\n"
19306 									 "#extension GL_ARB_enhanced_layouts : require\n"
19307 									 "\n"
19308 									 "VAR_DEFINITION"
19309 									 "\n"
19310 									 "in  vec4 in_vs;\n"
19311 									 "out vec4 vs_tcs;\n"
19312 									 "\n"
19313 									 "void main()\n"
19314 									 "{\n"
19315 									 "    vec4 result = in_vs;\n"
19316 									 "\n"
19317 									 "VARIABLE_USE"
19318 									 "\n"
19319 									 "    vs_tcs += result;\n"
19320 									 "}\n"
19321 									 "\n";
19322 
19323 	std::string source;
19324 	testCase&   test_case = m_test_cases[test_case_index];
19325 
19326 	if (test_case.m_stage == stage)
19327 	{
19328 		const GLchar* array_gohan = "";
19329 		const GLchar* array_goten = "";
19330 		const GLchar* aux_gohan   = getAuxiliaryQualifier(test_case.m_aux_gohan);
19331 #if DEBUG_NEG_REMOVE_ERROR
19332 		const GLchar* aux_goten = aux_gohan;
19333 #else
19334 		const GLchar* aux_goten   = getAuxiliaryQualifier(test_case.m_aux_goten);
19335 #endif /* DEBUG_NEG_REMOVE_ERROR */
19336 		GLchar		  buffer_gohan[16];
19337 		GLchar		  buffer_goten[16];
19338 		const GLchar*			 direction	 = "in";
19339 		const GLchar* index_gohan = "";
19340 		const GLchar* index_goten = "";
19341 		Utils::Variable::STORAGE storage	   = Utils::Variable::VARYING_INPUT;
19342 		const GLchar*			 interpolation = "";
19343 		size_t		  position	= 0;
19344 		size_t		  temp;
19345 		const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
19346 		const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
19347 		const GLchar* var_use		  = Utils::Shader::VERTEX == stage ? input_use : "\n";
19348 
19349 		if (false == test_case.m_is_input)
19350 		{
19351 			direction = "out";
19352 			storage   = Utils::Variable::VARYING_OUTPUT;
19353 			var_use = output_use;
19354 		}
19355 
19356 		if (isFlatRequired(stage, test_case.m_type_gohan, storage) ||
19357 			isFlatRequired(stage, test_case.m_type_goten, storage))
19358 		{
19359 			interpolation = "flat";
19360 		}
19361 
19362 		sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
19363 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
19364 
19365 		switch (stage)
19366 		{
19367 		case Utils::Shader::FRAGMENT:
19368 			source = fs_tested;
19369 			break;
19370 		case Utils::Shader::GEOMETRY:
19371 			source		= gs_tested;
19372 			array_gohan = test_case.m_is_input ? "[]" : "";
19373 			index_gohan = test_case.m_is_input ? "[0]" : "";
19374 			array_goten = test_case.m_is_input ? "[]" : "";
19375 			index_goten = test_case.m_is_input ? "[0]" : "";
19376 			break;
19377 		case Utils::Shader::TESS_CTRL:
19378 			source = tcs_tested;
19379 			if (PATCH != test_case.m_aux_gohan)
19380 			{
19381 				array_gohan = "[]";
19382 				index_gohan = "[gl_InvocationID]";
19383 			}
19384 #if DEBUG_NEG_REMOVE_ERROR
19385 			array_goten = array_gohan;
19386 			index_goten = index_gohan;
19387 #else
19388 			if (PATCH != test_case.m_aux_goten)
19389 			{
19390 				array_goten = "[]";
19391 				index_goten = "[gl_InvocationID]";
19392 			}
19393 #endif /* DEBUG_NEG_REMOVE_ERROR */
19394 			break;
19395 		case Utils::Shader::TESS_EVAL:
19396 			source		= tes_tested;
19397 			if (PATCH != test_case.m_aux_gohan)
19398 			{
19399 				array_gohan = test_case.m_is_input ? "[]" : "";
19400 				index_gohan = test_case.m_is_input ? "[0]" : "";
19401 			}
19402 #if DEBUG_NEG_REMOVE_ERROR
19403 			array_goten = array_gohan;
19404 			index_goten = index_gohan;
19405 #else
19406 			if (PATCH != test_case.m_aux_goten)
19407 			{
19408 				array_goten = test_case.m_is_input ? "[]" : "";
19409 				index_goten = test_case.m_is_input ? "[0]" : "";
19410 			}
19411 #endif /* DEBUG_NEG_REMOVE_ERROR */
19412 			break;
19413 		case Utils::Shader::VERTEX:
19414 			source = vs_tested;
19415 			break;
19416 		default:
19417 			TCU_FAIL("Invalid enum");
19418 		}
19419 
19420 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
19421 		position = 0;
19422 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
19423 		Utils::replaceToken("AUX", position, aux_gohan, source);
19424 		Utils::replaceToken("INTERPOLATION", position, interpolation, source);
19425 		Utils::replaceToken("DIRECTION", position, direction, source);
19426 		Utils::replaceToken("TYPE", position, type_gohan_name, source);
19427 		Utils::replaceToken("ARRAY", position, array_gohan, source);
19428 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
19429 		Utils::replaceToken("AUX", position, aux_goten, source);
19430 		Utils::replaceToken("INTERPOLATION", position, interpolation, source);
19431 		Utils::replaceToken("DIRECTION", position, direction, source);
19432 		Utils::replaceToken("TYPE", position, type_goten_name, source);
19433 		Utils::replaceToken("ARRAY", position, array_goten, source);
19434 
19435 		temp = position;
19436 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
19437 		position = temp;
19438 		if (!test_case.m_is_input)
19439 		{
19440 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
19441 			Utils::replaceToken("TYPE", position, type_goten_name, source);
19442 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
19443 			Utils::replaceToken("TYPE", position, type_goten_name, source);
19444 		}
19445 		else if (Utils::Shader::VERTEX == stage)
19446 		{
19447 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
19448 			Utils::replaceToken("TYPE", position, type_goten_name, source);
19449 		}
19450 
19451 		Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source);
19452 		Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source);
19453 	}
19454 	else
19455 	{
19456 		switch (stage)
19457 		{
19458 		case Utils::Shader::FRAGMENT:
19459 			source = fs;
19460 			break;
19461 		case Utils::Shader::GEOMETRY:
19462 			source = gs;
19463 			break;
19464 		case Utils::Shader::TESS_CTRL:
19465 			source = tcs;
19466 			break;
19467 		case Utils::Shader::TESS_EVAL:
19468 			source = tes;
19469 			break;
19470 		case Utils::Shader::VERTEX:
19471 			source = vs;
19472 			break;
19473 		default:
19474 			TCU_FAIL("Invalid enum");
19475 		}
19476 	}
19477 
19478 	return source;
19479 }
19480 
19481 /** Get description of test case
19482  *
19483  * @param test_case_index Index of test case
19484  *
19485  * @return Test case description
19486  **/
19487 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index)
19488 {
19489 	std::stringstream stream;
19490 	testCase&		  test_case = m_test_cases[test_case_index];
19491 
19492 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
19493 		   << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at "
19494 		   << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " "
19495 		   << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
19496 
19497 	if (true == test_case.m_is_input)
19498 	{
19499 		stream << "input";
19500 	}
19501 	else
19502 	{
19503 		stream << "output";
19504 	}
19505 
19506 	return stream.str();
19507 }
19508 
19509 /** Get number of test cases
19510  *
19511  * @return Number of test cases
19512  **/
19513 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber()
19514 {
19515 	return static_cast<GLuint>(m_test_cases.size());
19516 }
19517 
19518 /** Selects if "compute" stage is relevant for test
19519  *
19520  * @param ignored
19521  *
19522  * @return false
19523  **/
19524 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */)
19525 {
19526 	return false;
19527 }
19528 
19529 /** Prepare all test cases
19530  *
19531  **/
19532 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit()
19533 {
19534 	const GLuint		n_types					  = getTypesNumber();
19535 
19536 	for (GLuint i = 0; i < n_types; ++i)
19537 	{
19538 		const Utils::Type& type_gohan		   = getType(i);
19539 		const std::vector<GLuint>& valid_components_gohan = type_gohan.GetValidComponents();
19540 
19541 		if (valid_components_gohan.empty())
19542 		{
19543 			continue;
19544 		}
19545 
19546 		const GLuint gohan = valid_components_gohan.front();
19547 
19548 		for (GLuint j = 0; j < n_types; ++j)
19549 		{
19550 			const Utils::Type& type_goten		   = getType(j);
19551 			const std::vector<GLuint>& valid_components_goten = type_goten.GetValidComponents();
19552 
19553 			if (valid_components_goten.empty())
19554 			{
19555 				continue;
19556 			}
19557 
19558 			/* Just get the highest valid component for goten and
19559 			 * check if we can use it.
19560 			 */
19561 			const GLuint min_component = gohan + type_gohan.GetNumComponents();
19562 			const GLuint goten		   = valid_components_goten.back();
19563 
19564 			if (min_component > goten)
19565 			{
19566 				continue;
19567 			}
19568 
19569 			/* Skip invalid combinations */
19570 			if (!Utils::Type::CanTypesShareLocation(type_gohan.m_basic_type, type_goten.m_basic_type))
19571 			{
19572 				continue;
19573 			}
19574 
19575 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
19576 			{
19577 				/* Skip compute shader */
19578 				if (Utils::Shader::COMPUTE == stage)
19579 				{
19580 					continue;
19581 				}
19582 
19583 				for (GLuint aux = 0; aux < AUXILIARY_MAX; ++aux)
19584 				{
19585 					Utils::Shader::STAGES const shader_stage = static_cast<Utils::Shader::STAGES>(stage);
19586 					AUXILIARIES const			auxiliary	= static_cast<AUXILIARIES>(aux);
19587 
19588 					if (PATCH == auxiliary)
19589 					{
19590 						if (Utils::Shader::TESS_CTRL == shader_stage || Utils::Shader::TESS_EVAL == shader_stage)
19591 						{
19592 							bool	 direction			   = Utils::Shader::TESS_EVAL == shader_stage;
19593 							testCase test_case_patch_gohan = { gohan,	 goten,		auxiliary,  NONE,
19594 															   direction, shader_stage, type_gohan, type_goten };
19595 							testCase test_case_patch_goten = { gohan,	 goten,		NONE,		auxiliary,
19596 															   direction, shader_stage, type_gohan, type_goten };
19597 
19598 							m_test_cases.push_back(test_case_patch_gohan);
19599 							m_test_cases.push_back(test_case_patch_goten);
19600 						}
19601 						continue;
19602 					}
19603 
19604 					for (GLuint second_aux = 0; second_aux < AUXILIARY_MAX; ++second_aux)
19605 					{
19606 						AUXILIARIES const second_auxiliary = static_cast<AUXILIARIES>(second_aux);
19607 
19608 						if (PATCH == second_auxiliary || auxiliary == second_auxiliary)
19609 						{
19610 							continue;
19611 						}
19612 
19613 						if (Utils::Shader::FRAGMENT != shader_stage)
19614 						{
19615 							testCase test_case_out = { gohan, goten,		auxiliary,  second_auxiliary,
19616 													   false, shader_stage, type_gohan, type_goten };
19617 
19618 							m_test_cases.push_back(test_case_out);
19619 						}
19620 
19621 						if (Utils::Shader::VERTEX != shader_stage)
19622 						{
19623 							testCase test_case_in = { gohan, goten,		   auxiliary,  second_auxiliary,
19624 													  true,  shader_stage, type_gohan, type_goten };
19625 
19626 							m_test_cases.push_back(test_case_in);
19627 						}
19628 					}
19629 				}
19630 			}
19631 		}
19632 	}
19633 }
19634 
19635 /** Get auxiliary storage qualifier
19636  *
19637  * @param aux Enumeration
19638  *
19639  * @return GLSL qualifier
19640  **/
19641 const GLchar* VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux)
19642 {
19643 	const GLchar* result = 0;
19644 
19645 	switch (aux)
19646 	{
19647 	case NONE:
19648 		result = "";
19649 		break;
19650 	case PATCH:
19651 		result = "patch";
19652 		break;
19653 	case CENTROID:
19654 		result = "centroid";
19655 		break;
19656 	case SAMPLE:
19657 		result = "sample";
19658 		break;
19659 	default:
19660 		TCU_FAIL("Invalid enum");
19661 	}
19662 
19663 	return result;
19664 }
19665 
19666 /* Constants used by VertexAttribLocationAPITest */
19667 const GLuint VertexAttribLocationAPITest::m_goten_location = 6;
19668 
19669 /** Constructor
19670  *
19671  * @param context Test framework context
19672  **/
19673 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context& context)
19674 	: TextureTestBase(context, "vertex_attrib_location_api",
19675 					  "Test verifies that attribute locations API works as expected")
19676 {
19677 }
19678 
19679 /** Does BindAttribLocation for "goten" and relink program
19680  *
19681  * @param program           Program object
19682  * @param program_interface Interface of program
19683  **/
19684 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program&			 program,
19685 														Utils::ProgramInterface& program_interface)
19686 {
19687 	const Functions& gl = m_context.getRenderContext().getFunctions();
19688 
19689 	gl.bindAttribLocation(program.m_id, m_goten_location, "goten");
19690 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation");
19691 
19692 	program.Link(gl, program.m_id);
19693 
19694 	/* We still need to get locations for gohan and chichi */
19695 	TextureTestBase::prepareAttribLocation(program, program_interface);
19696 }
19697 
19698 /** Get interface of program
19699  *
19700  * @param ignored
19701  * @param program_interface   Interface of program
19702  * @param ignored
19703  **/
19704 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19705 													  Utils::ProgramInterface& program_interface,
19706 													  Utils::VaryingPassthrough& /* varying_passthrough */)
19707 {
19708 	Utils::ShaderInterface& si		  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
19709 	const Utils::Type&		type	  = Utils::Type::vec4;
19710 	const GLuint			type_size = type.GetSize();
19711 
19712 	/* Offsets */
19713 	const GLuint chichi_offset = 0;
19714 	const GLuint goten_offset  = chichi_offset + type_size;
19715 	const GLuint gohan_offset  = goten_offset + type_size;
19716 	const GLuint goku_offset   = gohan_offset + type_size;
19717 
19718 	/* Locations */
19719 	const GLuint goku_location  = 2;
19720 	const GLuint goten_location = m_goten_location;
19721 
19722 	/* Generate data */
19723 	m_goku_data   = type.GenerateDataPacked();
19724 	m_gohan_data  = type.GenerateDataPacked();
19725 	m_goten_data  = type.GenerateDataPacked();
19726 	m_chichi_data = type.GenerateDataPacked();
19727 
19728 	/* Globals */
19729 	si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19730 
19731 	/* Attributes */
19732 	si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19733 			 goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19734 			 0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid*)&m_goku_data[0] /* data */,
19735 			 m_goku_data.size() /* data_size */);
19736 
19737 	si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19738 			 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19739 			 0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */,
19740 			 (GLvoid*)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */);
19741 
19742 	si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19743 			 goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19744 			 0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */,
19745 			 (GLvoid*)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */);
19746 
19747 	si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19748 			 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19749 			 0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */,
19750 			 (GLvoid*)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */);
19751 }
19752 
19753 /** Selects if "compute" stage is relevant for test
19754  *
19755  * @param ignored
19756  *
19757  * @return false
19758  **/
19759 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19760 {
19761 	return false;
19762 }
19763 
19764 /* Constants used by FragmentDataLocationAPITest */
19765 const GLuint FragmentDataLocationAPITest::m_goten_location = 6;
19766 
19767 /** Constructor
19768  *
19769  * @param context Test framework context
19770  **/
19771 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context& context)
19772 	: TextureTestBase(context, "fragment_data_location_api",
19773 					  "Test verifies that fragment data locations API works as expected")
19774 	, m_goku(context)
19775 	, m_gohan(context)
19776 	, m_goten(context)
19777 	, m_chichi(context)
19778 	, m_goku_location(0)
19779 	, m_gohan_location(0)
19780 	, m_chichi_location(0)
19781 {
19782 }
19783 
19784 /** Verifies contents of drawn images
19785  *
19786  * @param ignored
19787  * @param ignored
19788  *
19789  * @return true if images are filled with expected values, false otherwise
19790  **/
19791 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& /* color_0 */)
19792 {
19793 	static const GLuint size			= m_width * m_height;
19794 	static const GLuint expected_goku   = 0xff000000;
19795 	static const GLuint expected_gohan  = 0xff0000ff;
19796 	static const GLuint expected_goten  = 0xff00ff00;
19797 	static const GLuint expected_chichi = 0xffff0000;
19798 
19799 	std::vector<GLuint> data;
19800 	data.resize(size);
19801 
19802 	m_goku.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19803 
19804 	for (GLuint i = 0; i < size; ++i)
19805 	{
19806 		const GLuint color = data[i];
19807 
19808 		if (expected_goku != color)
19809 		{
19810 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19811 												<< tcu::TestLog::EndMessage;
19812 			return false;
19813 		}
19814 	}
19815 
19816 	m_gohan.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19817 
19818 	for (GLuint i = 0; i < size; ++i)
19819 	{
19820 		const GLuint color = data[i];
19821 
19822 		if (expected_gohan != color)
19823 		{
19824 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19825 												<< tcu::TestLog::EndMessage;
19826 			return false;
19827 		}
19828 	}
19829 
19830 	m_goten.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19831 
19832 	for (GLuint i = 0; i < size; ++i)
19833 	{
19834 		const GLuint color = data[i];
19835 
19836 		if (expected_goten != color)
19837 		{
19838 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19839 												<< tcu::TestLog::EndMessage;
19840 			return false;
19841 		}
19842 	}
19843 
19844 	m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19845 
19846 	for (GLuint i = 0; i < size; ++i)
19847 	{
19848 		const GLuint color = data[i];
19849 
19850 		if (expected_chichi != color)
19851 		{
19852 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19853 												<< tcu::TestLog::EndMessage;
19854 			return false;
19855 		}
19856 	}
19857 
19858 	return true;
19859 }
19860 
19861 /** Prepare code snippet that will set out variables
19862  *
19863  * @param ignored
19864  * @param ignored
19865  * @param stage               Shader stage
19866  *
19867  * @return Code that pass in variables to next stage
19868  **/
19869 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */,
19870 														Utils::VaryingPassthrough& /* varying_passthrough */,
19871 														Utils::Shader::STAGES stage)
19872 {
19873 	std::string result;
19874 
19875 	/* Skip for compute shader */
19876 	if (Utils::Shader::FRAGMENT != stage)
19877 	{
19878 		result = "";
19879 	}
19880 	else
19881 	{
19882 		result = "chichi = vec4(0, 0, 1, 1);\n"
19883 				 "    goku   = vec4(0, 0, 0, 1);\n"
19884 				 "    goten  = vec4(0, 1, 0, 1);\n"
19885 				 "    gohan  = vec4(1, 0, 0, 1);\n";
19886 	}
19887 
19888 	return result;
19889 }
19890 
19891 /** Get interface of program
19892  *
19893  * @param ignored
19894  * @param program_interface Interface of program
19895  * @param ignored
19896  **/
19897 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19898 													  Utils::ProgramInterface& program_interface,
19899 													  Utils::VaryingPassthrough& /* varying_passthrough */)
19900 {
19901 	Utils::ShaderInterface& si   = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19902 	const Utils::Type&		type = Utils::Type::vec4;
19903 
19904 	/* Locations */
19905 	m_goku_location = 2;
19906 
19907 	/* Globals */
19908 	si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19909 
19910 	/* Attributes */
19911 	si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19912 			  m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19913 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19914 
19915 	si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19916 			  Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19917 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19918 
19919 	si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19920 			  m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19921 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19922 
19923 	si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19924 			  Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19925 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19926 }
19927 
19928 /** Selects if "compute" stage is relevant for test
19929  *
19930  * @param ignored
19931  *
19932  * @return false
19933  **/
19934 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19935 {
19936 	return false;
19937 }
19938 
19939 /** Get locations for all outputs with automatic_location
19940  *
19941  * @param program           Program object
19942  * @param program_interface Interface of program
19943  **/
19944 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program&		  program,
19945 														 Utils::ProgramInterface& program_interface)
19946 {
19947 	/* Bind location of goten */
19948 	const Functions& gl = m_context.getRenderContext().getFunctions();
19949 
19950 	gl.bindFragDataLocation(program.m_id, m_goten_location, "goten");
19951 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation");
19952 
19953 	program.Link(gl, program.m_id);
19954 
19955 	/* Prepare locations for gohan and chichi */
19956 	TextureTestBase::prepareFragmentDataLoc(program, program_interface);
19957 
19958 	/* Get all locations */
19959 	Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19960 
19961 	Utils::Variable::PtrVector& outputs = si.m_outputs;
19962 
19963 	for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
19964 	{
19965 		const Utils::Variable::Descriptor& desc = (*it)->m_descriptor;
19966 
19967 		if (0 == desc.m_name.compare("gohan"))
19968 		{
19969 			m_gohan_location = desc.m_expected_location;
19970 		}
19971 		else if (0 == desc.m_name.compare("chichi"))
19972 		{
19973 			m_chichi_location = desc.m_expected_location;
19974 		}
19975 
19976 		/* Locations of goku and goten are fixed */
19977 	}
19978 }
19979 
19980 /** Prepare framebuffer with single texture as color attachment
19981  *
19982  * @param framebuffer     Framebuffer
19983  * @param color_0_texture Texture that will used as color attachment
19984  **/
19985 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
19986 {
19987 	/* Let parent prepare its stuff */
19988 	TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture);
19989 
19990 	/* Prepare data */
19991 	std::vector<GLuint> texture_data;
19992 	texture_data.resize(m_width * m_height);
19993 
19994 	for (GLuint i = 0; i < texture_data.size(); ++i)
19995 	{
19996 		texture_data[i] = 0x20406080;
19997 	}
19998 
19999 	/* Prepare textures */
20000 	m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20001 
20002 	m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20003 
20004 	m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20005 
20006 	m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20007 
20008 	/* Attach textures to framebuffer */
20009 	framebuffer.Bind();
20010 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height);
20011 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height);
20012 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height);
20013 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height);
20014 
20015 	/* Set up drawbuffers */
20016 	const Functions& gl = m_context.getRenderContext().getFunctions();
20017 	// The fragment shader can have more than 4 color outputs, but it only care about 4 (goku, gohan, goten, chichi).
20018 	// We will first initialize all draw buffers to NONE and then set the real value for the 4 outputs we care about
20019 	GLint maxDrawBuffers = 0;
20020 	gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
20021 
20022 	std::vector<GLenum> buffers(maxDrawBuffers, GL_NONE);
20023 	buffers[m_chichi_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location);
20024 	buffers[m_goten_location]  = GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location);
20025 	buffers[m_goku_location]   = GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location);
20026 	buffers[m_gohan_location]  = GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location);
20027 
20028 	gl.drawBuffers(maxDrawBuffers, buffers.data());
20029 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
20030 }
20031 
20032 /** Constructor
20033  *
20034  * @param context Test framework context
20035  **/
20036 XFBInputTest::XFBInputTest(deqp::Context& context)
20037 	: NegativeTestBase(context, "xfb_input",
20038 					   "Test verifies that compiler reports error when xfb qualifiers are used with input")
20039 {
20040 }
20041 
20042 /** Source for given test case and stage
20043  *
20044  * @param test_case_index Index of test case
20045  * @param stage           Shader stage
20046  *
20047  * @return Shader source
20048  **/
20049 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20050 {
20051 #if DEBUG_NEG_REMOVE_ERROR
20052 	static const GLchar* buffer_var_definition = "/* layout (xfb_buffer = 2) */ in vec4 gohanARRAY;\n";
20053 	static const GLchar* offset_var_definition = "/* layout (xfb_offset = 16) */ in vec4 gohanARRAY;\n";
20054 	static const GLchar* stride_var_definition = "/* layout (xfb_stride = 32) */ in vec4 gohanARRAY;\n";
20055 #else
20056 	static const GLchar* buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n";
20057 	static const GLchar* offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n";
20058 	static const GLchar* stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n";
20059 #endif /* DEBUG_NEG_REMOVE_ERROR */
20060 	static const GLchar* fs					   = "#version 430 core\n"
20061 							  "#extension GL_ARB_enhanced_layouts : require\n"
20062 							  "\n"
20063 							  "in  vec4 gs_fs;\n"
20064 							  "out vec4 fs_out;\n"
20065 							  "\n"
20066 							  "void main()\n"
20067 							  "{\n"
20068 							  "    fs_out = gs_fs;\n"
20069 							  "}\n"
20070 							  "\n";
20071 	static const GLchar* fs_tested = "#version 430 core\n"
20072 									 "#extension GL_ARB_enhanced_layouts : require\n"
20073 									 "\n"
20074 									 "VAR_DEFINITION"
20075 									 "\n"
20076 									 "in  vec4 gs_fs;\n"
20077 									 "out vec4 fs_out;\n"
20078 									 "\n"
20079 									 "void main()\n"
20080 									 "{\n"
20081 									 "    vec4 result = gs_fs;\n"
20082 									 "\n"
20083 									 "    fs_out = result;\n"
20084 									 "}\n"
20085 									 "\n";
20086 	static const GLchar* gs = "#version 430 core\n"
20087 							  "#extension GL_ARB_enhanced_layouts : require\n"
20088 							  "\n"
20089 							  "layout(points)                           in;\n"
20090 							  "layout(triangle_strip, max_vertices = 4) out;\n"
20091 							  "\n"
20092 							  "in  vec4 tes_gs[];\n"
20093 							  "out vec4 gs_fs;\n"
20094 							  "\n"
20095 							  "void main()\n"
20096 							  "{\n"
20097 							  "    gs_fs = tes_gs[0];\n"
20098 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
20099 							  "    EmitVertex();\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 							  "}\n"
20110 							  "\n";
20111 	static const GLchar* gs_tested = "#version 430 core\n"
20112 									 "#extension GL_ARB_enhanced_layouts : require\n"
20113 									 "\n"
20114 									 "layout(points)                           in;\n"
20115 									 "layout(triangle_strip, max_vertices = 4) out;\n"
20116 									 "\n"
20117 									 "VAR_DEFINITION"
20118 									 "\n"
20119 									 "in  vec4 tes_gs[];\n"
20120 									 "out vec4 gs_fs;\n"
20121 									 "\n"
20122 									 "void main()\n"
20123 									 "{\n"
20124 									 "    vec4 result = tes_gs[0];\n"
20125 									 "\n"
20126 									 "    gs_fs = result;\n"
20127 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
20128 									 "    EmitVertex();\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 									 "}\n"
20139 									 "\n";
20140 	static const GLchar* tcs = "#version 430 core\n"
20141 							   "#extension GL_ARB_enhanced_layouts : require\n"
20142 							   "\n"
20143 							   "layout(vertices = 1) out;\n"
20144 							   "\n"
20145 							   "in  vec4 vs_tcs[];\n"
20146 							   "out vec4 tcs_tes[];\n"
20147 							   "\n"
20148 							   "void main()\n"
20149 							   "{\n"
20150 							   "\n"
20151 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
20152 							   "\n"
20153 							   "    gl_TessLevelOuter[0] = 1.0;\n"
20154 							   "    gl_TessLevelOuter[1] = 1.0;\n"
20155 							   "    gl_TessLevelOuter[2] = 1.0;\n"
20156 							   "    gl_TessLevelOuter[3] = 1.0;\n"
20157 							   "    gl_TessLevelInner[0] = 1.0;\n"
20158 							   "    gl_TessLevelInner[1] = 1.0;\n"
20159 							   "}\n"
20160 							   "\n";
20161 	static const GLchar* tcs_tested = "#version 430 core\n"
20162 									  "#extension GL_ARB_enhanced_layouts : require\n"
20163 									  "\n"
20164 									  "layout(vertices = 1) out;\n"
20165 									  "\n"
20166 									  "VAR_DEFINITION"
20167 									  "\n"
20168 									  "in  vec4 vs_tcs[];\n"
20169 									  "out vec4 tcs_tes[];\n"
20170 									  "\n"
20171 									  "void main()\n"
20172 									  "{\n"
20173 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
20174 									  "\n"
20175 									  "    tcs_tes[gl_InvocationID] = result;\n"
20176 									  "\n"
20177 									  "    gl_TessLevelOuter[0] = 1.0;\n"
20178 									  "    gl_TessLevelOuter[1] = 1.0;\n"
20179 									  "    gl_TessLevelOuter[2] = 1.0;\n"
20180 									  "    gl_TessLevelOuter[3] = 1.0;\n"
20181 									  "    gl_TessLevelInner[0] = 1.0;\n"
20182 									  "    gl_TessLevelInner[1] = 1.0;\n"
20183 									  "}\n"
20184 									  "\n";
20185 	static const GLchar* tes = "#version 430 core\n"
20186 							   "#extension GL_ARB_enhanced_layouts : require\n"
20187 							   "\n"
20188 							   "layout(isolines, point_mode) in;\n"
20189 							   "\n"
20190 							   "in  vec4 tcs_tes[];\n"
20191 							   "out vec4 tes_gs;\n"
20192 							   "\n"
20193 							   "void main()\n"
20194 							   "{\n"
20195 							   "    tes_gs = tcs_tes[0];\n"
20196 							   "}\n"
20197 							   "\n";
20198 	static const GLchar* tes_tested = "#version 430 core\n"
20199 									  "#extension GL_ARB_enhanced_layouts : require\n"
20200 									  "\n"
20201 									  "layout(isolines, point_mode) in;\n"
20202 									  "\n"
20203 									  "VAR_DEFINITION"
20204 									  "\n"
20205 									  "in  vec4 tcs_tes[];\n"
20206 									  "out vec4 tes_gs;\n"
20207 									  "\n"
20208 									  "void main()\n"
20209 									  "{\n"
20210 									  "    vec4 result = tcs_tes[0];\n"
20211 									  "\n"
20212 									  "    tes_gs += result;\n"
20213 									  "}\n"
20214 									  "\n";
20215 	static const GLchar* vs = "#version 430 core\n"
20216 							  "#extension GL_ARB_enhanced_layouts : require\n"
20217 							  "\n"
20218 							  "in  vec4 in_vs;\n"
20219 							  "out vec4 vs_tcs;\n"
20220 							  "\n"
20221 							  "void main()\n"
20222 							  "{\n"
20223 							  "    vs_tcs = in_vs;\n"
20224 							  "}\n"
20225 							  "\n";
20226 	static const GLchar* vs_tested = "#version 430 core\n"
20227 									 "#extension GL_ARB_enhanced_layouts : require\n"
20228 									 "\n"
20229 									 "VAR_DEFINITION"
20230 									 "\n"
20231 									 "in  vec4 in_vs;\n"
20232 									 "out vec4 vs_tcs;\n"
20233 									 "\n"
20234 									 "void main()\n"
20235 									 "{\n"
20236 									 "    vec4 result = in_vs;\n"
20237 									 "\n"
20238 									 "    vs_tcs += result;\n"
20239 									 "}\n"
20240 									 "\n";
20241 
20242 	std::string source;
20243 	testCase&   test_case = m_test_cases[test_case_index];
20244 
20245 	if (test_case.m_stage == stage)
20246 	{
20247 		const GLchar* array	= "";
20248 		size_t		  position = 0;
20249 		const GLchar* var_definition = 0;
20250 
20251 		switch (test_case.m_qualifier)
20252 		{
20253 		case BUFFER:
20254 			var_definition = buffer_var_definition;
20255 			break;
20256 		case OFFSET:
20257 			var_definition = offset_var_definition;
20258 			break;
20259 		case STRIDE:
20260 			var_definition = stride_var_definition;
20261 			break;
20262 		default:
20263 			TCU_FAIL("Invalid enum");
20264 		}
20265 
20266 		switch (stage)
20267 		{
20268 		case Utils::Shader::FRAGMENT:
20269 			source = fs_tested;
20270 			break;
20271 		case Utils::Shader::GEOMETRY:
20272 			source = gs_tested;
20273 			array  = "[]";
20274 			break;
20275 		case Utils::Shader::TESS_CTRL:
20276 			source = tcs_tested;
20277 			array  = "[]";
20278 			break;
20279 		case Utils::Shader::TESS_EVAL:
20280 			source = tes_tested;
20281 			array  = "[]";
20282 			break;
20283 		case Utils::Shader::VERTEX:
20284 			source = vs_tested;
20285 			break;
20286 		default:
20287 			TCU_FAIL("Invalid enum");
20288 		}
20289 
20290 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
20291 		position = 0;
20292 		Utils::replaceToken("ARRAY", position, array, source);
20293 	}
20294 	else
20295 	{
20296 		switch (stage)
20297 		{
20298 		case Utils::Shader::FRAGMENT:
20299 			source = fs;
20300 			break;
20301 		case Utils::Shader::GEOMETRY:
20302 			source = gs;
20303 			break;
20304 		case Utils::Shader::TESS_CTRL:
20305 			source = tcs;
20306 			break;
20307 		case Utils::Shader::TESS_EVAL:
20308 			source = tes;
20309 			break;
20310 		case Utils::Shader::VERTEX:
20311 			source = vs;
20312 			break;
20313 		default:
20314 			TCU_FAIL("Invalid enum");
20315 		}
20316 	}
20317 
20318 	return source;
20319 }
20320 
20321 /** Get description of test case
20322  *
20323  * @param test_case_index Index of test case
20324  *
20325  * @return Test case description
20326  **/
20327 std::string XFBInputTest::getTestCaseName(GLuint test_case_index)
20328 {
20329 	std::stringstream stream;
20330 	testCase&		  test_case = m_test_cases[test_case_index];
20331 
20332 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: ";
20333 
20334 	switch (test_case.m_qualifier)
20335 	{
20336 	case BUFFER:
20337 		stream << "xfb_buffer";
20338 		break;
20339 	case OFFSET:
20340 		stream << "xfb_offset";
20341 		break;
20342 	case STRIDE:
20343 		stream << "xfb_stride";
20344 		break;
20345 	default:
20346 		TCU_FAIL("Invalid enum");
20347 	}
20348 
20349 	return stream.str();
20350 }
20351 
20352 /** Get number of test cases
20353  *
20354  * @return Number of test cases
20355  **/
20356 GLuint XFBInputTest::getTestCaseNumber()
20357 {
20358 	return static_cast<GLuint>(m_test_cases.size());
20359 }
20360 
20361 /** Selects if "compute" stage is relevant for test
20362  *
20363  * @param ignored
20364  *
20365  * @return false
20366  **/
20367 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */)
20368 {
20369 	return false;
20370 }
20371 
20372 /** Prepare all test cases
20373  *
20374  **/
20375 void XFBInputTest::testInit()
20376 {
20377 	for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
20378 	{
20379 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
20380 		{
20381 			if (Utils::Shader::COMPUTE == stage)
20382 			{
20383 				continue;
20384 			}
20385 
20386 			testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
20387 
20388 			m_test_cases.push_back(test_case);
20389 		}
20390 	}
20391 }
20392 
20393 /* Constants used by XFBAllStagesTest */
20394 const GLuint XFBAllStagesTest::m_gs_index = 3;
20395 
20396 /** Constructor
20397  *
20398  * @param context Test context
20399  **/
20400 XFBAllStagesTest::XFBAllStagesTest(deqp::Context& context)
20401 	: BufferTestBase(context, "xfb_all_stages",
20402 					 "Test verifies that only last stage in vertex processing can output to transform feedback")
20403 {
20404 	/* Nothing to be done here */
20405 }
20406 
20407 /** Get descriptors of buffers necessary for test
20408  *
20409  * @param ignored
20410  * @param out_descriptors Descriptors of buffers used by test
20411  **/
20412 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
20413 											bufferDescriptor::Vector& out_descriptors)
20414 {
20415 	static const GLuint n_stages = 4;
20416 	const Utils::Type&  vec4	 = Utils::Type::vec4;
20417 
20418 	/* Data */
20419 	tcu::Vec4 sum;
20420 
20421 	/* Test uses single uniform and xfb per stage + uniform for fragment shader */
20422 	out_descriptors.resize(n_stages * 2 + 1);
20423 
20424 	/* */
20425 	for (GLuint i = 0; i < n_stages; ++i)
20426 	{
20427 		/* Get references */
20428 		bufferDescriptor& uniform = out_descriptors[i + 0];
20429 		bufferDescriptor& xfb	 = out_descriptors[i + n_stages];
20430 
20431 		/* Index */
20432 		uniform.m_index = i;
20433 		xfb.m_index		= i;
20434 
20435 		/* Target */
20436 		uniform.m_target = Utils::Buffer::Uniform;
20437 		xfb.m_target	 = Utils::Buffer::Transform_feedback;
20438 
20439 		/* Data */
20440 		const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
20441 
20442 		sum += var;
20443 
20444 		uniform.m_initial_data.resize(vec4.GetSize());
20445 		memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
20446 
20447 		xfb.m_initial_data = vec4.GenerateDataPacked();
20448 
20449 		if (m_gs_index != i)
20450 		{
20451 			xfb.m_expected_data = xfb.m_initial_data;
20452 		}
20453 		else
20454 		{
20455 			xfb.m_expected_data.resize(vec4.GetSize());
20456 			memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize());
20457 		}
20458 	}
20459 
20460 	/* FS */
20461 	{
20462 		/* Get reference */
20463 		bufferDescriptor& uniform = out_descriptors[n_stages * 2];
20464 
20465 		/* Index */
20466 		uniform.m_index = n_stages;
20467 
20468 		/* Target */
20469 		uniform.m_target = Utils::Buffer::Uniform;
20470 
20471 		/* Data */
20472 		const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
20473 
20474 		uniform.m_initial_data.resize(vec4.GetSize());
20475 		memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
20476 	}
20477 }
20478 
20479 /** Get body of main function for given shader stage
20480  *
20481  * @param ignored
20482  * @param stage            Shader stage
20483  * @param out_assignments  Set to empty
20484  * @param out_calculations Set to empty
20485  **/
20486 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20487 									 std::string& out_assignments, std::string& out_calculations)
20488 {
20489 	out_calculations = "";
20490 
20491 	static const GLchar* vs  = "    vs_tcs  = uni_vs;\n";
20492 	static const GLchar* tcs = "    tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n";
20493 	static const GLchar* tes = "    tes_gs  = uni_tes + tcs_tes[0];\n";
20494 	static const GLchar* gs  = "    gs_fs   = uni_gs  + tes_gs[0];\n";
20495 	static const GLchar* fs  = "    fs_out  = uni_fs  + gs_fs;\n";
20496 
20497 	const GLchar* assignments = 0;
20498 	switch (stage)
20499 	{
20500 	case Utils::Shader::FRAGMENT:
20501 		assignments = fs;
20502 		break;
20503 	case Utils::Shader::GEOMETRY:
20504 		assignments = gs;
20505 		break;
20506 	case Utils::Shader::TESS_CTRL:
20507 		assignments = tcs;
20508 		break;
20509 	case Utils::Shader::TESS_EVAL:
20510 		assignments = tes;
20511 		break;
20512 	case Utils::Shader::VERTEX:
20513 		assignments = vs;
20514 		break;
20515 	default:
20516 		TCU_FAIL("Invalid enum");
20517 	}
20518 
20519 	out_assignments = assignments;
20520 }
20521 
20522 /** Get interface of shader
20523  *
20524  * @param ignored
20525  * @param stage         Shader stage
20526  * @param out_interface Set to ""
20527  **/
20528 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20529 										  std::string& out_interface)
20530 {
20531 	static const GLchar* vs = "layout(xfb_buffer = 0, xfb_offset = 0) out     vec4 vs_tcs;\n"
20532 							  "layout(binding    = 0)                 uniform vs_block {\n"
20533 							  "    vec4 uni_vs;\n"
20534 							  "};\n";
20535 	static const GLchar* tcs = "                                       in      vec4 vs_tcs[];\n"
20536 							   "layout(xfb_buffer = 1, xfb_offset = 0) out     vec4 tcs_tes[1];\n"
20537 							   "layout(binding    = 1)                 uniform tcs_block {\n"
20538 							   "    vec4 uni_tcs;\n"
20539 							   "};\n";
20540 	static const GLchar* tes = "                                       in      vec4 tcs_tes[];\n"
20541 							   "layout(xfb_buffer = 2, xfb_offset = 0) out     vec4 tes_gs;\n"
20542 							   "layout(binding    = 2)                 uniform tes_block {\n"
20543 							   "    vec4 uni_tes;\n"
20544 							   "};\n";
20545 	static const GLchar* gs = "                                       in      vec4 tes_gs[];\n"
20546 							  "layout(xfb_buffer = 3, xfb_offset = 0) out     vec4 gs_fs;\n"
20547 							  "layout(binding    = 3)                 uniform gs_block {\n"
20548 							  "    vec4 uni_gs;\n"
20549 							  "};\n";
20550 	static const GLchar* fs = "                       in      vec4 gs_fs;\n"
20551 							  "                       out     vec4 fs_out;\n"
20552 							  "layout(binding    = 4) uniform fs_block {\n"
20553 							  "    vec4 uni_fs;\n"
20554 							  "};\n";
20555 
20556 	const GLchar* interface = 0;
20557 	switch (stage)
20558 	{
20559 	case Utils::Shader::FRAGMENT:
20560 		interface = fs;
20561 		break;
20562 	case Utils::Shader::GEOMETRY:
20563 		interface = gs;
20564 		break;
20565 	case Utils::Shader::TESS_CTRL:
20566 		interface = tcs;
20567 		break;
20568 	case Utils::Shader::TESS_EVAL:
20569 		interface = tes;
20570 		break;
20571 	case Utils::Shader::VERTEX:
20572 		interface = vs;
20573 		break;
20574 	default:
20575 		TCU_FAIL("Invalid enum");
20576 	}
20577 
20578 	out_interface = interface;
20579 }
20580 
20581 /* Constants used by XFBStrideOfEmptyListTest */
20582 const GLuint XFBStrideOfEmptyListTest::m_stride = 64;
20583 
20584 /** Constructor
20585  *
20586  * @param context Test context
20587  **/
20588 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context& context)
20589 	: BufferTestBase(
20590 		  context, "xfb_stride_of_empty_list",
20591 		  "Test verifies correct behavior when xfb_stride qualifier is specified but no xfb_offset is specified")
20592 {
20593 	/* Nothing to be done here */
20594 }
20595 
20596 /** Execute drawArrays for single vertex
20597  *
20598  * @param test_case_index Index of test case
20599  *
20600  * @return true if proper error is reported
20601  **/
20602 bool XFBStrideOfEmptyListTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20603 {
20604 	const Functions& gl		= m_context.getRenderContext().getFunctions();
20605 	bool			 result = true;
20606 
20607 	/* Draw */
20608 	gl.disable(GL_RASTERIZER_DISCARD);
20609 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20610 
20611 	gl.beginTransformFeedback(GL_POINTS);
20612 	GLenum error = gl.getError();
20613 	switch (test_case_index)
20614 	{
20615 	case VALID:
20616 		if (GL_NO_ERROR != error)
20617 		{
20618 			gl.endTransformFeedback();
20619 			GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20620 		}
20621 
20622 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20623 		error = gl.getError();
20624 
20625 		gl.endTransformFeedback();
20626 		GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20627 		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20628 
20629 		break;
20630 
20631 	case FIRST_MISSING:
20632 		if (GL_NO_ERROR == error)
20633 		{
20634 			gl.endTransformFeedback();
20635 		}
20636 
20637 		if (GL_INVALID_OPERATION != error)
20638 		{
20639 			m_context.getTestContext().getLog()
20640 				<< tcu::TestLog::Message << "XFB at index 0, that is written by GS, is missing. It was expected that "
20641 											"INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20642 				<< glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20643 
20644 			result = false;
20645 		}
20646 
20647 		break;
20648 
20649 	case SECOND_MISSING:
20650 		if (GL_NO_ERROR != error)
20651 		{
20652 			gl.endTransformFeedback();
20653 			GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20654 		}
20655 
20656 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20657 		error = gl.getError();
20658 
20659 		gl.endTransformFeedback();
20660 		GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20661 		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20662 
20663 		break;
20664 	}
20665 
20666 	/* Done */
20667 	return result;
20668 }
20669 
20670 /** Get descriptors of buffers necessary for test
20671  *
20672  * @param test_case_index Index of test case
20673  * @param out_descriptors Descriptors of buffers used by test
20674  **/
20675 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint				  test_case_index,
20676 													bufferDescriptor::Vector& out_descriptors)
20677 {
20678 	switch (test_case_index)
20679 	{
20680 	case VALID:
20681 	{
20682 		/* Test needs single uniform and two xfbs */
20683 		out_descriptors.resize(3);
20684 
20685 		/* Get references */
20686 		bufferDescriptor& uniform = out_descriptors[0];
20687 		bufferDescriptor& xfb_0   = out_descriptors[1];
20688 		bufferDescriptor& xfb_1   = out_descriptors[2];
20689 
20690 		/* Index */
20691 		uniform.m_index = 0;
20692 		xfb_0.m_index   = 0;
20693 		xfb_1.m_index   = 1;
20694 
20695 		/* Target */
20696 		uniform.m_target = Utils::Buffer::Uniform;
20697 		xfb_0.m_target   = Utils::Buffer::Transform_feedback;
20698 		xfb_1.m_target   = Utils::Buffer::Transform_feedback;
20699 
20700 		/* Data */
20701 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20702 
20703 		xfb_0.m_initial_data  = Utils::Type::vec4.GenerateDataPacked();
20704 		xfb_0.m_expected_data = uniform.m_initial_data;
20705 
20706 		/* Data, contents are the same as no modification is expected */
20707 		xfb_1.m_initial_data.resize(m_stride);
20708 		xfb_1.m_expected_data.resize(m_stride);
20709 
20710 		for (GLuint i = 0; i < m_stride; ++i)
20711 		{
20712 			xfb_1.m_initial_data[0]  = (glw::GLubyte)i;
20713 			xfb_1.m_expected_data[0] = (glw::GLubyte)i;
20714 		}
20715 	}
20716 
20717 	break;
20718 
20719 	case FIRST_MISSING:
20720 	{
20721 		/* Test needs single uniform and two xfbs */
20722 		out_descriptors.resize(2);
20723 
20724 		/* Get references */
20725 		bufferDescriptor& uniform = out_descriptors[0];
20726 		bufferDescriptor& xfb_1   = out_descriptors[1];
20727 
20728 		/* Index */
20729 		uniform.m_index = 0;
20730 		xfb_1.m_index   = 1;
20731 
20732 		/* Target */
20733 		uniform.m_target = Utils::Buffer::Uniform;
20734 		xfb_1.m_target   = Utils::Buffer::Transform_feedback;
20735 
20736 		/* Data */
20737 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20738 
20739 		/* Draw call will not be executed, contents does not matter */
20740 		xfb_1.m_initial_data.resize(m_stride);
20741 	}
20742 
20743 	break;
20744 
20745 	case SECOND_MISSING:
20746 	{
20747 		/* Test needs single uniform and two xfbs */
20748 		out_descriptors.resize(2);
20749 
20750 		/* Get references */
20751 		bufferDescriptor& uniform = out_descriptors[0];
20752 		bufferDescriptor& xfb_0   = out_descriptors[1];
20753 
20754 		/* Index */
20755 		uniform.m_index = 0;
20756 		xfb_0.m_index   = 0;
20757 
20758 		/* Target */
20759 		uniform.m_target = Utils::Buffer::Uniform;
20760 		xfb_0.m_target   = Utils::Buffer::Transform_feedback;
20761 
20762 		/* Data */
20763 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20764 
20765 		xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20766 		xfb_0.m_expected_data = uniform.m_initial_data;
20767 	}
20768 
20769 	break;
20770 	}
20771 }
20772 
20773 /** Get body of main function for given shader stage
20774  *
20775  * @param ignored
20776  * @param stage            Shader stage
20777  * @param out_assignments  Set to empty
20778  * @param out_calculations Set to empty
20779  **/
20780 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20781 											 std::string& out_assignments, std::string& out_calculations)
20782 {
20783 	out_calculations = "";
20784 
20785 	static const GLchar* gs = "    gs_fs  = uni_gs;\n";
20786 	static const GLchar* fs = "    fs_out = vec4(gs_fs);\n";
20787 
20788 	const GLchar* assignments = "";
20789 	switch (stage)
20790 	{
20791 	case Utils::Shader::FRAGMENT:
20792 		assignments = fs;
20793 		break;
20794 	case Utils::Shader::GEOMETRY:
20795 		assignments = gs;
20796 		break;
20797 	default:
20798 		break;
20799 	}
20800 
20801 	out_assignments = assignments;
20802 }
20803 
20804 /** Get interface of shader
20805  *
20806  * @param ignored
20807  * @param stage            Shader stage
20808  * @param out_interface    Set to ""
20809  **/
20810 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20811 												  std::string& out_interface)
20812 {
20813 	static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0)  out     vec4 gs_fs;\n"
20814 							  "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
20815 							  "\n"
20816 							  "layout (binding    = 0)                  uniform gs_block {\n"
20817 							  "    vec4 uni_gs;\n"
20818 							  "};\n";
20819 	static const GLchar* fs = "in  vec4 gs_fs;\n"
20820 							  "out vec4 fs_out;\n";
20821 
20822 	switch (stage)
20823 	{
20824 	case Utils::Shader::FRAGMENT:
20825 		out_interface = fs;
20826 		break;
20827 	case Utils::Shader::GEOMETRY:
20828 		out_interface = gs;
20829 		break;
20830 	default:
20831 		out_interface = "";
20832 		return;
20833 	}
20834 }
20835 
20836 /** Returns buffer details in human readable form.
20837  *
20838  * @param test_case_index Index of test case
20839  *
20840  * @return Case description
20841  **/
20842 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index)
20843 {
20844 	std::string result;
20845 
20846 	switch (test_case_index)
20847 	{
20848 	case VALID:
20849 		result = "Valid case";
20850 		break;
20851 	case FIRST_MISSING:
20852 		result = "Missing xfb at index 0";
20853 		break;
20854 	case SECOND_MISSING:
20855 		result = "Missing xfb at index 1";
20856 		break;
20857 	default:
20858 		TCU_FAIL("Invalid enum");
20859 	}
20860 
20861 	return result;
20862 }
20863 
20864 /** Get number of test cases
20865  *
20866  * @return 3
20867  **/
20868 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber()
20869 {
20870 	return 3;
20871 }
20872 
20873 /* Constants used by XFBStrideOfEmptyListTest */
20874 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64;
20875 
20876 /** Constructor
20877  *
20878  * @param context Test context
20879  **/
20880 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context& context)
20881 	: BufferTestBase(context, "xfb_stride_of_empty_list_and_api",
20882 					 "Test verifies that xfb_stride qualifier is not overriden by API")
20883 {
20884 	/* Nothing to be done here */
20885 }
20886 
20887 /** Execute drawArrays for single vertex
20888  *
20889  * @param test_case_index Index of test case
20890  *
20891  * @return true if proper error is reported
20892  **/
20893 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20894 {
20895 	const Functions& gl		= m_context.getRenderContext().getFunctions();
20896 	bool			 result = true;
20897 
20898 	/* Draw */
20899 	gl.disable(GL_RASTERIZER_DISCARD);
20900 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20901 
20902 	gl.beginTransformFeedback(GL_POINTS);
20903 	GLenum error = gl.getError();
20904 	switch (test_case_index)
20905 	{
20906 	case VALID:
20907 		if (GL_NO_ERROR != error)
20908 		{
20909 			gl.endTransformFeedback();
20910 			GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20911 		}
20912 
20913 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20914 		error = gl.getError();
20915 
20916 		gl.endTransformFeedback();
20917 		GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20918 		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20919 
20920 		break;
20921 
20922 	case FIRST_MISSING:
20923 		if (GL_NO_ERROR != error)
20924 		{
20925 			gl.endTransformFeedback();
20926 			GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20927 		}
20928 
20929 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20930 		error = gl.getError();
20931 
20932 		gl.endTransformFeedback();
20933 		GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20934 		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20935 
20936 		break;
20937 
20938 	case SECOND_MISSING:
20939 		if (GL_NO_ERROR == error)
20940 		{
20941 			gl.endTransformFeedback();
20942 		}
20943 
20944 		if (GL_INVALID_OPERATION != error)
20945 		{
20946 			m_context.getTestContext().getLog()
20947 				<< tcu::TestLog::Message << "XFB at index 1, that is declared as empty, is missing. It was expected "
20948 											"that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20949 				<< glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20950 
20951 			result = false;
20952 		}
20953 
20954 		break;
20955 	}
20956 
20957 	/* Done */
20958 	return result;
20959 }
20960 
20961 /** Get descriptors of buffers necessary for test
20962  *
20963  * @param test_case_index Index of test case
20964  * @param out_descriptors Descriptors of buffers used by test
20965  **/
20966 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint				test_case_index,
20967 														  bufferDescriptor::Vector& out_descriptors)
20968 {
20969 	switch (test_case_index)
20970 	{
20971 	case VALID:
20972 	{
20973 		/* Test needs single uniform and two xfbs */
20974 		out_descriptors.resize(3);
20975 
20976 		/* Get references */
20977 		bufferDescriptor& uniform = out_descriptors[0];
20978 		bufferDescriptor& xfb_0   = out_descriptors[1];
20979 		bufferDescriptor& xfb_1   = out_descriptors[2];
20980 
20981 		/* Index */
20982 		uniform.m_index = 0;
20983 		xfb_0.m_index   = 0;
20984 		xfb_1.m_index   = 1;
20985 
20986 		/* Target */
20987 		uniform.m_target = Utils::Buffer::Uniform;
20988 		xfb_0.m_target   = Utils::Buffer::Transform_feedback;
20989 		xfb_1.m_target   = Utils::Buffer::Transform_feedback;
20990 
20991 		/* Data */
20992 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20993 
20994 		/* Data, contents are the same as no modification is expected */
20995 		xfb_0.m_initial_data.resize(m_stride);
20996 		xfb_0.m_expected_data.resize(m_stride);
20997 
20998 		for (GLuint i = 0; i < m_stride; ++i)
20999 		{
21000 			xfb_0.m_initial_data[0]  = (glw::GLubyte)i;
21001 			xfb_0.m_expected_data[0] = (glw::GLubyte)i;
21002 		}
21003 
21004 		xfb_1.m_initial_data  = Utils::Type::vec4.GenerateDataPacked();
21005 		xfb_1.m_expected_data = uniform.m_initial_data;
21006 	}
21007 
21008 	break;
21009 
21010 	case FIRST_MISSING:
21011 	{
21012 		/* Test needs single uniform and two xfbs */
21013 		out_descriptors.resize(2);
21014 
21015 		/* Get references */
21016 		bufferDescriptor& uniform = out_descriptors[0];
21017 		bufferDescriptor& xfb_1   = out_descriptors[1];
21018 
21019 		/* Index */
21020 		uniform.m_index = 0;
21021 		xfb_1.m_index   = 1;
21022 
21023 		/* Target */
21024 		uniform.m_target = Utils::Buffer::Uniform;
21025 		xfb_1.m_target   = Utils::Buffer::Transform_feedback;
21026 
21027 		/* Data */
21028 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21029 
21030 		/* Data, contents are the same as no modification is expected */
21031 		xfb_1.m_initial_data  = Utils::Type::vec4.GenerateDataPacked();
21032 		xfb_1.m_expected_data = uniform.m_initial_data;
21033 	}
21034 
21035 	break;
21036 
21037 	case SECOND_MISSING:
21038 	{
21039 		/* Test needs single uniform and two xfbs */
21040 		out_descriptors.resize(2);
21041 
21042 		/* Get references */
21043 		bufferDescriptor& uniform = out_descriptors[0];
21044 		bufferDescriptor& xfb_0   = out_descriptors[1];
21045 
21046 		/* Index */
21047 		uniform.m_index = 0;
21048 		xfb_0.m_index   = 0;
21049 
21050 		/* Target */
21051 		uniform.m_target = Utils::Buffer::Uniform;
21052 		xfb_0.m_target   = Utils::Buffer::Transform_feedback;
21053 
21054 		/* Data */
21055 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21056 
21057 		/* Draw call will not be executed, contents does not matter */
21058 		xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21059 	}
21060 
21061 	break;
21062 	}
21063 }
21064 
21065 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
21066  *
21067  * @param ignored
21068  * @param captured_varyings Vector of varying names to be captured
21069  **/
21070 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
21071 														 Utils::Program::NameVector& captured_varyings,
21072 														 GLint* xfb_components)
21073 {
21074 	captured_varyings.push_back("gs_fs1");
21075 	captured_varyings.push_back("gs_fs2");
21076 	*xfb_components	= 4;
21077 }
21078 
21079 /** Get body of main function for given shader stage
21080  *
21081  * @param ignored
21082  * @param stage            Shader stage
21083  * @param out_assignments  Set to empty
21084  * @param out_calculations Set to empty
21085  **/
21086 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21087 												   std::string& out_assignments, std::string& out_calculations)
21088 {
21089 	out_calculations = "";
21090 
21091 	static const GLchar* gs = "    gs_fs1 = -uni_gs;\n"
21092 							  "    gs_fs2 = uni_gs;\n";
21093 	static const GLchar* fs = "    fs_out = vec4(gs_fs2);\n";
21094 
21095 	const GLchar* assignments = "";
21096 	switch (stage)
21097 	{
21098 	case Utils::Shader::FRAGMENT:
21099 		assignments = fs;
21100 		break;
21101 	case Utils::Shader::GEOMETRY:
21102 		assignments = gs;
21103 		break;
21104 	default:
21105 		break;
21106 	}
21107 
21108 	out_assignments = assignments;
21109 }
21110 
21111 /** Get interface of shader
21112  *
21113  * @param ignored
21114  * @param stage            Shader stage
21115  * @param out_interface    Set to ""
21116  **/
21117 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21118 														std::string& out_interface)
21119 {
21120 	static const GLchar* gs = "layout (xfb_buffer = 0, xfb_stride = 64) out vec4 gs_fs1;\n"
21121 							  "layout (xfb_buffer = 1, xfb_offset = 0)  out vec4 gs_fs2;\n"
21122 							  "\n"
21123 							  "layout(binding    = 0) uniform gs_block {\n"
21124 							  "    vec4 uni_gs;\n"
21125 							  "};\n";
21126 	static const GLchar* fs = "in  vec4 gs_fs2;\n"
21127 							  "out vec4 fs_out;\n";
21128 
21129 	switch (stage)
21130 	{
21131 	case Utils::Shader::FRAGMENT:
21132 		out_interface = fs;
21133 		break;
21134 	case Utils::Shader::GEOMETRY:
21135 		out_interface = gs;
21136 		break;
21137 	default:
21138 		out_interface = "";
21139 		return;
21140 	}
21141 }
21142 
21143 /** Returns buffer details in human readable form.
21144  *
21145  * @param test_case_index Index of test case
21146  *
21147  * @return Case description
21148  **/
21149 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index)
21150 {
21151 	std::string result;
21152 
21153 	switch (test_case_index)
21154 	{
21155 	case VALID:
21156 		result = "Valid case";
21157 		break;
21158 	case FIRST_MISSING:
21159 		result = "Missing xfb at index 0";
21160 		break;
21161 	case SECOND_MISSING:
21162 		result = "Missing xfb at index 1";
21163 		break;
21164 	default:
21165 		TCU_FAIL("Invalid enum");
21166 	}
21167 
21168 	return result;
21169 }
21170 
21171 /** Get number of test cases
21172  *
21173  * @return 2
21174  **/
21175 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber()
21176 {
21177 	return 3;
21178 }
21179 
21180 /** Constructor
21181  *
21182  * @param context Test framework context
21183  **/
21184 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context& context)
21185 	: NegativeTestBase(context, "xfb_too_small_stride",
21186 					   "Test verifies that compiler reports error when xfb_stride sets not enough space")
21187 {
21188 }
21189 
21190 /** Source for given test case and stage
21191  *
21192  * @param test_case_index Index of test case
21193  * @param stage           Shader stage
21194  *
21195  * @return Shader source
21196  **/
21197 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21198 {
21199 #if DEBUG_NEG_REMOVE_ERROR
21200 	static const GLchar* array_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 32 */ ) out;\n"
21201 #else
21202 	static const GLchar* array_var_definition  = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
21203 #endif /* DEBUG_NEG_REMOVE_ERROR */
21204 												"\n"
21205 												"layout (xfb_offset = 16) out vec4 gohan[4];\n";
21206 #if DEBUG_NEG_REMOVE_ERROR
21207 	static const GLchar* block_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 32 */ ) out;\n"
21208 #else
21209 	static const GLchar* block_var_definition  = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
21210 #endif /* DEBUG_NEG_REMOVE_ERROR */
21211 												"\n"
21212 												"layout (xfb_offset = 0) out Goku {\n"
21213 												"    vec4 gohan;\n"
21214 												"    vec4 goten;\n"
21215 												"    vec4 chichi;\n"
21216 												"} goku;\n";
21217 #if DEBUG_NEG_REMOVE_ERROR
21218 	static const GLchar* offset_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 40 */ ) out;\n"
21219 #else
21220 	static const GLchar* offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n"
21221 #endif /* DEBUG_NEG_REMOVE_ERROR */
21222 												 "\n"
21223 												 "layout (xfb_offset = 32) out vec4 gohan;\n";
21224 // 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;"
21225 // To make the shader failed to compile, change xfb_stride to a value that is smaller than 32
21226 #if DEBUG_NEG_REMOVE_ERROR
21227 	static const GLchar* stride_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 28 */ ) out;\n"
21228 												 "\n"
21229 												 "layout (xfb_offset = 16 /*, xfb_stride = 28 */ ) out vec4 gohan;\n";
21230 #else
21231 	static const GLchar* stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n"
21232 												 "\n"
21233 												 "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohan;\n";
21234 #endif /* DEBUG_NEG_REMOVE_ERROR */
21235 	static const GLchar* array_use = "    gohan[0] = result / 2;\n"
21236 									 "    gohan[1] = result / 4;\n"
21237 									 "    gohan[2] = result / 6;\n"
21238 									 "    gohan[3] = result / 8;\n";
21239 	static const GLchar* block_use = "    goku.gohan  = result / 2;\n"
21240 									 "    goku.goten  = result / 4;\n"
21241 									 "    goku.chichi = result / 6;\n";
21242 	static const GLchar* output_use = "gohan = result / 4;\n";
21243 	static const GLchar* fs			= "#version 430 core\n"
21244 							  "#extension GL_ARB_enhanced_layouts : require\n"
21245 							  "\n"
21246 							  "in  vec4 any_fs;\n"
21247 							  "out vec4 fs_out;\n"
21248 							  "\n"
21249 							  "void main()\n"
21250 							  "{\n"
21251 							  "    fs_out = any_fs;\n"
21252 							  "}\n"
21253 							  "\n";
21254 	static const GLchar* gs_tested = "#version 430 core\n"
21255 									 "#extension GL_ARB_enhanced_layouts : require\n"
21256 									 "\n"
21257 									 "layout(points)                           in;\n"
21258 									 "layout(triangle_strip, max_vertices = 4) out;\n"
21259 									 "\n"
21260 									 "VAR_DEFINITION"
21261 									 "\n"
21262 									 "in  vec4 vs_any[];\n"
21263 									 "out vec4 any_fs;\n"
21264 									 "\n"
21265 									 "void main()\n"
21266 									 "{\n"
21267 									 "    vec4 result = vs_any[0];\n"
21268 									 "\n"
21269 									 "VARIABLE_USE"
21270 									 "\n"
21271 									 "    any_fs = result;\n"
21272 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
21273 									 "    EmitVertex();\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 									 "}\n"
21284 									 "\n";
21285 	static const GLchar* tcs = "#version 430 core\n"
21286 							   "#extension GL_ARB_enhanced_layouts : require\n"
21287 							   "\n"
21288 							   "layout(vertices = 1) out;\n"
21289 							   "\n"
21290 							   "in  vec4 vs_any[];\n"
21291 							   "out vec4 tcs_tes[];\n"
21292 							   "\n"
21293 							   "void main()\n"
21294 							   "{\n"
21295 							   "\n"
21296 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21297 							   "\n"
21298 							   "    gl_TessLevelOuter[0] = 1.0;\n"
21299 							   "    gl_TessLevelOuter[1] = 1.0;\n"
21300 							   "    gl_TessLevelOuter[2] = 1.0;\n"
21301 							   "    gl_TessLevelOuter[3] = 1.0;\n"
21302 							   "    gl_TessLevelInner[0] = 1.0;\n"
21303 							   "    gl_TessLevelInner[1] = 1.0;\n"
21304 							   "}\n"
21305 							   "\n";
21306 	static const GLchar* tes_tested = "#version 430 core\n"
21307 									  "#extension GL_ARB_enhanced_layouts : require\n"
21308 									  "\n"
21309 									  "layout(isolines, point_mode) in;\n"
21310 									  "\n"
21311 									  "VAR_DEFINITION"
21312 									  "\n"
21313 									  "in  vec4 tcs_tes[];\n"
21314 									  "out vec4 any_fs;\n"
21315 									  "\n"
21316 									  "void main()\n"
21317 									  "{\n"
21318 									  "    vec4 result = tcs_tes[0];\n"
21319 									  "\n"
21320 									  "VARIABLE_USE"
21321 									  "\n"
21322 									  "    any_fs += result;\n"
21323 									  "}\n"
21324 									  "\n";
21325 	static const GLchar* vs = "#version 430 core\n"
21326 							  "#extension GL_ARB_enhanced_layouts : require\n"
21327 							  "\n"
21328 							  "in  vec4 in_vs;\n"
21329 							  "out vec4 vs_any;\n"
21330 							  "\n"
21331 							  "void main()\n"
21332 							  "{\n"
21333 							  "    vs_any = in_vs;\n"
21334 							  "}\n"
21335 							  "\n";
21336 	static const GLchar* vs_tested = "#version 430 core\n"
21337 									 "#extension GL_ARB_enhanced_layouts : require\n"
21338 									 "\n"
21339 									 "VAR_DEFINITION"
21340 									 "\n"
21341 									 "in  vec4 in_vs;\n"
21342 									 "out vec4 any_fs;\n"
21343 									 "\n"
21344 									 "void main()\n"
21345 									 "{\n"
21346 									 "    vec4 result = in_vs;\n"
21347 									 "\n"
21348 									 "VARIABLE_USE"
21349 									 "\n"
21350 									 "    any_fs += result;\n"
21351 									 "}\n"
21352 									 "\n";
21353 
21354 	std::string source;
21355 	testCase&   test_case = m_test_cases[test_case_index];
21356 
21357 	if (test_case.m_stage == stage)
21358 	{
21359 		size_t		  position = 0;
21360 		const GLchar* var_definition = 0;
21361 		const GLchar* var_use		 = 0;
21362 
21363 		switch (test_case.m_case)
21364 		{
21365 		case OFFSET:
21366 			var_definition = offset_var_definition;
21367 			var_use		   = output_use;
21368 			break;
21369 		case STRIDE:
21370 			var_definition = stride_var_definition;
21371 			var_use		   = output_use;
21372 			break;
21373 		case BLOCK:
21374 			var_definition = block_var_definition;
21375 			var_use		   = block_use;
21376 			break;
21377 		case ARRAY:
21378 			var_definition = array_var_definition;
21379 			var_use		   = array_use;
21380 			break;
21381 		default:
21382 			TCU_FAIL("Invalid enum");
21383 		}
21384 
21385 		switch (stage)
21386 		{
21387 		case Utils::Shader::GEOMETRY:
21388 			source = gs_tested;
21389 			break;
21390 		case Utils::Shader::TESS_EVAL:
21391 			source = tes_tested;
21392 			break;
21393 		case Utils::Shader::VERTEX:
21394 			source = vs_tested;
21395 			break;
21396 		default:
21397 			TCU_FAIL("Invalid enum");
21398 		}
21399 
21400 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21401 		position = 0;
21402 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21403 	}
21404 	else
21405 	{
21406 		switch (test_case.m_stage)
21407 		{
21408 		case Utils::Shader::GEOMETRY:
21409 			switch (stage)
21410 			{
21411 			case Utils::Shader::FRAGMENT:
21412 				source = fs;
21413 				break;
21414 			case Utils::Shader::VERTEX:
21415 				source = vs;
21416 				break;
21417 			default:
21418 				source = "";
21419 			}
21420 			break;
21421 		case Utils::Shader::TESS_EVAL:
21422 			switch (stage)
21423 			{
21424 			case Utils::Shader::FRAGMENT:
21425 				source = fs;
21426 				break;
21427 			case Utils::Shader::TESS_CTRL:
21428 				source = tcs;
21429 				break;
21430 			case Utils::Shader::VERTEX:
21431 				source = vs;
21432 				break;
21433 			default:
21434 				source = "";
21435 			}
21436 			break;
21437 		case Utils::Shader::VERTEX:
21438 			switch (stage)
21439 			{
21440 			case Utils::Shader::FRAGMENT:
21441 				source = fs;
21442 				break;
21443 			default:
21444 				source = "";
21445 			}
21446 			break;
21447 		default:
21448 			TCU_FAIL("Invalid enum");
21449 		}
21450 	}
21451 
21452 	return source;
21453 }
21454 
21455 /** Get description of test case
21456  *
21457  * @param test_case_index Index of test case
21458  *
21459  * @return Test case description
21460  **/
21461 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index)
21462 {
21463 	std::stringstream stream;
21464 	testCase&		  test_case = m_test_cases[test_case_index];
21465 
21466 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
21467 
21468 	switch (test_case.m_case)
21469 	{
21470 	case OFFSET:
21471 		stream << "buffer stride: 40, vec4 offset: 32";
21472 		break;
21473 	case STRIDE:
21474 		stream << "buffer stride: 32, vec4 off 16 stride: 32";
21475 		break;
21476 	case BLOCK:
21477 		stream << "buffer stride: 32, block 3xvec4 offset 0";
21478 		break;
21479 	case ARRAY:
21480 		stream << "buffer stride: 32, vec4[4] offset 16";
21481 		break;
21482 	default:
21483 		TCU_FAIL("Invalid enum");
21484 	}
21485 
21486 	return stream.str();
21487 }
21488 
21489 /** Get number of test cases
21490  *
21491  * @return Number of test cases
21492  **/
21493 GLuint XFBTooSmallStrideTest::getTestCaseNumber()
21494 {
21495 	return static_cast<GLuint>(m_test_cases.size());
21496 }
21497 
21498 /** Selects if "compute" stage is relevant for test
21499  *
21500  * @param ignored
21501  *
21502  * @return false
21503  **/
21504 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21505 {
21506 	return false;
21507 }
21508 
21509 /** Prepare all test cases
21510  *
21511  **/
21512 void XFBTooSmallStrideTest::testInit()
21513 {
21514 	for (GLuint c = 0; c < CASE_MAX; ++c)
21515 	{
21516 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21517 		{
21518 			/*
21519 			 It is invalid to define transform feedback output in TCS, according to spec:
21520 			 The data captured in transform feedback mode depends on the active programs on each of the shader stages.
21521 			 If a program is active for the geometry shader stage, transform feedback captures the vertices of each
21522 			 primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation
21523 			 shader stage, transform feedback captures each primitive produced by the tessellation primitive generator,
21524 			 whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures
21525 			 each primitive processed by the vertex shader.
21526 			 */
21527 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21528 				(Utils::Shader::FRAGMENT == stage))
21529 			{
21530 				continue;
21531 			}
21532 
21533 			testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
21534 
21535 			m_test_cases.push_back(test_case);
21536 		}
21537 	}
21538 }
21539 
21540 /** Constructor
21541  *
21542  * @param context Test framework context
21543  **/
21544 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context& context)
21545 	: NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected")
21546 {
21547 }
21548 
21549 /** Source for given test case and stage
21550  *
21551  * @param test_case_index Index of test case
21552  * @param stage           Shader stage
21553  *
21554  * @return Shader source
21555  **/
21556 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21557 {
21558 	static const GLchar* invalid_var_definition = "const uint type_size = SIZE;\n"
21559 												  "\n"
21560 #if DEBUG_NEG_REMOVE_ERROR
21561 												  "layout (xfb_stride = 2 * type_size) out;\n"
21562 #else
21563 												  "layout (xfb_stride = type_size) out;\n"
21564 #endif /* DEBUG_NEG_REMOVE_ERROR */
21565 												  "\n"
21566 												  "layout (xfb_offset = 0)         out TYPE goku;\n"
21567 												  "layout (xfb_offset = type_size) out TYPE vegeta;\n";
21568 	static const GLchar* valid_var_definition = "const uint type_size = SIZE;\n"
21569 												"\n"
21570 												"layout (xfb_stride = type_size) out;\n"
21571 												"\n"
21572 												"layout (xfb_offset = 0) out TYPE goku;\n";
21573 	static const GLchar* invalid_use = "    goku   = TYPE(1);\n"
21574 									   "    vegeta = TYPE(0);\n"
21575 									   "    if (vec4(0) == result)\n"
21576 									   "    {\n"
21577 									   "        goku   = TYPE(0);\n"
21578 									   "        vegeta = TYPE(1);\n"
21579 									   "    }\n";
21580 	static const GLchar* valid_use = "    goku   = TYPE(1);\n"
21581 									 "    if (vec4(0) == result)\n"
21582 									 "    {\n"
21583 									 "        goku   = TYPE(0);\n"
21584 									 "    }\n";
21585 	static const GLchar* fs = "#version 430 core\n"
21586 							  "#extension GL_ARB_enhanced_layouts : require\n"
21587 							  "\n"
21588 							  "in  vec4 any_fs;\n"
21589 							  "out vec4 fs_out;\n"
21590 							  "\n"
21591 							  "void main()\n"
21592 							  "{\n"
21593 							  "    fs_out = any_fs;\n"
21594 							  "}\n"
21595 							  "\n";
21596 	static const GLchar* gs_tested = "#version 430 core\n"
21597 									 "#extension GL_ARB_enhanced_layouts : require\n"
21598 									 "\n"
21599 									 "layout(points)                           in;\n"
21600 									 "layout(triangle_strip, max_vertices = 4) out;\n"
21601 									 "\n"
21602 									 "VAR_DEFINITION"
21603 									 "\n"
21604 									 "in  vec4 vs_any[];\n"
21605 									 "out vec4 any_fs;\n"
21606 									 "\n"
21607 									 "void main()\n"
21608 									 "{\n"
21609 									 "    vec4 result = vs_any[0];\n"
21610 									 "\n"
21611 									 "VARIABLE_USE"
21612 									 "\n"
21613 									 "    any_fs = result;\n"
21614 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
21615 									 "    EmitVertex();\n"
21616 									 "    any_fs = result;\n"
21617 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
21618 									 "    EmitVertex();\n"
21619 									 "    any_fs = result;\n"
21620 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
21621 									 "    EmitVertex();\n"
21622 									 "    any_fs = result;\n"
21623 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
21624 									 "    EmitVertex();\n"
21625 									 "}\n"
21626 									 "\n";
21627 	static const GLchar* tcs = "#version 430 core\n"
21628 							   "#extension GL_ARB_enhanced_layouts : require\n"
21629 							   "\n"
21630 							   "layout(vertices = 1) out;\n"
21631 							   "\n"
21632 							   "in  vec4 vs_any[];\n"
21633 							   "out vec4 tcs_tes[];\n"
21634 							   "\n"
21635 							   "void main()\n"
21636 							   "{\n"
21637 							   "\n"
21638 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21639 							   "\n"
21640 							   "    gl_TessLevelOuter[0] = 1.0;\n"
21641 							   "    gl_TessLevelOuter[1] = 1.0;\n"
21642 							   "    gl_TessLevelOuter[2] = 1.0;\n"
21643 							   "    gl_TessLevelOuter[3] = 1.0;\n"
21644 							   "    gl_TessLevelInner[0] = 1.0;\n"
21645 							   "    gl_TessLevelInner[1] = 1.0;\n"
21646 							   "}\n"
21647 							   "\n";
21648 	static const GLchar* tes_tested = "#version 430 core\n"
21649 									  "#extension GL_ARB_enhanced_layouts : require\n"
21650 									  "\n"
21651 									  "layout(isolines, point_mode) in;\n"
21652 									  "\n"
21653 									  "VAR_DEFINITION"
21654 									  "\n"
21655 									  "in  vec4 tcs_tes[];\n"
21656 									  "out vec4 any_fs;\n"
21657 									  "\n"
21658 									  "void main()\n"
21659 									  "{\n"
21660 									  "    vec4 result = tcs_tes[0];\n"
21661 									  "\n"
21662 									  "VARIABLE_USE"
21663 									  "\n"
21664 									  "    any_fs = result;\n"
21665 									  "}\n"
21666 									  "\n";
21667 	static const GLchar* vs = "#version 430 core\n"
21668 							  "#extension GL_ARB_enhanced_layouts : require\n"
21669 							  "\n"
21670 							  "in  vec4 in_vs;\n"
21671 							  "out vec4 vs_any;\n"
21672 							  "\n"
21673 							  "void main()\n"
21674 							  "{\n"
21675 							  "    vs_any = in_vs;\n"
21676 							  "}\n"
21677 							  "\n";
21678 	static const GLchar* vs_tested = "#version 430 core\n"
21679 									 "#extension GL_ARB_enhanced_layouts : require\n"
21680 									 "\n"
21681 									 "VAR_DEFINITION"
21682 									 "\n"
21683 									 "in  vec4 in_vs;\n"
21684 									 "out vec4 any_fs;\n"
21685 									 "\n"
21686 									 "void main()\n"
21687 									 "{\n"
21688 									 "    vec4 result = in_vs;\n"
21689 									 "\n"
21690 									 "VARIABLE_USE"
21691 									 "\n"
21692 									 "    any_fs = result;\n"
21693 									 "}\n"
21694 									 "\n";
21695 
21696 	std::string source;
21697 	testCase&   test_case = m_test_cases[test_case_index];
21698 
21699 	if (test_case.m_stage == stage)
21700 	{
21701 		GLchar		  buffer[16];
21702 		size_t		  position = 0;
21703 		const GLchar* type_name		 = test_case.m_type.GetGLSLTypeName();
21704 		const GLchar* var_definition = 0;
21705 		const GLchar* var_use		 = 0;
21706 
21707 		sprintf(buffer, "%d", test_case.m_type.GetSize());
21708 
21709 		switch (test_case.m_case)
21710 		{
21711 		case VALID:
21712 			var_definition = valid_var_definition;
21713 			var_use		   = valid_use;
21714 			break;
21715 		case INVALID:
21716 			var_definition = invalid_var_definition;
21717 			var_use		   = invalid_use;
21718 			break;
21719 		default:
21720 			TCU_FAIL("Invalid enum");
21721 		}
21722 
21723 		switch (stage)
21724 		{
21725 		case Utils::Shader::GEOMETRY:
21726 			source = gs_tested;
21727 			break;
21728 		case Utils::Shader::TESS_EVAL:
21729 			source = tes_tested;
21730 			break;
21731 		case Utils::Shader::VERTEX:
21732 			source = vs_tested;
21733 			break;
21734 		default:
21735 			TCU_FAIL("Invalid enum");
21736 		}
21737 
21738 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21739 		position = 0;
21740 		Utils::replaceToken("SIZE", position, buffer, source);
21741 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21742 
21743 		Utils::replaceAllTokens("TYPE", type_name, source);
21744 	}
21745 	else
21746 	{
21747 		switch (test_case.m_stage)
21748 		{
21749 		case Utils::Shader::GEOMETRY:
21750 			switch (stage)
21751 			{
21752 			case Utils::Shader::FRAGMENT:
21753 				source = fs;
21754 				break;
21755 			case Utils::Shader::VERTEX:
21756 				source = vs;
21757 				break;
21758 			default:
21759 				source = "";
21760 			}
21761 			break;
21762 		case Utils::Shader::TESS_EVAL:
21763 			switch (stage)
21764 			{
21765 			case Utils::Shader::FRAGMENT:
21766 				source = fs;
21767 				break;
21768 			case Utils::Shader::TESS_CTRL:
21769 				source = tcs;
21770 				break;
21771 			case Utils::Shader::VERTEX:
21772 				source = vs;
21773 				break;
21774 			default:
21775 				source = "";
21776 			}
21777 			break;
21778 		case Utils::Shader::VERTEX:
21779 			switch (stage)
21780 			{
21781 			case Utils::Shader::FRAGMENT:
21782 				source = fs;
21783 				break;
21784 			default:
21785 				source = "";
21786 			}
21787 			break;
21788 		default:
21789 			TCU_FAIL("Invalid enum");
21790 		}
21791 	}
21792 
21793 	return source;
21794 }
21795 
21796 /** Get description of test case
21797  *
21798  * @param test_case_index Index of test case
21799  *
21800  * @return Test case description
21801  **/
21802 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index)
21803 {
21804 	std::stringstream stream;
21805 	testCase&		  test_case = m_test_cases[test_case_index];
21806 
21807 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
21808 		   << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
21809 
21810 	switch (test_case.m_case)
21811 	{
21812 	case VALID:
21813 		stream << "valid";
21814 		break;
21815 	case INVALID:
21816 		stream << "invalid";
21817 		break;
21818 	default:
21819 		TCU_FAIL("Invalid enum");
21820 	}
21821 
21822 	return stream.str();
21823 }
21824 
21825 /** Get number of test cases
21826  *
21827  * @return Number of test cases
21828  **/
21829 GLuint XFBVariableStrideTest::getTestCaseNumber()
21830 {
21831 	return static_cast<GLuint>(m_test_cases.size());
21832 }
21833 
21834 /** Selects if "compute" stage is relevant for test
21835  *
21836  * @param ignored
21837  *
21838  * @return false
21839  **/
21840 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21841 {
21842 	return false;
21843 }
21844 
21845 /** Selects if compilation failure is expected result
21846  *
21847  * @param test_case_index Index of test case
21848  *
21849  * @return true
21850  **/
21851 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index)
21852 {
21853 	testCase& test_case = m_test_cases[test_case_index];
21854 
21855 	return (INVALID == test_case.m_case);
21856 }
21857 
21858 /** Prepare all test cases
21859  *
21860  **/
21861 void XFBVariableStrideTest::testInit()
21862 {
21863 	const GLuint n_types = getTypesNumber();
21864 
21865 	for (GLuint i = 0; i < n_types; ++i)
21866 	{
21867 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21868 		{
21869 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21870 				(Utils::Shader::FRAGMENT == stage))
21871 			{
21872 				continue;
21873 			}
21874 
21875 			const Utils::Type& type = getType(i);
21876 			for (GLuint c = 0; c < CASE_MAX; ++c)
21877 			{
21878 				testCase test_case = { static_cast<CASES>(c), static_cast<Utils::Shader::STAGES>(stage), type };
21879 
21880 				m_test_cases.push_back(test_case);
21881 			}
21882 		}
21883 	}
21884 }
21885 
21886 /** Constructor
21887  *
21888  * @param context Test framework context
21889  **/
21890 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context& context)
21891 	: TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks")
21892 {
21893 }
21894 
21895 /** Source for given test case and stage
21896  *
21897  * @param test_case_index Index of test case
21898  * @param stage           Shader stage
21899  *
21900  * @return Shader source
21901  **/
21902 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21903 {
21904 	static const GLchar* var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n"
21905 										  "    vec4 gohan;\n"
21906 										  "    vec4 goten;\n"
21907 										  "    vec4 chichi;\n"
21908 										  "} gokuARRAY;\n";
21909 	static const GLchar* var_use = "    gokuINDEX.gohan  = vec4(1, 0, 0, 0);\n"
21910 								   "    gokuINDEX.goten  = vec4(0, 0, 1, 0);\n"
21911 								   "    gokuINDEX.chichi = vec4(0, 1, 0, 0);\n"
21912 								   "    if (vec4(0) == result)\n"
21913 								   "    {\n"
21914 								   "        gokuINDEX.gohan  = vec4(0, 1, 1, 1);\n"
21915 								   "        gokuINDEX.goten  = vec4(1, 1, 0, 1);\n"
21916 								   "        gokuINDEX.chichi = vec4(1, 0, 1, 1);\n"
21917 								   "    }\n";
21918 	static const GLchar* gs_tested =
21919 		"#version 430 core\n"
21920 		"#extension GL_ARB_enhanced_layouts : require\n"
21921 		"\n"
21922 		"layout(points)                           in;\n"
21923 		"layout(triangle_strip, max_vertices = 4) out;\n"
21924 		"\n"
21925 		"VAR_DEFINITION"
21926 		"\n"
21927 		"out gl_PerVertex \n"
21928 		"{ \n"
21929 		"   vec4  gl_Position; \n" // gl_Position must be redeclared in separable program mode
21930 		"}; \n"
21931 		"in  vec4 tes_gs[];\n"
21932 		"out vec4 gs_fs;\n"
21933 		"\n"
21934 		"void main()\n"
21935 		"{\n"
21936 		"    vec4 result = tes_gs[0];\n"
21937 		"\n"
21938 		"VARIABLE_USE"
21939 		"\n"
21940 		"    gs_fs = result;\n"
21941 		"    gl_Position  = vec4(-1, -1, 0, 1);\n"
21942 		"    EmitVertex();\n"
21943 		"    gs_fs = result;\n"
21944 		"    gl_Position  = vec4(-1, 1, 0, 1);\n"
21945 		"    EmitVertex();\n"
21946 		"    gs_fs = result;\n"
21947 		"    gl_Position  = vec4(1, -1, 0, 1);\n"
21948 		"    EmitVertex();\n"
21949 		"    gs_fs = result;\n"
21950 		"    gl_Position  = vec4(1, 1, 0, 1);\n"
21951 		"    EmitVertex();\n"
21952 		"}\n"
21953 		"\n";
21954 	static const GLchar* tcs = "#version 430 core\n"
21955 							   "#extension GL_ARB_enhanced_layouts : require\n"
21956 							   "\n"
21957 							   "layout(vertices = 1) out;\n"
21958 							   "\n"
21959 							   "in  vec4 vs_tcs[];\n"
21960 							   "out vec4 tcs_tes[];\n"
21961 							   "\n"
21962 							   "void main()\n"
21963 							   "{\n"
21964 							   "\n"
21965 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
21966 							   "\n"
21967 							   "    gl_TessLevelOuter[0] = 1.0;\n"
21968 							   "    gl_TessLevelOuter[1] = 1.0;\n"
21969 							   "    gl_TessLevelOuter[2] = 1.0;\n"
21970 							   "    gl_TessLevelOuter[3] = 1.0;\n"
21971 							   "    gl_TessLevelInner[0] = 1.0;\n"
21972 							   "    gl_TessLevelInner[1] = 1.0;\n"
21973 							   "}\n"
21974 							   "\n";
21975 #if 0
21976 	static const GLchar* tcs_tested =
21977 		"#version 430 core\n"
21978 		"#extension GL_ARB_enhanced_layouts : require\n"
21979 		"\n"
21980 		"layout(vertices = 1) out;\n"
21981 		"\n"
21982 		"VAR_DEFINITION"
21983 		"\n"
21984 		"in  vec4 vs_tcs[];\n"
21985 		"out vec4 tcs_tes[];\n"
21986 		"\n"
21987 		"void main()\n"
21988 		"{\n"
21989 		"    vec4 result = vs_tcs[gl_InvocationID];\n"
21990 		"\n"
21991 		"VARIABLE_USE"
21992 		"\n"
21993 		"    tcs_tes[gl_InvocationID] = result;\n"
21994 		"\n"
21995 		"    gl_TessLevelOuter[0] = 1.0;\n"
21996 		"    gl_TessLevelOuter[1] = 1.0;\n"
21997 		"    gl_TessLevelOuter[2] = 1.0;\n"
21998 		"    gl_TessLevelOuter[3] = 1.0;\n"
21999 		"    gl_TessLevelInner[0] = 1.0;\n"
22000 		"    gl_TessLevelInner[1] = 1.0;\n"
22001 		"}\n"
22002 		"\n";
22003 #endif
22004 	static const GLchar* tes_tested = "#version 430 core\n"
22005 									  "#extension GL_ARB_enhanced_layouts : require\n"
22006 									  "\n"
22007 									  "layout(isolines, point_mode) in;\n"
22008 									  "\n"
22009 									  "VAR_DEFINITION"
22010 									  "\n"
22011 									  "in  vec4 tcs_tes[];\n"
22012 									  "out vec4 tes_gs;\n"
22013 									  "\n"
22014 									  "void main()\n"
22015 									  "{\n"
22016 									  "    vec4 result = tcs_tes[0];\n"
22017 									  "\n"
22018 									  "VARIABLE_USE"
22019 									  "\n"
22020 									  "    tes_gs += result;\n"
22021 									  "}\n"
22022 									  "\n";
22023 	static const GLchar* vs = "#version 430 core\n"
22024 							  "#extension GL_ARB_enhanced_layouts : require\n"
22025 							  "\n"
22026 							  "in  vec4 in_vs;\n"
22027 							  "out vec4 vs_tcs;\n"
22028 							  "out vec4 tes_gs;\n"
22029 							  "\n"
22030 							  "void main()\n"
22031 							  "{\n"
22032 							  "    vs_tcs = tes_gs = in_vs;\n"
22033 							  "}\n"
22034 							  "\n";
22035 	static const GLchar* vs_tested = "#version 430 core\n"
22036 									 "#extension GL_ARB_enhanced_layouts : require\n"
22037 									 "\n"
22038 									 "VAR_DEFINITION"
22039 									 "\n"
22040 									 "in  vec4 in_vs;\n"
22041 									 "out vec4 vs_tcs;\n"
22042 									 "\n"
22043 									 "void main()\n"
22044 									 "{\n"
22045 									 "    vec4 result = in_vs;\n"
22046 									 "\n"
22047 									 "VARIABLE_USE"
22048 									 "\n"
22049 									 "    vs_tcs += result;\n"
22050 									 "}\n"
22051 									 "\n";
22052 
22053 	std::string			  source;
22054 	Utils::Shader::STAGES test_case = m_test_cases[test_case_index];
22055 
22056 	if (test_case == stage)
22057 	{
22058 		const GLchar* array	= "";
22059 		const GLchar* index	= "";
22060 		size_t		  position = 0;
22061 		size_t		  temp;
22062 		// It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22063 		// change array = "[]" to "[1]"
22064 		switch (stage)
22065 		{
22066 		case Utils::Shader::GEOMETRY:
22067 			source = gs_tested;
22068 			array  = "[1]";
22069 			index  = "[0]";
22070 			break;
22071 /*
22072 			 It is invalid to define transform feedback output in HS
22073 			 */
22074 #if 0
22075 			case Utils::Shader::TESS_CTRL:
22076 			source = tcs_tested;
22077 			array = "[]";
22078 			index = "[gl_InvocationID]";
22079 			break;
22080 #endif
22081 		case Utils::Shader::TESS_EVAL:
22082 			source = tes_tested;
22083 			array  = "[1]";
22084 			index  = "[0]";
22085 			break;
22086 		case Utils::Shader::VERTEX:
22087 			source = vs_tested;
22088 			break;
22089 		default:
22090 			TCU_FAIL("Invalid enum");
22091 		}
22092 
22093 		temp = position;
22094 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22095 		position = temp;
22096 		Utils::replaceToken("ARRAY", position, array, source);
22097 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22098 
22099 		Utils::replaceAllTokens("INDEX", index, source);
22100 	}
22101 	else
22102 	{
22103 		switch (test_case)
22104 		{
22105 		case Utils::Shader::GEOMETRY:
22106 			switch (stage)
22107 			{
22108 			case Utils::Shader::VERTEX:
22109 				source = vs;
22110 				break;
22111 			default:
22112 				source = "";
22113 			}
22114 			break;
22115 		case Utils::Shader::TESS_CTRL:
22116 			switch (stage)
22117 			{
22118 			case Utils::Shader::VERTEX:
22119 				source = vs;
22120 				break;
22121 			default:
22122 				source = "";
22123 			}
22124 			break;
22125 		case Utils::Shader::TESS_EVAL:
22126 			switch (stage)
22127 			{
22128 			case Utils::Shader::TESS_CTRL:
22129 				source = tcs;
22130 				break;
22131 			case Utils::Shader::VERTEX:
22132 				source = vs;
22133 				break;
22134 			default:
22135 				source = "";
22136 			}
22137 			break;
22138 		case Utils::Shader::VERTEX:
22139 			source = "";
22140 			break;
22141 		default:
22142 			TCU_FAIL("Invalid enum");
22143 		}
22144 	}
22145 
22146 	return source;
22147 }
22148 
22149 /** Get description of test case
22150  *
22151  * @param test_case_index Index of test case
22152  *
22153  * @return Test case description
22154  **/
22155 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index)
22156 {
22157 	std::stringstream stream;
22158 
22159 	stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]);
22160 
22161 	return stream.str();
22162 }
22163 
22164 /** Get number of test cases
22165  *
22166  * @return Number of test cases
22167  **/
22168 GLuint XFBBlockStrideTest::getTestCaseNumber()
22169 {
22170 	return static_cast<GLuint>(m_test_cases.size());
22171 }
22172 
22173 /** Inspects program for xfb stride
22174  *
22175  * @param program Program to query
22176  *
22177  * @return true if query results match expected values, false otherwise
22178  **/
22179 bool XFBBlockStrideTest::inspectProgram(Utils::Program& program)
22180 {
22181 	GLint stride = 0;
22182 
22183 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
22184 						1 /* buf_size */, &stride);
22185 
22186 	return (128 == stride);
22187 }
22188 
22189 /** Runs test case
22190  *
22191  * @param test_case_index Id of test case
22192  *
22193  * @return true if test case pass, false otherwise
22194  **/
22195 bool XFBBlockStrideTest::testCase(GLuint test_case_index)
22196 {
22197 	const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
22198 	Utils::Program	 program(m_context);
22199 	const std::string& tcs_source		= getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
22200 	const std::string& tes_source		= getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
22201 	bool			   test_case_result = true;
22202 	const std::string& vs_source		= getShaderSource(test_case_index, Utils::Shader::VERTEX);
22203 
22204 	program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
22205 
22206 	test_case_result = inspectProgram(program);
22207 
22208 	return test_case_result;
22209 }
22210 
22211 /** Prepare all test cases
22212  *
22213  **/
22214 void XFBBlockStrideTest::testInit()
22215 {
22216 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22217 	{
22218 		if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22219 			(Utils::Shader::FRAGMENT == stage))
22220 		{
22221 			continue;
22222 		}
22223 
22224 		m_test_cases.push_back((Utils::Shader::STAGES)stage);
22225 	}
22226 }
22227 
22228 /** Constructor
22229  *
22230  * @param context Test context
22231  **/
22232 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context& context)
22233 	: BufferTestBase(context, "xfb_block_member_stride",
22234 					 "Test verifies that xfb_stride qualifier is respected for block member")
22235 {
22236 	/* Nothing to be done here */
22237 }
22238 
22239 /** Get descriptors of buffers necessary for test
22240  *
22241  * @param ignored
22242  * @param out_descriptors Descriptors of buffers used by test
22243  **/
22244 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
22245 													bufferDescriptor::Vector& out_descriptors)
22246 {
22247 	const Utils::Type& vec4 = Utils::Type::vec4;
22248 
22249 	/* Test needs single uniform and xfb */
22250 	out_descriptors.resize(2);
22251 
22252 	/* Get references */
22253 	bufferDescriptor& uniform = out_descriptors[0];
22254 	bufferDescriptor& xfb	 = out_descriptors[1];
22255 
22256 	/* Index */
22257 	uniform.m_index = 0;
22258 	xfb.m_index		= 0;
22259 
22260 	/* Target */
22261 	uniform.m_target = Utils::Buffer::Uniform;
22262 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
22263 
22264 	/* Data */
22265 	static const GLuint			vec4_size   = 16;
22266 	const std::vector<GLubyte>& gohan_data  = vec4.GenerateDataPacked();
22267 	const std::vector<GLubyte>& goten_data  = vec4.GenerateDataPacked();
22268 	const std::vector<GLubyte>& chichi_data = vec4.GenerateDataPacked();
22269 
22270 	/* Uniform data */
22271 	uniform.m_initial_data.resize(3 * vec4_size);
22272 	memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size);
22273 	memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size);
22274 	memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
22275 
22276 	/* XFB data */
22277 	xfb.m_initial_data.resize(4 * vec4_size);
22278 	xfb.m_expected_data.resize(4 * vec4_size);
22279 
22280 	for (GLuint i = 0; i < 4 * vec4_size; ++i)
22281 	{
22282 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
22283 		xfb.m_expected_data[i] = (glw::GLubyte)i;
22284 	}
22285 
22286 	// the xfb_offset of "chichi" should be 32
22287 	memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size);
22288 	memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size);
22289 	memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
22290 }
22291 
22292 /** Get body of main function for given shader stage
22293  *
22294  * @param ignored
22295  * @param stage            Shader stage
22296  * @param out_assignments  Set to empty
22297  * @param out_calculations Set to empty
22298  **/
22299 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
22300 											 std::string& out_assignments, std::string& out_calculations)
22301 {
22302 	out_calculations = "";
22303 
22304 	static const GLchar* gs = "    gohan  = uni_gohan;\n"
22305 							  "    goten  = uni_goten;\n"
22306 							  "    chichi = uni_chichi;\n";
22307 	static const GLchar* fs = "    fs_out = gohan + goten + chichi;\n";
22308 
22309 	const GLchar* assignments = "";
22310 	switch (stage)
22311 	{
22312 	case Utils::Shader::FRAGMENT:
22313 		assignments = fs;
22314 		break;
22315 	case Utils::Shader::GEOMETRY:
22316 		assignments = gs;
22317 		break;
22318 	default:
22319 		break;
22320 	}
22321 
22322 	out_assignments = assignments;
22323 }
22324 
22325 /** Get interface of shader
22326  *
22327  * @param ignored
22328  * @param stage            Shader stage
22329  * @param out_interface    Set to ""
22330  **/
22331 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
22332 												  std::string& out_interface)
22333 {
22334 	static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
22335 							  "                             vec4 gohan;\n"
22336 							  "    layout (xfb_stride = 48) vec4 goten;\n"
22337 							  "                             vec4 chichi;\n"
22338 							  "};\n"
22339 							  "layout(binding = 0) uniform gs_block {\n"
22340 							  "    vec4 uni_gohan;\n"
22341 							  "    vec4 uni_goten;\n"
22342 							  "    vec4 uni_chichi;\n"
22343 							  "};\n";
22344 	static const GLchar* fs = "in Goku {\n"
22345 							  "    vec4 gohan;\n"
22346 							  "    vec4 goten;\n"
22347 							  "    vec4 chichi;\n"
22348 							  "};\n"
22349 							  "out vec4 fs_out;\n";
22350 
22351 	switch (stage)
22352 	{
22353 	case Utils::Shader::FRAGMENT:
22354 		out_interface = fs;
22355 		break;
22356 	case Utils::Shader::GEOMETRY:
22357 		out_interface = gs;
22358 		break;
22359 	default:
22360 		out_interface = "";
22361 		return;
22362 	}
22363 }
22364 
22365 /** Inspects program to check if all resources are as expected
22366  *
22367  * @param ignored
22368  * @param program    Program instance
22369  * @param out_stream Error message
22370  *
22371  * @return true if everything is ok, false otherwise
22372  **/
22373 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program& program,
22374 											  std::stringstream& out_stream)
22375 {
22376 	const GLuint gohan_id  = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING);
22377 	const GLuint goten_id  = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING);
22378 	const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING);
22379 
22380 	GLint gohan_offset  = 0;
22381 	GLint goten_offset  = 0;
22382 	GLint chichi_offset = 0;
22383 
22384 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset);
22385 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset);
22386 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset);
22387 
22388 	// the xfb_offset of "chichi" should be 32
22389 	if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset))
22390 	{
22391 		out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset
22392 				   << "] expected: [0, 16, 32]";
22393 		return false;
22394 	}
22395 
22396 	return true;
22397 }
22398 
22399 /** Constructor
22400  *
22401  * @param context Test framework context
22402  **/
22403 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context& context)
22404 	: NegativeTestBase(context, "xfb_duplicated_stride",
22405 					   "Test verifies that compiler reports error when conflicting stride qualifiers are used")
22406 {
22407 }
22408 
22409 /** Source for given test case and stage
22410  *
22411  * @param test_case_index Index of test case
22412  * @param stage           Shader stage
22413  *
22414  * @return Shader source
22415  **/
22416 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22417 {
22418 	static const GLchar* invalid_var_definition = "const uint valid_stride = 64;\n"
22419 #if DEBUG_NEG_REMOVE_ERROR
22420 												  "const uint conflicting_stride = 64;\n"
22421 #else
22422 												  "const uint conflicting_stride = 128;\n"
22423 #endif /* DEBUG_NEG_REMOVE_ERROR */
22424 												  "\n"
22425 												  "layout (xfb_buffer = 0, xfb_stride = valid_stride)       out;\n"
22426 												  "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n";
22427 	static const GLchar* valid_var_definition = "const uint valid_stride = 64;\n"
22428 												"\n"
22429 												"layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
22430 												"layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n";
22431 	static const GLchar* fs = "#version 430 core\n"
22432 							  "#extension GL_ARB_enhanced_layouts : require\n"
22433 							  "\n"
22434 							  "in  vec4 any_fs;\n"
22435 							  "out vec4 fs_out;\n"
22436 							  "\n"
22437 							  "void main()\n"
22438 							  "{\n"
22439 							  "    fs_out = any_fs;\n"
22440 							  "}\n"
22441 							  "\n";
22442 	static const GLchar* gs_tested = "#version 430 core\n"
22443 									 "#extension GL_ARB_enhanced_layouts : require\n"
22444 									 "\n"
22445 									 "layout(points)                           in;\n"
22446 									 "layout(triangle_strip, max_vertices = 4) out;\n"
22447 									 "\n"
22448 									 "VAR_DEFINITION"
22449 									 "\n"
22450 									 "in  vec4 vs_any[];\n"
22451 									 "out vec4 any_fs;\n"
22452 									 "\n"
22453 									 "void main()\n"
22454 									 "{\n"
22455 									 "    vec4 result = vs_any[0];\n"
22456 									 "\n"
22457 									 "    any_fs = result;\n"
22458 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
22459 									 "    EmitVertex();\n"
22460 									 "    any_fs = result;\n"
22461 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
22462 									 "    EmitVertex();\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 									 "}\n"
22470 									 "\n";
22471 	static const GLchar* tcs = "#version 430 core\n"
22472 							   "#extension GL_ARB_enhanced_layouts : require\n"
22473 							   "\n"
22474 							   "layout(vertices = 1) out;\n"
22475 							   "\n"
22476 							   "in  vec4 vs_any[];\n"
22477 							   "out vec4 tcs_tes[];\n"
22478 							   "\n"
22479 							   "void main()\n"
22480 							   "{\n"
22481 							   "\n"
22482 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
22483 							   "\n"
22484 							   "    gl_TessLevelOuter[0] = 1.0;\n"
22485 							   "    gl_TessLevelOuter[1] = 1.0;\n"
22486 							   "    gl_TessLevelOuter[2] = 1.0;\n"
22487 							   "    gl_TessLevelOuter[3] = 1.0;\n"
22488 							   "    gl_TessLevelInner[0] = 1.0;\n"
22489 							   "    gl_TessLevelInner[1] = 1.0;\n"
22490 							   "}\n"
22491 							   "\n";
22492 	static const GLchar* tes_tested = "#version 430 core\n"
22493 									  "#extension GL_ARB_enhanced_layouts : require\n"
22494 									  "\n"
22495 									  "layout(isolines, point_mode) in;\n"
22496 									  "\n"
22497 									  "VAR_DEFINITION"
22498 									  "\n"
22499 									  "in  vec4 tcs_tes[];\n"
22500 									  "out vec4 any_fs;\n"
22501 									  "\n"
22502 									  "void main()\n"
22503 									  "{\n"
22504 									  "    vec4 result = tcs_tes[0];\n"
22505 									  "\n"
22506 									  "    any_fs = result;\n"
22507 									  "}\n"
22508 									  "\n";
22509 	static const GLchar* vs = "#version 430 core\n"
22510 							  "#extension GL_ARB_enhanced_layouts : require\n"
22511 							  "\n"
22512 							  "in  vec4 in_vs;\n"
22513 							  "out vec4 vs_any;\n"
22514 							  "\n"
22515 							  "void main()\n"
22516 							  "{\n"
22517 							  "    vs_any = in_vs;\n"
22518 							  "}\n"
22519 							  "\n";
22520 	static const GLchar* vs_tested = "#version 430 core\n"
22521 									 "#extension GL_ARB_enhanced_layouts : require\n"
22522 									 "\n"
22523 									 "VAR_DEFINITION"
22524 									 "\n"
22525 									 "in  vec4 in_vs;\n"
22526 									 "out vec4 any_fs;\n"
22527 									 "\n"
22528 									 "void main()\n"
22529 									 "{\n"
22530 									 "    vec4 result = in_vs;\n"
22531 									 "\n"
22532 									 "    any_fs += result;\n"
22533 									 "}\n"
22534 									 "\n";
22535 
22536 	std::string source;
22537 	testCase&   test_case = m_test_cases[test_case_index];
22538 
22539 	if (test_case.m_stage == stage)
22540 	{
22541 		size_t		  position		 = 0;
22542 		const GLchar* var_definition = 0;
22543 
22544 		switch (test_case.m_case)
22545 		{
22546 		case VALID:
22547 			var_definition = valid_var_definition;
22548 			break;
22549 		case INVALID:
22550 			var_definition = invalid_var_definition;
22551 			break;
22552 		default:
22553 			TCU_FAIL("Invalid enum");
22554 		}
22555 
22556 		switch (stage)
22557 		{
22558 		case Utils::Shader::GEOMETRY:
22559 			source = gs_tested;
22560 			break;
22561 		case Utils::Shader::TESS_EVAL:
22562 			source = tes_tested;
22563 			break;
22564 		case Utils::Shader::VERTEX:
22565 			source = vs_tested;
22566 			break;
22567 		default:
22568 			TCU_FAIL("Invalid enum");
22569 		}
22570 
22571 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22572 	}
22573 	else
22574 	{
22575 		switch (test_case.m_stage)
22576 		{
22577 		case Utils::Shader::GEOMETRY:
22578 			switch (stage)
22579 			{
22580 			case Utils::Shader::FRAGMENT:
22581 				source = fs;
22582 				break;
22583 			case Utils::Shader::VERTEX:
22584 				source = vs;
22585 				break;
22586 			default:
22587 				source = "";
22588 			}
22589 			break;
22590 		case Utils::Shader::TESS_EVAL:
22591 			switch (stage)
22592 			{
22593 			case Utils::Shader::FRAGMENT:
22594 				source = fs;
22595 				break;
22596 			case Utils::Shader::TESS_CTRL:
22597 				source = tcs;
22598 				break;
22599 			case Utils::Shader::VERTEX:
22600 				source = vs;
22601 				break;
22602 			default:
22603 				source = "";
22604 			}
22605 			break;
22606 		case Utils::Shader::VERTEX:
22607 			switch (stage)
22608 			{
22609 			case Utils::Shader::FRAGMENT:
22610 				source = fs;
22611 				break;
22612 			default:
22613 				source = "";
22614 			}
22615 			break;
22616 		default:
22617 			TCU_FAIL("Invalid enum");
22618 		}
22619 	}
22620 
22621 	return source;
22622 }
22623 
22624 /** Get description of test case
22625  *
22626  * @param test_case_index Index of test case
22627  *
22628  * @return Test case description
22629  **/
22630 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index)
22631 {
22632 	std::stringstream stream;
22633 	testCase&		  test_case = m_test_cases[test_case_index];
22634 
22635 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
22636 
22637 	switch (test_case.m_case)
22638 	{
22639 	case VALID:
22640 		stream << "valid";
22641 		break;
22642 	case INVALID:
22643 		stream << "invalid";
22644 		break;
22645 	default:
22646 		TCU_FAIL("Invalid enum");
22647 	}
22648 
22649 	return stream.str();
22650 }
22651 
22652 /** Get number of test cases
22653  *
22654  * @return Number of test cases
22655  **/
22656 GLuint XFBDuplicatedStrideTest::getTestCaseNumber()
22657 {
22658 	return static_cast<GLuint>(m_test_cases.size());
22659 }
22660 
22661 /** Selects if "compute" stage is relevant for test
22662  *
22663  * @param ignored
22664  *
22665  * @return false
22666  **/
22667 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */)
22668 {
22669 	return false;
22670 }
22671 
22672 /** Selects if compilation failure is expected result
22673  *
22674  * @param test_case_index Index of test case
22675  *
22676  * @return true
22677  **/
22678 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index)
22679 {
22680 	testCase& test_case = m_test_cases[test_case_index];
22681 
22682 	return (INVALID == test_case.m_case);
22683 }
22684 
22685 /** Prepare all test cases
22686  *
22687  **/
22688 void XFBDuplicatedStrideTest::testInit()
22689 {
22690 	for (GLuint c = 0; c < CASE_MAX; ++c)
22691 	{
22692 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22693 		{
22694 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22695 				(Utils::Shader::FRAGMENT == stage))
22696 			{
22697 				continue;
22698 			}
22699 
22700 			testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
22701 
22702 			m_test_cases.push_back(test_case);
22703 		}
22704 	}
22705 }
22706 
22707 /** Constructor
22708  *
22709  * @param context Test framework context
22710  **/
22711 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context& context)
22712 	: TestBase(context, "xfb_get_program_resource_api",
22713 			   "Test verifies that get program resource reports correct results for XFB")
22714 {
22715 }
22716 
22717 /** Source for given test case and stage
22718  *
22719  * @param test_case_index Index of test case
22720  * @param stage           Shader stage
22721  *
22722  * @return Shader source
22723  **/
22724 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22725 {
22726 	static const GLchar* api_var_definition = "out TYPE b0_v1ARRAY;\n"
22727 											  "out TYPE b1_v1ARRAY;\n"
22728 											  "out TYPE b0_v3ARRAY;\n"
22729 											  "out TYPE b0_v0ARRAY;\n";
22730 	static const GLchar* xfb_var_definition =
22731 		"const uint type_size = SIZE;\n"
22732 		"\n"
22733 		"layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n"
22734 		"\n"
22735 		"layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n"
22736 		"layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n"
22737 		"layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n"
22738 		"layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n";
22739 	static const GLchar* var_use = "    b0_v1INDEX = TYPE(0);\n"
22740 								   "    b1_v1INDEX = TYPE(1);\n"
22741 								   "    b0_v3INDEX = TYPE(0);\n"
22742 								   "    b0_v0INDEX = TYPE(1);\n"
22743 								   "    if (vec4(0) == result)\n"
22744 								   "    {\n"
22745 								   "        b0_v1INDEX = TYPE(1);\n"
22746 								   "        b1_v1INDEX = TYPE(0);\n"
22747 								   "        b0_v3INDEX = TYPE(1);\n"
22748 								   "        b0_v0INDEX = TYPE(0);\n"
22749 								   "    }\n";
22750 	static const GLchar* gs_tested =
22751 		"#version 430 core\n"
22752 		"#extension GL_ARB_enhanced_layouts : require\n"
22753 		"\n"
22754 		"layout(points)                           in;\n"
22755 		"layout(triangle_strip, max_vertices = 4) out;\n"
22756 		"\n"
22757 		"VAR_DEFINITION"
22758 		"\n"
22759 		"out gl_PerVertex \n"
22760 		"{ \n"
22761 		"   vec4  gl_Position; \n" // gl_Position must be redeclared in separable program mode
22762 		"}; \n"
22763 		"in  vec4 tes_gs[];\n"
22764 		"out vec4 gs_fs;\n"
22765 		"\n"
22766 		"void main()\n"
22767 		"{\n"
22768 		"    vec4 result = tes_gs[0];\n"
22769 		"\n"
22770 		"VARIABLE_USE"
22771 		"\n"
22772 		"    gs_fs = result;\n"
22773 		"    gl_Position  = vec4(-1, -1, 0, 1);\n"
22774 		"    EmitVertex();\n"
22775 		"    gs_fs = result;\n"
22776 		"    gl_Position  = vec4(-1, 1, 0, 1);\n"
22777 		"    EmitVertex();\n"
22778 		"    gs_fs = result;\n"
22779 		"    gl_Position  = vec4(1, -1, 0, 1);\n"
22780 		"    EmitVertex();\n"
22781 		"    gs_fs = result;\n"
22782 		"    gl_Position  = vec4(1, 1, 0, 1);\n"
22783 		"    EmitVertex();\n"
22784 		"}\n"
22785 		"\n";
22786 #if 0
22787 	static const GLchar* tcs_tested =
22788 		"#version 430 core\n"
22789 		"#extension GL_ARB_enhanced_layouts : require\n"
22790 		"\n"
22791 		"layout(vertices = 1) out;\n"
22792 		"\n"
22793 		"VAR_DEFINITION"
22794 		"\n"
22795 		"in  vec4 vs_tcs[];\n"
22796 		"out vec4 tcs_tes[];\n"
22797 		"\n"
22798 		"void main()\n"
22799 		"{\n"
22800 		"    vec4 result = vs_tcs[gl_InvocationID];\n"
22801 		"\n"
22802 		"VARIABLE_USE"
22803 		"\n"
22804 		"    tcs_tes[gl_InvocationID] = result;\n"
22805 		"\n"
22806 		"    gl_TessLevelOuter[0] = 1.0;\n"
22807 		"    gl_TessLevelOuter[1] = 1.0;\n"
22808 		"    gl_TessLevelOuter[2] = 1.0;\n"
22809 		"    gl_TessLevelOuter[3] = 1.0;\n"
22810 		"    gl_TessLevelInner[0] = 1.0;\n"
22811 		"    gl_TessLevelInner[1] = 1.0;\n"
22812 		"}\n"
22813 		"\n";
22814 #endif
22815 	static const GLchar* tes_tested = "#version 430 core\n"
22816 									  "#extension GL_ARB_enhanced_layouts : require\n"
22817 									  "\n"
22818 									  "layout(isolines, point_mode) in;\n"
22819 									  "\n"
22820 									  "VAR_DEFINITION"
22821 									  "\n"
22822 									  "in  vec4 tcs_tes[];\n"
22823 									  "out vec4 tes_gs;\n"
22824 									  "\n"
22825 									  "void main()\n"
22826 									  "{\n"
22827 									  "    vec4 result = tcs_tes[0];\n"
22828 									  "\n"
22829 									  "VARIABLE_USE"
22830 									  "\n"
22831 									  "    tes_gs = result;\n"
22832 									  "}\n"
22833 									  "\n";
22834 	static const GLchar* vs_tested = "#version 430 core\n"
22835 									 "#extension GL_ARB_enhanced_layouts : require\n"
22836 									 "\n"
22837 									 "VAR_DEFINITION"
22838 									 "\n"
22839 									 "in  vec4 in_vs;\n"
22840 									 "out vec4 vs_tcs;\n"
22841 									 "\n"
22842 									 "void main()\n"
22843 									 "{\n"
22844 									 "    vec4 result = in_vs;\n"
22845 									 "\n"
22846 									 "VARIABLE_USE"
22847 									 "\n"
22848 									 "    vs_tcs = result;\n"
22849 									 "}\n"
22850 									 "\n";
22851 
22852 	std::string		 source;
22853 	const test_Case& test_case = m_test_cases[test_case_index];
22854 
22855 	if (test_case.m_stage == stage)
22856 	{
22857 		const GLchar* array = "";
22858 		GLchar		  buffer[16];
22859 		const GLchar* index	= "";
22860 		size_t		  position = 0;
22861 		size_t		  temp;
22862 		const GLchar* type_name		 = test_case.m_type.GetGLSLTypeName();
22863 		const GLchar* var_definition = 0;
22864 
22865 		sprintf(buffer, "%d", test_case.m_type.GetSize());
22866 
22867 		if (XFB == test_case.m_case)
22868 		{
22869 			var_definition = xfb_var_definition;
22870 		}
22871 		else
22872 		{
22873 			var_definition = api_var_definition;
22874 		}
22875 
22876 		// It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22877 		// change array = "[]" to "[1]"
22878 		switch (stage)
22879 		{
22880 		case Utils::Shader::GEOMETRY:
22881 			source = gs_tested;
22882 			array  = "[1]";
22883 			index  = "[0]";
22884 			break;
22885 // It is invalid to output transform feedback varyings in tessellation control shader
22886 #if 0
22887 		case Utils::Shader::TESS_CTRL:
22888 			source = tcs_tested;
22889 			array = "[]";
22890 			index = "[gl_InvocationID]";
22891 			break;
22892 #endif
22893 		case Utils::Shader::TESS_EVAL:
22894 			source = tes_tested;
22895 			array  = "[1]";
22896 			index  = "[0]";
22897 			break;
22898 		case Utils::Shader::VERTEX:
22899 			source = vs_tested;
22900 			break;
22901 		default:
22902 			TCU_FAIL("Invalid enum");
22903 		}
22904 
22905 		temp = position;
22906 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22907 		if (XFB == test_case.m_case)
22908 		{
22909 			position = temp;
22910 			Utils::replaceToken("SIZE", position, buffer, source);
22911 		}
22912 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22913 
22914 		Utils::replaceAllTokens("ARRAY", array, source);
22915 		Utils::replaceAllTokens("INDEX", index, source);
22916 		Utils::replaceAllTokens("TYPE", type_name, source);
22917 	}
22918 	else
22919 	{
22920 		source = "";
22921 	}
22922 
22923 	return source;
22924 }
22925 
22926 /** Get description of test case
22927  *
22928  * @param test_case_index Index of test case
22929  *
22930  * @return Test case description
22931  **/
22932 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index)
22933 {
22934 	std::stringstream stream;
22935 	const test_Case&  test_case = m_test_cases[test_case_index];
22936 
22937 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
22938 		   << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
22939 
22940 	switch (test_case.m_case)
22941 	{
22942 	case INTERLEAVED:
22943 		stream << "interleaved";
22944 		break;
22945 	case SEPARATED:
22946 		stream << "separated";
22947 		break;
22948 	case XFB:
22949 		stream << "xfb";
22950 		break;
22951 	default:
22952 		TCU_FAIL("Invalid enum");
22953 	}
22954 
22955 	return stream.str();
22956 }
22957 
22958 /** Get number of test cases
22959  *
22960  * @return Number of test cases
22961  **/
22962 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber()
22963 {
22964 	return static_cast<GLuint>(m_test_cases.size());
22965 }
22966 
22967 /** Inspects program for offset, buffer index, buffer stride and type
22968  *
22969  * @param test_case_index Index of test case
22970  * @param program         Program to query
22971  *
22972  * @return true if query results match expected values, false otherwise
22973  **/
22974 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program& program)
22975 {
22976 	GLint			 b0_stride	= 0;
22977 	GLint			 b1_stride	= 0;
22978 	GLint			 b0_v0_buf	= 0;
22979 	GLint			 b0_v0_offset = 0;
22980 	GLint			 b0_v0_type   = 0;
22981 	GLint			 b0_v1_buf	= 0;
22982 	GLint			 b0_v1_offset = 0;
22983 	GLint			 b0_v1_type   = 0;
22984 	GLint			 b0_v3_buf	= 0;
22985 	GLint			 b0_v3_offset = 0;
22986 	GLint			 b0_v3_type   = 0;
22987 	GLint			 b1_v1_buf	= 0;
22988 	GLint			 b1_v1_offset = 0;
22989 	GLint			 b1_v1_type   = 0;
22990 	const test_Case& test_case	= m_test_cases[test_case_index];
22991 	const GLenum	 type_enum	= test_case.m_type.GetTypeGLenum();
22992 	const GLint		 type_size	= test_case.m_type.GetSize();
22993 
22994 	GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING);
22995 	GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22996 	GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING);
22997 	GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22998 
22999 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset);
23000 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset);
23001 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset);
23002 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset);
23003 
23004 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type);
23005 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type);
23006 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type);
23007 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type);
23008 
23009 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23010 						1 /* buf_size */, &b0_v0_buf);
23011 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23012 						1 /* buf_size */, &b0_v1_buf);
23013 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23014 						1 /* buf_size */, &b0_v3_buf);
23015 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23016 						1 /* buf_size */, &b1_v1_buf);
23017 
23018 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
23019 						&b0_stride);
23020 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
23021 						&b1_stride);
23022 
23023 	if (SEPARATED != test_case.m_case)
23024 	{
23025 		return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) &&
23026 				((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) &&
23027 				((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) &&
23028 				((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
23029 				((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) &&
23030 				((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) &&
23031 				((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
23032 	}
23033 	else
23034 	{
23035 		return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) &&
23036 				((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) &&
23037 				((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
23038 				((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) &&
23039 				((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
23040 	}
23041 }
23042 
23043 /** Insert gl_SkipComponents
23044  *
23045  * @param num_components How many gl_SkipComponents1 need to be inserted
23046  * @param varyings The transform feedback varyings string vector
23047  *
23048  **/
23049 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector& varyings)
23050 {
23051 	int num_component_4 = num_components / 4;
23052 	int num_component_1 = num_components % 4;
23053 	for (int i = 0; i < num_component_4; i++)
23054 	{
23055 		varyings.push_back("gl_SkipComponents4");
23056 	}
23057 	switch (num_component_1)
23058 	{
23059 	case 1:
23060 		varyings.push_back("gl_SkipComponents1");
23061 		break;
23062 	case 2:
23063 		varyings.push_back("gl_SkipComponents2");
23064 		break;
23065 	case 3:
23066 		varyings.push_back("gl_SkipComponents3");
23067 		break;
23068 	default:
23069 		break;
23070 	}
23071 }
23072 
23073 /** Runs test case
23074  *
23075  * @param test_case_index Id of test case
23076  *
23077  * @return true if test case pass, false otherwise
23078  **/
23079 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index)
23080 {
23081 	const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
23082 	Utils::Program	 program(m_context);
23083 	const std::string& tcs_source		= getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
23084 	const std::string& tes_source		= getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
23085 	const test_Case&   test_case		= m_test_cases[test_case_index];
23086 	bool			   test_case_result = true;
23087 	const std::string& vs_source		= getShaderSource(test_case_index, Utils::Shader::VERTEX);
23088 
23089 	// According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values.
23090 	// 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.
23091 
23092 	if (INTERLEAVED == test_case.m_case)
23093 	{
23094 		/*
23095 		 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
23096 		 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
23097 		 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
23098 		 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
23099 
23100 		 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,
23101 		 we need to calculate how many "gl_SkipComponents" need to be inserted.
23102 		 */
23103 		Utils::Program::NameVector captured_varyings;
23104 		captured_varyings.push_back("b0_v0");
23105 		captured_varyings.push_back("b0_v1");
23106 		// Compute how many gl_SkipComponents to be inserted
23107 		int numComponents = test_case.m_type.GetSize() / 4;
23108 		insertSkipComponents(numComponents, captured_varyings);
23109 		captured_varyings.push_back("b0_v3");
23110 		captured_varyings.push_back("gl_NextBuffer");
23111 		insertSkipComponents(numComponents, captured_varyings);
23112 		captured_varyings.push_back("b1_v1");
23113 		insertSkipComponents(numComponents * 2, captured_varyings);
23114 
23115 		program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true,
23116 					 true /* separable */);
23117 	}
23118 	else if (SEPARATED == test_case.m_case)
23119 	{
23120 		Utils::Program::NameVector captured_varyings;
23121 
23122 		captured_varyings.push_back("b0_v0");
23123 		captured_varyings.push_back("b0_v1");
23124 		captured_varyings.push_back("b0_v3");
23125 		captured_varyings.push_back("b1_v1");
23126 
23127 		program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false,
23128 					 true /* separable */);
23129 	}
23130 	else
23131 	{
23132 
23133 		program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
23134 	}
23135 
23136 	test_case_result = inspectProgram(test_case_index, program);
23137 
23138 	return test_case_result;
23139 }
23140 
23141 /** Prepare all test cases
23142  *
23143  **/
23144 void XFBGetProgramResourceAPITest::testInit()
23145 {
23146 	const Functions& gl		 = m_context.getRenderContext().getFunctions();
23147 	const GLuint	 n_types = getTypesNumber();
23148 	GLint			 max_xfb_int;
23149 	GLint			 max_xfb_sep;
23150 
23151 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
23152 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23153 
23154 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep);
23155 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23156 
23157 	GLint max_varyings;
23158 	gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings);
23159 
23160 	for (GLuint i = 0; i < n_types; ++i)
23161 	{
23162 		// 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,
23163 		// 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
23164 		// shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader
23165 		// to guarantee the number of varying not exceeded.
23166 		/*
23167 		 layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;
23168 		 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
23169 		 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
23170 		 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
23171 		 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
23172 		 in  vec4 in_vs;
23173 		 out vec4 vs_tcs;
23174 		 */
23175 		if (i == 7 || i == 9)
23176 			continue;
23177 		const Utils::Type& type = getType(i);
23178 		if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings)
23179 		{
23180 			continue;
23181 		}
23182 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23183 		{
23184 			/*
23185 			 It is invalid to define transform feedback output in HS
23186 			 */
23187 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23188 				(Utils::Shader::FRAGMENT == stage))
23189 			{
23190 				continue;
23191 			}
23192 
23193 			test_Case test_case_int = { INTERLEAVED, (Utils::Shader::STAGES)stage, type };
23194 			test_Case test_case_sep = { SEPARATED, (Utils::Shader::STAGES)stage, type };
23195 			test_Case test_case_xfb = { XFB, (Utils::Shader::STAGES)stage, type };
23196 
23197 			if ((int)type.GetSize() <= max_xfb_int)
23198 			{
23199 				m_test_cases.push_back(test_case_xfb);
23200 				m_test_cases.push_back(test_case_int);
23201 			}
23202 
23203 			if ((int)type.GetSize() <= max_xfb_sep)
23204 			{
23205 				m_test_cases.push_back(test_case_sep);
23206 			}
23207 		}
23208 	}
23209 }
23210 
23211 /** Constructor
23212  *
23213  * @param context Test context
23214  **/
23215 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context& context)
23216 	: BufferTestBase(context, "xfb_override_qualifiers_with_api",
23217 					 "Test verifies that xfb_offset qualifier is not overriden with API")
23218 {
23219 	/* Nothing to be done here */
23220 }
23221 
23222 /** Get descriptors of buffers necessary for test
23223  *
23224  * @param test_case_index Index of test case
23225  * @param out_descriptors Descriptors of buffers used by test
23226  **/
23227 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint				  test_case_index,
23228 															bufferDescriptor::Vector& out_descriptors)
23229 {
23230 	const Utils::Type& type = getType(test_case_index);
23231 
23232 	/* Test needs single uniform and xfb */
23233 	out_descriptors.resize(2);
23234 
23235 	/* Get references */
23236 	bufferDescriptor& uniform = out_descriptors[0];
23237 	bufferDescriptor& xfb	 = out_descriptors[1];
23238 
23239 	/* Index */
23240 	uniform.m_index = 0;
23241 	xfb.m_index		= 0;
23242 
23243 	/* Target */
23244 	uniform.m_target = Utils::Buffer::Uniform;
23245 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
23246 
23247 	/* Data */
23248 	const GLuint				gen_start   = Utils::s_rand;
23249 	const std::vector<GLubyte>& vegeta_data = type.GenerateData();
23250 	const std::vector<GLubyte>& trunks_data = type.GenerateData();
23251 	const std::vector<GLubyte>& goku_data   = type.GenerateData();
23252 
23253 	Utils::s_rand								= gen_start;
23254 	const std::vector<GLubyte>& vegeta_data_pck = type.GenerateDataPacked();
23255 	type.GenerateDataPacked(); // generate the data for trunks
23256 	const std::vector<GLubyte>& goku_data_pck = type.GenerateDataPacked();
23257 
23258 	const GLuint type_size	 = static_cast<GLuint>(vegeta_data.size());
23259 	const GLuint padded_type_size = type.GetBaseAlignment(false) * type.m_n_columns;
23260 	const GLuint type_size_pck = static_cast<GLuint>(vegeta_data_pck.size());
23261 
23262 	/* Uniform data */
23263 	uniform.m_initial_data.resize(3 * padded_type_size);
23264 	memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size);
23265 	memcpy(&uniform.m_initial_data[0] + padded_type_size, &trunks_data[0], type_size);
23266 	memcpy(&uniform.m_initial_data[0] + 2 * padded_type_size, &goku_data[0], type_size);
23267 
23268 	/* XFB data */
23269 	xfb.m_initial_data.resize(3 * type_size_pck);
23270 	xfb.m_expected_data.resize(3 * type_size_pck);
23271 
23272 	for (GLuint i = 0; i < 3 * type_size_pck; ++i)
23273 	{
23274 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
23275 		xfb.m_expected_data[i] = (glw::GLubyte)i;
23276 	}
23277 
23278 	memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck);
23279 	memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck);
23280 }
23281 
23282 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
23283  *
23284  * @param ignored
23285  * @param captured_varyings List of names
23286  **/
23287 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint test_case_index,
23288 														   Utils::Program::NameVector& captured_varyings,
23289 														   GLint* xfb_components)
23290 {
23291 	captured_varyings.resize(1);
23292 
23293 	captured_varyings[0] = "trunks";
23294 
23295 	/* The test captures 3 varyings of type 'type' */
23296 	Utils::Type	type		= getType(test_case_index);
23297 	GLint		type_size	= type.GetSize(false);
23298 	*xfb_components			= 3 * type_size / 4;
23299 }
23300 
23301 /** Get body of main function for given shader stage
23302  *
23303  * @param test_case_index  Index of test case
23304  * @param stage            Shader stage
23305  * @param out_assignments  Set to empty
23306  * @param out_calculations Set to empty
23307  **/
23308 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
23309 													 std::string& out_assignments, std::string& out_calculations)
23310 {
23311 	out_calculations = "";
23312 
23313 	static const GLchar* gs = "    vegeta = uni_vegeta;\n"
23314 							  "    trunks = uni_trunks;\n"
23315 							  "    goku   = uni_goku;\n";
23316 	static const GLchar* fs = "    fs_out = vec4(0);\n"
23317 							  "    if (TYPE(1) == goku + trunks + vegeta)\n"
23318 							  "    {\n"
23319 							  "        fs_out = vec4(1);\n"
23320 							  "    }\n";
23321 
23322 	const GLchar* assignments = "";
23323 	switch (stage)
23324 	{
23325 	case Utils::Shader::FRAGMENT:
23326 		assignments = fs;
23327 		break;
23328 	case Utils::Shader::GEOMETRY:
23329 		assignments = gs;
23330 		break;
23331 	default:
23332 		break;
23333 	}
23334 
23335 	out_assignments = assignments;
23336 
23337 	if (Utils::Shader::FRAGMENT == stage)
23338 	{
23339 		const Utils::Type& type = getType(test_case_index);
23340 
23341 		Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments);
23342 	}
23343 }
23344 
23345 /** Get interface of shader
23346  *
23347  * @param test_case_index  Index of test case
23348  * @param stage            Shader stage
23349  * @param out_interface    Set to ""
23350  **/
23351 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
23352 														  std::string& out_interface)
23353 {
23354 	static const GLchar* gs = "const uint sizeof_type = SIZE;\n"
23355 							  "\n"
23356 							  "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n"
23357 							  "                                      flat out TYPE trunks;\n"
23358 							  "layout (xfb_offset = 0)               flat out TYPE goku;\n"
23359 							  "\n"
23360 							  /*
23361 		 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default,
23362 		 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will
23363 		 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API
23364 		 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the
23365 		 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed,
23366 		 we need to add the qualifier std140,  and change the declaration as layout(binding=0, std140), which can make
23367 		 sure all the block members are packed and the application can upload the data by glBufferData() directly.
23368 		 */
23369 							  "layout(binding = 0, std140) uniform gs_block {\n"
23370 							  "    TYPE uni_vegeta;\n"
23371 							  "    TYPE uni_trunks;\n"
23372 							  "    TYPE uni_goku;\n"
23373 							  "};\n";
23374 	static const GLchar* fs = "flat in TYPE vegeta;\n"
23375 							  "flat in TYPE trunks;\n"
23376 							  "flat in TYPE goku;\n"
23377 							  "\n"
23378 							  "out vec4 fs_out;\n";
23379 
23380 	const Utils::Type& type = getType(test_case_index);
23381 
23382 	switch (stage)
23383 	{
23384 	case Utils::Shader::FRAGMENT:
23385 		out_interface = fs;
23386 		break;
23387 	case Utils::Shader::GEOMETRY:
23388 		out_interface = gs;
23389 		break;
23390 	default:
23391 		out_interface = "";
23392 		return;
23393 	}
23394 
23395 	if (Utils::Shader::GEOMETRY == stage)
23396 	{
23397 		GLchar		 buffer[16];
23398 		size_t		 position  = 0;
23399 		const GLuint type_size = type.GetSize();
23400 
23401 		sprintf(buffer, "%d", type_size);
23402 
23403 		Utils::replaceToken("SIZE", position, buffer, out_interface);
23404 	}
23405 
23406 	Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface);
23407 }
23408 
23409 /** Get type name
23410  *
23411  * @param test_case_index Index of test case
23412  *
23413  * @return Name of type test in test_case_index
23414  **/
23415 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index)
23416 {
23417 	return getTypeName(test_case_index);
23418 }
23419 
23420 /** Returns number of types to test
23421  *
23422  * @return Number of types, 34
23423  **/
23424 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber()
23425 {
23426 	return getTypesNumber();
23427 }
23428 
23429 /** Inspects program to check if all resources are as expected
23430  *
23431  * @param test_case_index Index of test case
23432  * @param program         Program instance
23433  * @param out_stream      Error message
23434  *
23435  * @return true if everything is ok, false otherwise
23436  **/
23437 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program& program,
23438 													  std::stringstream& out_stream)
23439 {
23440 	GLint			   stride	= 0;
23441 	const Utils::Type& type		 = getType(test_case_index);
23442 	const GLuint	   type_size = type.GetSize(false);
23443 
23444 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
23445 						1 /* buf_size */, &stride);
23446 
23447 	if ((GLint)(3 * type_size) != stride)
23448 	{
23449 		out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
23450 
23451 		return false;
23452 	}
23453 
23454 	return true;
23455 }
23456 
23457 /** Constructor
23458  *
23459  * @param context Test context
23460  **/
23461 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context& context)
23462 	: BufferTestBase(context, "xfb_vertex_streams",
23463 					 "Test verifies that xfb qualifier works with multiple output streams")
23464 {
23465 	/* Nothing to be done here */
23466 }
23467 
23468 /** Get descriptors of buffers necessary for test
23469  *
23470  * @param ignored
23471  * @param out_descriptors Descriptors of buffers used by test
23472  **/
23473 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
23474 												bufferDescriptor::Vector& out_descriptors)
23475 {
23476 	const Utils::Type& type = Utils::Type::vec4;
23477 
23478 	/* Test needs single uniform and three xfbs */
23479 	out_descriptors.resize(4);
23480 
23481 	/* Get references */
23482 	bufferDescriptor& uniform = out_descriptors[0];
23483 	bufferDescriptor& xfb_1   = out_descriptors[1];
23484 	bufferDescriptor& xfb_2   = out_descriptors[2];
23485 	bufferDescriptor& xfb_3   = out_descriptors[3];
23486 
23487 	/* Index */
23488 	uniform.m_index = 0;
23489 	xfb_1.m_index   = 1;
23490 	xfb_2.m_index   = 2;
23491 	xfb_3.m_index   = 3;
23492 
23493 	/* Target */
23494 	uniform.m_target = Utils::Buffer::Uniform;
23495 	xfb_1.m_target   = Utils::Buffer::Transform_feedback;
23496 	xfb_2.m_target   = Utils::Buffer::Transform_feedback;
23497 	xfb_3.m_target   = Utils::Buffer::Transform_feedback;
23498 
23499 	/* Data */
23500 	const std::vector<GLubyte>& goku_data   = type.GenerateData();
23501 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
23502 	const std::vector<GLubyte>& goten_data  = type.GenerateData();
23503 	const std::vector<GLubyte>& picolo_data = type.GenerateData();
23504 	const std::vector<GLubyte>& vegeta_data = type.GenerateData();
23505 	const std::vector<GLubyte>& bulma_data  = type.GenerateData();
23506 
23507 	const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
23508 
23509 	/* Uniform data */
23510 	uniform.m_initial_data.resize(6 * type_size);
23511 	memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size);
23512 	memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size);
23513 	memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
23514 	memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size);
23515 	memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
23516 	memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size);
23517 
23518 	/* XFB data */
23519 	static const GLuint xfb_stride = 64;
23520 	xfb_1.m_initial_data.resize(xfb_stride);
23521 	xfb_1.m_expected_data.resize(xfb_stride);
23522 	xfb_2.m_initial_data.resize(xfb_stride);
23523 	xfb_2.m_expected_data.resize(xfb_stride);
23524 	xfb_3.m_initial_data.resize(xfb_stride);
23525 	xfb_3.m_expected_data.resize(xfb_stride);
23526 
23527 	for (GLuint i = 0; i < xfb_stride; ++i)
23528 	{
23529 		xfb_1.m_initial_data[i]  = (glw::GLubyte)i;
23530 		xfb_1.m_expected_data[i] = (glw::GLubyte)i;
23531 		xfb_2.m_initial_data[i]  = (glw::GLubyte)i;
23532 		xfb_2.m_expected_data[i] = (glw::GLubyte)i;
23533 		xfb_3.m_initial_data[i]  = (glw::GLubyte)i;
23534 		xfb_3.m_expected_data[i] = (glw::GLubyte)i;
23535 	}
23536 
23537 	memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size);
23538 	memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size);
23539 	memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size);
23540 	memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size);
23541 	memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size);
23542 	memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size);
23543 }
23544 
23545 /** Get body of main function for given shader stage
23546  *
23547  * @param ignored
23548  * @param stage            Shader stage
23549  * @param out_assignments  Set to empty
23550  * @param out_calculations Set to empty
23551  **/
23552 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23553 										 std::string& out_assignments, std::string& out_calculations)
23554 {
23555 	out_calculations = "";
23556 
23557 	// the shader declares the output variables with different "stream" qualifier, to make the data can export to
23558 	// each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted
23559 	// by the GS is assigned to specific stream.
23560 	static const GLchar* gs = "    goku   = uni_goku;\n"
23561 							  "    gohan  = uni_gohan;\n"
23562 							  "    goten  = uni_goten;\n"
23563 							  "    EmitStreamVertex(0);\n"
23564 							  "    EndStreamPrimitive(0);\n"
23565 							  "    picolo = uni_picolo;\n"
23566 							  "    vegeta = uni_vegeta;\n"
23567 							  "    EmitStreamVertex(1);\n"
23568 							  "    EndStreamPrimitive(1);\n"
23569 							  "    bulma  = uni_bulma;\n"
23570 							  "    EmitStreamVertex(2);\n"
23571 							  "    EndStreamPrimitive(2);\n";
23572 
23573 	static const GLchar* fs = "    fs_out = gohan + goku + goten;\n";
23574 
23575 	const GLchar* assignments = "";
23576 	switch (stage)
23577 	{
23578 	case Utils::Shader::FRAGMENT:
23579 		assignments = fs;
23580 		break;
23581 	case Utils::Shader::GEOMETRY:
23582 		assignments = gs;
23583 		break;
23584 	default:
23585 		break;
23586 	}
23587 
23588 	out_assignments = assignments;
23589 }
23590 
23591 /** Get interface of shader
23592  *
23593  * @param ignored
23594  * @param stage            Shader stage
23595  * @param out_interface    Set to ""
23596  **/
23597 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23598 											  std::string& out_interface)
23599 {
23600 	static const GLchar* gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
23601 							  "layout (xfb_buffer = 2, xfb_stride = 64) out;\n"
23602 							  "layout (xfb_buffer = 3, xfb_stride = 64) out;\n"
23603 							  "\n"
23604 							  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23605 							  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23606 							  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"
23607 							  "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n"
23608 							  "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n"
23609 							  "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n"
23610 							  "\n"
23611 							  "layout(binding = 0) uniform gs_block {\n"
23612 							  "    vec4 uni_goku;\n"
23613 							  "    vec4 uni_gohan;\n"
23614 							  "    vec4 uni_goten;\n"
23615 							  "    vec4 uni_picolo;\n"
23616 							  "    vec4 uni_vegeta;\n"
23617 							  "    vec4 uni_bulma;\n"
23618 							  "};\n";
23619 	/*
23620 	 Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader
23621 	 */
23622 	static const GLchar* fs = "in vec4 goku;\n"
23623 							  "in vec4 gohan;\n"
23624 							  "in vec4 goten;\n"
23625 							  "\n"
23626 							  "out vec4 fs_out;\n";
23627 
23628 	switch (stage)
23629 	{
23630 	case Utils::Shader::FRAGMENT:
23631 		out_interface = fs;
23632 		break;
23633 	case Utils::Shader::GEOMETRY:
23634 		out_interface = gs;
23635 		break;
23636 	default:
23637 		out_interface = "";
23638 		return;
23639 	}
23640 }
23641 
23642 /** Constructor
23643  *
23644  * @param context Test framework context
23645  **/
23646 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context& context)
23647 	: NegativeTestBase(
23648 		  context, "xfb_multiple_vertex_streams",
23649 		  "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer")
23650 {
23651 }
23652 
23653 /** Source for given test case and stage
23654  *
23655  * @param ignored
23656  * @param stage           Shader stage
23657  *
23658  * @return Shader source
23659  **/
23660 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage)
23661 {
23662 	static const GLchar* var_definition = "const uint valid_stride = 64;\n"
23663 										  "\n"
23664 										  "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n"
23665 										  "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n"
23666 										  "\n"
23667 										  "\n"
23668 #if DEBUG_NEG_REMOVE_ERROR
23669 										  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23670 										  "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 gohan;\n"
23671 										  "layout (stream = 2, xfb_buffer = 2, xfb_offset = 16) out vec4 goten;\n";
23672 #else
23673 										  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23674 										  "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23675 										  "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n";
23676 #endif /* DEBUG_NEG_REMOVE_ERROR */
23677 	static const GLchar* var_use = "    goku  = result / 2;\n"
23678 								   "    gohan = result / 4;\n"
23679 								   "    goten = result / 6;\n";
23680 	static const GLchar* fs = "#version 430 core\n"
23681 							  "#extension GL_ARB_enhanced_layouts : require\n"
23682 							  "\n"
23683 							  "in  vec4 gs_fs;\n"
23684 							  "in  vec4 goku;\n"
23685 							  "out vec4 fs_out;\n"
23686 							  "\n"
23687 							  "void main()\n"
23688 							  "{\n"
23689 							  "    fs_out = gs_fs + goku;\n"
23690 							  "}\n"
23691 							  "\n";
23692 	static const GLchar* gs = "#version 430 core\n"
23693 							  "#extension GL_ARB_enhanced_layouts : require\n"
23694 							  "\n"
23695 							  "layout(points)                           in;\n"
23696 							  "layout(triangle_strip, max_vertices = 4) out;\n"
23697 							  "\n"
23698 							  "VAR_DEFINITION"
23699 							  "\n"
23700 							  "in  vec4 vs_gs[];\n"
23701 							  "out vec4 gs_fs;\n"
23702 							  "\n"
23703 							  "void main()\n"
23704 							  "{\n"
23705 							  "    vec4 result = vs_gs[0];\n"
23706 							  "\n"
23707 							  "VARIABLE_USE"
23708 							  "\n"
23709 							  "    gs_fs = result;\n"
23710 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
23711 							  "    EmitVertex();\n"
23712 							  "    gs_fs = result;\n"
23713 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
23714 							  "    EmitVertex();\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 							  "}\n"
23722 							  "\n";
23723 	static const GLchar* vs = "#version 430 core\n"
23724 							  "#extension GL_ARB_enhanced_layouts : require\n"
23725 							  "\n"
23726 							  "in  vec4 in_vs;\n"
23727 							  "out vec4 vs_gs;\n"
23728 							  "\n"
23729 							  "void main()\n"
23730 							  "{\n"
23731 							  "    vs_gs = in_vs;\n"
23732 							  "}\n"
23733 							  "\n";
23734 
23735 	std::string source;
23736 
23737 	if (Utils::Shader::GEOMETRY == stage)
23738 	{
23739 		size_t position = 0;
23740 
23741 		source = gs;
23742 
23743 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23744 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23745 	}
23746 	else
23747 	{
23748 		switch (stage)
23749 		{
23750 		case Utils::Shader::FRAGMENT:
23751 			source = fs;
23752 			break;
23753 		case Utils::Shader::VERTEX:
23754 			source = vs;
23755 			break;
23756 		default:
23757 			source = "";
23758 		}
23759 	}
23760 
23761 	return source;
23762 }
23763 
23764 /** Selects if "compute" stage is relevant for test
23765  *
23766  * @param ignored
23767  *
23768  * @return false
23769  **/
23770 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */)
23771 {
23772 	return false;
23773 }
23774 
23775 /** Constructor
23776  *
23777  * @param context Test framework context
23778  **/
23779 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context& context)
23780 	: NegativeTestBase(context, "xfb_exceed_buffer_limit",
23781 					   "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit")
23782 {
23783 }
23784 
23785 /** Source for given test case and stage
23786  *
23787  * @param test_case_index Index of test case
23788  * @param stage           Shader stage
23789  *
23790  * @return Shader source
23791  **/
23792 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23793 {
23794 	static const GLchar* block_var_definition = "const uint buffer_index = MAX_BUFFER;\n"
23795 												"\n"
23796 #if DEBUG_NEG_REMOVE_ERROR
23797 												"layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
23798 #else
23799 												"layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n"
23800 #endif /* DEBUG_NEG_REMOVE_ERROR */
23801 												"    vec4 member;\n"
23802 												"} goku;\n";
23803 	static const GLchar* global_var_definition = "const uint buffer_index = MAX_BUFFER;\n"
23804 												 "\n"
23805 #if DEBUG_NEG_REMOVE_ERROR
23806 												 "layout (xfb_buffer = 0) out;\n";
23807 #else
23808 												 "layout (xfb_buffer = buffer_index) out;\n";
23809 #endif /* DEBUG_NEG_REMOVE_ERROR */
23810 	static const GLchar* vector_var_definition = "const uint buffer_index = MAX_BUFFER;\n"
23811 												 "\n"
23812 #if DEBUG_NEG_REMOVE_ERROR
23813 												 "layout (xfb_buffer = 0) out vec4 goku;\n";
23814 #else
23815 												 "layout (xfb_buffer = buffer_index) out vec4 goku;\n";
23816 #endif /* DEBUG_NEG_REMOVE_ERROR */
23817 	static const GLchar* block_use  = "    goku.member = result / 2;\n";
23818 	static const GLchar* global_use = "";
23819 	static const GLchar* vector_use = "    goku = result / 2;\n";
23820 	static const GLchar* fs			= "#version 430 core\n"
23821 							  "#extension GL_ARB_enhanced_layouts : require\n"
23822 							  "\n"
23823 							  "in  vec4 any_fs;\n"
23824 							  "out vec4 fs_out;\n"
23825 							  "\n"
23826 							  "void main()\n"
23827 							  "{\n"
23828 							  "    fs_out = any_fs;\n"
23829 							  "}\n"
23830 							  "\n";
23831 	static const GLchar* gs_tested = "#version 430 core\n"
23832 									 "#extension GL_ARB_enhanced_layouts : require\n"
23833 									 "\n"
23834 									 "layout(points)                           in;\n"
23835 									 "layout(triangle_strip, max_vertices = 4) out;\n"
23836 									 "\n"
23837 									 "VAR_DEFINITION"
23838 									 "\n"
23839 									 "in  vec4 vs_any[];\n"
23840 									 "out vec4 any_fs;\n"
23841 									 "\n"
23842 									 "void main()\n"
23843 									 "{\n"
23844 									 "    vec4 result = vs_any[0];\n"
23845 									 "\n"
23846 									 "VARIABLE_USE"
23847 									 "\n"
23848 									 "    any_fs = result;\n"
23849 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
23850 									 "    EmitVertex();\n"
23851 									 "    any_fs = result;\n"
23852 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
23853 									 "    EmitVertex();\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 									 "}\n"
23861 									 "\n";
23862 	static const GLchar* tcs = "#version 430 core\n"
23863 							   "#extension GL_ARB_enhanced_layouts : require\n"
23864 							   "\n"
23865 							   "layout(vertices = 1) out;\n"
23866 							   "\n"
23867 							   "in  vec4 vs_any[];\n"
23868 							   "out vec4 tcs_tes[];\n"
23869 							   "\n"
23870 							   "void main()\n"
23871 							   "{\n"
23872 							   "\n"
23873 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
23874 							   "\n"
23875 							   "    gl_TessLevelOuter[0] = 1.0;\n"
23876 							   "    gl_TessLevelOuter[1] = 1.0;\n"
23877 							   "    gl_TessLevelOuter[2] = 1.0;\n"
23878 							   "    gl_TessLevelOuter[3] = 1.0;\n"
23879 							   "    gl_TessLevelInner[0] = 1.0;\n"
23880 							   "    gl_TessLevelInner[1] = 1.0;\n"
23881 							   "}\n"
23882 							   "\n";
23883 	static const GLchar* tes_tested = "#version 430 core\n"
23884 									  "#extension GL_ARB_enhanced_layouts : require\n"
23885 									  "\n"
23886 									  "layout(isolines, point_mode) in;\n"
23887 									  "\n"
23888 									  "VAR_DEFINITION"
23889 									  "\n"
23890 									  "in  vec4 tcs_tes[];\n"
23891 									  "out vec4 any_fs;\n"
23892 									  "\n"
23893 									  "void main()\n"
23894 									  "{\n"
23895 									  "    vec4 result = tcs_tes[0];\n"
23896 									  "\n"
23897 									  "VARIABLE_USE"
23898 									  "\n"
23899 									  "    any_fs += result;\n"
23900 									  "}\n"
23901 									  "\n";
23902 	static const GLchar* vs = "#version 430 core\n"
23903 							  "#extension GL_ARB_enhanced_layouts : require\n"
23904 							  "\n"
23905 							  "in  vec4 in_vs;\n"
23906 							  "out vec4 vs_any;\n"
23907 							  "\n"
23908 							  "void main()\n"
23909 							  "{\n"
23910 							  "    vs_any = in_vs;\n"
23911 							  "}\n"
23912 							  "\n";
23913 	static const GLchar* vs_tested = "#version 430 core\n"
23914 									 "#extension GL_ARB_enhanced_layouts : require\n"
23915 									 "\n"
23916 									 "VAR_DEFINITION"
23917 									 "\n"
23918 									 "in  vec4 in_vs;\n"
23919 									 "out vec4 any_fs;\n"
23920 									 "\n"
23921 									 "void main()\n"
23922 									 "{\n"
23923 									 "    vec4 result = in_vs;\n"
23924 									 "\n"
23925 									 "VARIABLE_USE"
23926 									 "\n"
23927 									 "    any_fs = result;\n"
23928 									 "}\n"
23929 									 "\n";
23930 
23931 	std::string source;
23932 	testCase&   test_case = m_test_cases[test_case_index];
23933 
23934 	if (test_case.m_stage == stage)
23935 	{
23936 		GLchar			 buffer[16];
23937 		const Functions& gl		   = m_context.getRenderContext().getFunctions();
23938 		GLint			 max_n_xfb = 0;
23939 		size_t			 position  = 0;
23940 		const GLchar*	var_definition = 0;
23941 		const GLchar*	var_use		= 0;
23942 
23943 		gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb);
23944 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23945 
23946 		sprintf(buffer, "%d", max_n_xfb);
23947 
23948 		switch (test_case.m_case)
23949 		{
23950 		case BLOCK:
23951 			var_definition = block_var_definition;
23952 			var_use		   = block_use;
23953 			break;
23954 		case GLOBAL:
23955 			var_definition = global_var_definition;
23956 			var_use		   = global_use;
23957 			break;
23958 		case VECTOR:
23959 			var_definition = vector_var_definition;
23960 			var_use		   = vector_use;
23961 			break;
23962 		default:
23963 			TCU_FAIL("Invalid enum");
23964 		}
23965 
23966 		switch (stage)
23967 		{
23968 		case Utils::Shader::GEOMETRY:
23969 			source = gs_tested;
23970 			break;
23971 		case Utils::Shader::TESS_EVAL:
23972 			source = tes_tested;
23973 			break;
23974 		case Utils::Shader::VERTEX:
23975 			source = vs_tested;
23976 			break;
23977 		default:
23978 			TCU_FAIL("Invalid enum");
23979 		}
23980 
23981 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23982 		position = 0;
23983 		Utils::replaceToken("MAX_BUFFER", position, buffer, source);
23984 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23985 	}
23986 	else
23987 	{
23988 		switch (test_case.m_stage)
23989 		{
23990 		case Utils::Shader::GEOMETRY:
23991 			switch (stage)
23992 			{
23993 			case Utils::Shader::FRAGMENT:
23994 				source = fs;
23995 				break;
23996 			case Utils::Shader::VERTEX:
23997 				source = vs;
23998 				break;
23999 			default:
24000 				source = "";
24001 			}
24002 			break;
24003 		case Utils::Shader::TESS_EVAL:
24004 			switch (stage)
24005 			{
24006 			case Utils::Shader::FRAGMENT:
24007 				source = fs;
24008 				break;
24009 			case Utils::Shader::TESS_CTRL:
24010 				source = tcs;
24011 				break;
24012 			case Utils::Shader::VERTEX:
24013 				source = vs;
24014 				break;
24015 			default:
24016 				source = "";
24017 			}
24018 			break;
24019 		case Utils::Shader::VERTEX:
24020 			switch (stage)
24021 			{
24022 			case Utils::Shader::FRAGMENT:
24023 				source = fs;
24024 				break;
24025 			default:
24026 				source = "";
24027 			}
24028 			break;
24029 		default:
24030 			TCU_FAIL("Invalid enum");
24031 		}
24032 	}
24033 
24034 	return source;
24035 }
24036 
24037 /** Get description of test case
24038  *
24039  * @param test_case_index Index of test case
24040  *
24041  * @return Test case description
24042  **/
24043 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index)
24044 {
24045 	std::stringstream stream;
24046 	testCase&		  test_case = m_test_cases[test_case_index];
24047 
24048 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
24049 
24050 	switch (test_case.m_case)
24051 	{
24052 	case BLOCK:
24053 		stream << "BLOCK";
24054 		break;
24055 	case GLOBAL:
24056 		stream << "GLOBAL";
24057 		break;
24058 	case VECTOR:
24059 		stream << "VECTOR";
24060 		break;
24061 	default:
24062 		TCU_FAIL("Invalid enum");
24063 	}
24064 
24065 	return stream.str();
24066 }
24067 
24068 /** Get number of test cases
24069  *
24070  * @return Number of test cases
24071  **/
24072 GLuint XFBExceedBufferLimitTest::getTestCaseNumber()
24073 {
24074 	return static_cast<GLuint>(m_test_cases.size());
24075 }
24076 
24077 /** Selects if "compute" stage is relevant for test
24078  *
24079  * @param ignored
24080  *
24081  * @return false
24082  **/
24083 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */)
24084 {
24085 	return false;
24086 }
24087 
24088 /** Prepare all test cases
24089  *
24090  **/
24091 void XFBExceedBufferLimitTest::testInit()
24092 {
24093 	for (GLuint c = 0; c < CASE_MAX; ++c)
24094 	{
24095 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24096 		{
24097 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24098 				(Utils::Shader::FRAGMENT == stage))
24099 			{
24100 				continue;
24101 			}
24102 
24103 			testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
24104 
24105 			m_test_cases.push_back(test_case);
24106 		}
24107 	}
24108 }
24109 
24110 /** Constructor
24111  *
24112  * @param context Test framework context
24113  **/
24114 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context& context)
24115 	: NegativeTestBase(context, "xfb_exceed_offset_limit",
24116 					   "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit")
24117 {
24118 }
24119 
24120 /** Source for given test case and stage
24121  *
24122  * @param test_case_index Index of test case
24123  * @param stage           Shader stage
24124  *
24125  * @return Shader source
24126  **/
24127 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24128 {
24129 	static const GLchar* block_var_definition = "const uint overflow_offset = MAX_SIZE + 16;\n"
24130 												"\n"
24131 #if DEBUG_NEG_REMOVE_ERROR
24132 												"layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
24133 #else
24134 												"layout (xfb_buffer = 0, xfb_offset = overflow_offset + 16) out Goku "
24135 												"{\n"
24136 #endif /* DEBUG_NEG_REMOVE_ERROR */
24137 												"    vec4 member;\n"
24138 												"} goku;\n";
24139 	static const GLchar* global_var_definition = "const uint overflow_offset = MAX_SIZE + 16;\n"
24140 												 "\n"
24141 #if DEBUG_NEG_REMOVE_ERROR
24142 												 "layout (xfb_buffer = 0, xfb_stride = 0) out;\n";
24143 #else
24144 												 "layout (xfb_buffer = 0, xfb_stride = overflow_offset) out;\n";
24145 #endif /* DEBUG_NEG_REMOVE_ERROR */
24146 	static const GLchar* vector_var_definition = "const uint overflow_offset = MAX_SIZE + 16;\n"
24147 												 "\n"
24148 #if DEBUG_NEG_REMOVE_ERROR
24149 												 "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 goku;\n";
24150 #else
24151 												 "layout (xfb_buffer = 0, xfb_offset = overflow_offset) out vec4 "
24152 												 "goku;\n";
24153 #endif /* DEBUG_NEG_REMOVE_ERROR */
24154 	static const GLchar* block_use  = "    goku.member = result / 2;\n";
24155 	static const GLchar* global_use = "";
24156 	static const GLchar* vector_use = "    goku = result / 2;\n";
24157 	static const GLchar* fs			= "#version 430 core\n"
24158 							  "#extension GL_ARB_enhanced_layouts : require\n"
24159 							  "\n"
24160 							  "in  vec4 any_fs;\n"
24161 							  "out vec4 fs_out;\n"
24162 							  "\n"
24163 							  "void main()\n"
24164 							  "{\n"
24165 							  "    fs_out = any_fs;\n"
24166 							  "}\n"
24167 							  "\n";
24168 	static const GLchar* gs_tested = "#version 430 core\n"
24169 									 "#extension GL_ARB_enhanced_layouts : require\n"
24170 									 "\n"
24171 									 "layout(points)                           in;\n"
24172 									 "layout(triangle_strip, max_vertices = 4) out;\n"
24173 									 "\n"
24174 									 "VAR_DEFINITION"
24175 									 "\n"
24176 									 "in  vec4 vs_any[];\n"
24177 									 "out vec4 any_fs;\n"
24178 									 "\n"
24179 									 "void main()\n"
24180 									 "{\n"
24181 									 "    vec4 result = vs_any[0];\n"
24182 									 "\n"
24183 									 "VARIABLE_USE"
24184 									 "\n"
24185 									 "    any_fs = result;\n"
24186 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
24187 									 "    EmitVertex();\n"
24188 									 "    any_fs = result;\n"
24189 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
24190 									 "    EmitVertex();\n"
24191 									 "    any_fs = result;\n"
24192 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
24193 									 "    EmitVertex();\n"
24194 									 "    any_fs = result;\n"
24195 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
24196 									 "    EmitVertex();\n"
24197 									 "}\n"
24198 									 "\n";
24199 	static const GLchar* tcs = "#version 430 core\n"
24200 							   "#extension GL_ARB_enhanced_layouts : require\n"
24201 							   "\n"
24202 							   "layout(vertices = 1) out;\n"
24203 							   "\n"
24204 							   "in  vec4 vs_any[];\n"
24205 							   "out vec4 tcs_tes[];\n"
24206 							   "\n"
24207 							   "void main()\n"
24208 							   "{\n"
24209 							   "\n"
24210 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
24211 							   "\n"
24212 							   "    gl_TessLevelOuter[0] = 1.0;\n"
24213 							   "    gl_TessLevelOuter[1] = 1.0;\n"
24214 							   "    gl_TessLevelOuter[2] = 1.0;\n"
24215 							   "    gl_TessLevelOuter[3] = 1.0;\n"
24216 							   "    gl_TessLevelInner[0] = 1.0;\n"
24217 							   "    gl_TessLevelInner[1] = 1.0;\n"
24218 							   "}\n"
24219 							   "\n";
24220 	static const GLchar* tes_tested = "#version 430 core\n"
24221 									  "#extension GL_ARB_enhanced_layouts : require\n"
24222 									  "\n"
24223 									  "layout(isolines, point_mode) in;\n"
24224 									  "\n"
24225 									  "VAR_DEFINITION"
24226 									  "\n"
24227 									  "in  vec4 tcs_tes[];\n"
24228 									  "out vec4 any_fs;\n"
24229 									  "\n"
24230 									  "void main()\n"
24231 									  "{\n"
24232 									  "    vec4 result = tcs_tes[0];\n"
24233 									  "\n"
24234 									  "VARIABLE_USE"
24235 									  "\n"
24236 									  "    any_fs += result;\n"
24237 									  "}\n"
24238 									  "\n";
24239 	static const GLchar* vs = "#version 430 core\n"
24240 							  "#extension GL_ARB_enhanced_layouts : require\n"
24241 							  "\n"
24242 							  "in  vec4 in_vs;\n"
24243 							  "out vec4 vs_any;\n"
24244 							  "\n"
24245 							  "void main()\n"
24246 							  "{\n"
24247 							  "    vs_any = in_vs;\n"
24248 							  "}\n"
24249 							  "\n";
24250 	static const GLchar* vs_tested = "#version 430 core\n"
24251 									 "#extension GL_ARB_enhanced_layouts : require\n"
24252 									 "\n"
24253 									 "VAR_DEFINITION"
24254 									 "\n"
24255 									 "in  vec4 in_vs;\n"
24256 									 "out vec4 any_fs;\n"
24257 									 "\n"
24258 									 "void main()\n"
24259 									 "{\n"
24260 									 "    vec4 result = in_vs;\n"
24261 									 "\n"
24262 									 "VARIABLE_USE"
24263 									 "\n"
24264 									 "    any_fs = result;\n"
24265 									 "}\n"
24266 									 "\n";
24267 
24268 	std::string source;
24269 	testCase&   test_case = m_test_cases[test_case_index];
24270 
24271 	if (test_case.m_stage == stage)
24272 	{
24273 		GLchar			 buffer[16];
24274 		const Functions& gl				 = m_context.getRenderContext().getFunctions();
24275 		GLint			 max_n_xfb_comp  = 0;
24276 		GLint			 max_n_xfb_bytes = 0;
24277 		size_t			 position		 = 0;
24278 		const GLchar*	var_definition = 0;
24279 		const GLchar*	var_use		= 0;
24280 
24281 		gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp);
24282 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
24283 
24284 		max_n_xfb_bytes = max_n_xfb_comp * 4;
24285 
24286 		sprintf(buffer, "%d", max_n_xfb_bytes);
24287 
24288 		switch (test_case.m_case)
24289 		{
24290 		case BLOCK:
24291 			var_definition = block_var_definition;
24292 			var_use		   = block_use;
24293 			break;
24294 		case GLOBAL:
24295 			var_definition = global_var_definition;
24296 			var_use		   = global_use;
24297 			break;
24298 		case VECTOR:
24299 			var_definition = vector_var_definition;
24300 			var_use		   = vector_use;
24301 			break;
24302 		default:
24303 			TCU_FAIL("Invalid enum");
24304 		}
24305 
24306 		switch (stage)
24307 		{
24308 		case Utils::Shader::GEOMETRY:
24309 			source = gs_tested;
24310 			break;
24311 		case Utils::Shader::TESS_EVAL:
24312 			source = tes_tested;
24313 			break;
24314 		case Utils::Shader::VERTEX:
24315 			source = vs_tested;
24316 			break;
24317 		default:
24318 			TCU_FAIL("Invalid enum");
24319 		}
24320 
24321 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
24322 		position = 0;
24323 		Utils::replaceToken("MAX_SIZE", position, buffer, source);
24324 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
24325 	}
24326 	else
24327 	{
24328 		switch (test_case.m_stage)
24329 		{
24330 		case Utils::Shader::GEOMETRY:
24331 			switch (stage)
24332 			{
24333 			case Utils::Shader::FRAGMENT:
24334 				source = fs;
24335 				break;
24336 			case Utils::Shader::VERTEX:
24337 				source = vs;
24338 				break;
24339 			default:
24340 				source = "";
24341 			}
24342 			break;
24343 		case Utils::Shader::TESS_EVAL:
24344 			switch (stage)
24345 			{
24346 			case Utils::Shader::FRAGMENT:
24347 				source = fs;
24348 				break;
24349 			case Utils::Shader::TESS_CTRL:
24350 				source = tcs;
24351 				break;
24352 			case Utils::Shader::VERTEX:
24353 				source = vs;
24354 				break;
24355 			default:
24356 				source = "";
24357 			}
24358 			break;
24359 		case Utils::Shader::VERTEX:
24360 			switch (stage)
24361 			{
24362 			case Utils::Shader::FRAGMENT:
24363 				source = fs;
24364 				break;
24365 			default:
24366 				source = "";
24367 			}
24368 			break;
24369 		default:
24370 			TCU_FAIL("Invalid enum");
24371 		}
24372 	}
24373 
24374 	return source;
24375 }
24376 
24377 /** Get description of test case
24378  *
24379  * @param test_case_index Index of test case
24380  *
24381  * @return Test case description
24382  **/
24383 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index)
24384 {
24385 	std::stringstream stream;
24386 	testCase&		  test_case = m_test_cases[test_case_index];
24387 
24388 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
24389 
24390 	switch (test_case.m_case)
24391 	{
24392 	case BLOCK:
24393 		stream << "BLOCK";
24394 		break;
24395 	case GLOBAL:
24396 		stream << "GLOBAL";
24397 		break;
24398 	case VECTOR:
24399 		stream << "VECTOR";
24400 		break;
24401 	default:
24402 		TCU_FAIL("Invalid enum");
24403 	}
24404 
24405 	return stream.str();
24406 }
24407 
24408 /** Get number of test cases
24409  *
24410  * @return Number of test cases
24411  **/
24412 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber()
24413 {
24414 	return static_cast<GLuint>(m_test_cases.size());
24415 }
24416 
24417 /** Selects if "compute" stage is relevant for test
24418  *
24419  * @param ignored
24420  *
24421  * @return false
24422  **/
24423 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */)
24424 {
24425 	return false;
24426 }
24427 
24428 /** Prepare all test cases
24429  *
24430  **/
24431 void XFBExceedOffsetLimitTest::testInit()
24432 {
24433 	for (GLuint c = 0; c < CASE_MAX; ++c)
24434 	{
24435 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24436 		{
24437 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24438 				(Utils::Shader::FRAGMENT == stage))
24439 			{
24440 				continue;
24441 			}
24442 
24443 			testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
24444 
24445 			m_test_cases.push_back(test_case);
24446 		}
24447 	}
24448 }
24449 
24450 /** Constructor
24451  *
24452  * @param context Test context
24453  **/
24454 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context& context)
24455 	: BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected")
24456 {
24457 	/* Nothing to be done here */
24458 }
24459 
24460 /** Get descriptors of buffers necessary for test
24461  *
24462  * @param test_case_index Index of test case
24463  * @param out_descriptors Descriptors of buffers used by test
24464  **/
24465 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24466 {
24467 	// the function "getType(test_case_index)" can't return correct data type, so change code as following:
24468 	const Utils::Type& type = m_test_cases[test_case_index].m_type;
24469 
24470 	/* Test needs single uniform and two xfbs */
24471 	out_descriptors.resize(3);
24472 
24473 	/* Get references */
24474 	bufferDescriptor& uniform = out_descriptors[0];
24475 	bufferDescriptor& xfb_1   = out_descriptors[1];
24476 	bufferDescriptor& xfb_3   = out_descriptors[2];
24477 
24478 	/* Index */
24479 	uniform.m_index = 0;
24480 	xfb_1.m_index   = 1;
24481 	xfb_3.m_index   = 3;
24482 
24483 	/* Target */
24484 	uniform.m_target = Utils::Buffer::Uniform;
24485 	xfb_1.m_target   = Utils::Buffer::Transform_feedback;
24486 	xfb_3.m_target   = Utils::Buffer::Transform_feedback;
24487 
24488 	/* Data */
24489 	const GLuint				gen_start   = Utils::s_rand;
24490 	const std::vector<GLubyte>& chichi_data = type.GenerateData();
24491 	const std::vector<GLubyte>& bulma_data  = type.GenerateData();
24492 	const std::vector<GLubyte>& trunks_data = type.GenerateData();
24493 	const std::vector<GLubyte>& bra_data	= type.GenerateData();
24494 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
24495 	const std::vector<GLubyte>& goten_data  = type.GenerateData();
24496 
24497 	Utils::s_rand								= gen_start;
24498 	const std::vector<GLubyte>& chichi_data_pck = type.GenerateDataPacked();
24499 	const std::vector<GLubyte>& bulma_data_pck  = type.GenerateDataPacked();
24500 	const std::vector<GLubyte>& trunks_data_pck = type.GenerateDataPacked();
24501 	const std::vector<GLubyte>& bra_data_pck	= type.GenerateDataPacked();
24502 	const std::vector<GLubyte>& gohan_data_pck  = type.GenerateDataPacked();
24503 	const std::vector<GLubyte>& goten_data_pck  = type.GenerateDataPacked();
24504 
24505 	const GLuint type_size	 = static_cast<GLuint>(chichi_data.size());
24506 	const GLuint padded_type_size	= type.GetBaseAlignment(false) * type.m_n_columns;
24507 	const GLuint type_size_pck = static_cast<GLuint>(chichi_data_pck.size());
24508 
24509 	/* Uniform data */
24510 	uniform.m_initial_data.resize(6 * padded_type_size);
24511 	memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size);
24512 	memcpy(&uniform.m_initial_data[0] + padded_type_size, &bulma_data[0], type_size);
24513 	memcpy(&uniform.m_initial_data[0] + 2 * padded_type_size, &trunks_data[0], type_size);
24514 	memcpy(&uniform.m_initial_data[0] + 3 * padded_type_size, &bra_data[0], type_size);
24515 	memcpy(&uniform.m_initial_data[0] + 4 * padded_type_size, &gohan_data[0], type_size);
24516 	memcpy(&uniform.m_initial_data[0] + 5 * padded_type_size, &goten_data[0], type_size);
24517 
24518 	/* XFB data */
24519 	xfb_1.m_initial_data.resize(3 * type_size_pck);
24520 	xfb_1.m_expected_data.resize(3 * type_size_pck);
24521 	xfb_3.m_initial_data.resize(3 * type_size_pck);
24522 	xfb_3.m_expected_data.resize(3 * type_size_pck);
24523 
24524 	for (GLuint i = 0; i < 3 * type_size_pck; ++i)
24525 	{
24526 		xfb_1.m_initial_data[i]  = (glw::GLubyte)i;
24527 		xfb_1.m_expected_data[i] = (glw::GLubyte)i;
24528 		xfb_3.m_initial_data[i]  = (glw::GLubyte)i;
24529 		xfb_3.m_expected_data[i] = (glw::GLubyte)i;
24530 	}
24531 
24532 	memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck);
24533 	memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck);
24534 	memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck);
24535 	memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck);
24536 	memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck);
24537 	memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck);
24538 }
24539 
24540 /** Source for given test case and stage
24541  *
24542  * @param test_case_index Index of test case
24543  * @param stage           Shader stage
24544  *
24545  * @return Shader source
24546  **/
24547 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24548 {
24549 	static const GLchar* fs =
24550 		"#version 430 core\n"
24551 		"#extension GL_ARB_enhanced_layouts : require\n"
24552 		"\n"
24553 		"flat in TYPE chichi;\n"
24554 		"flat in TYPE bulma;\n"
24555 		"in Vegeta {\n"
24556 		"    flat TYPE trunk;\n"
24557 		"    flat TYPE bra;\n"
24558 		"} vegeta;\n"
24559 		"in Goku {\n"
24560 		"    flat TYPE gohan;\n"
24561 		"    flat TYPE goten;\n"
24562 		"} goku;\n"
24563 		"\n"
24564 		"out vec4 fs_out;\n"
24565 		"\n"
24566 		"void main()\n"
24567 		"{\n"
24568 		"    fs_out = vec4(1);\n"
24569 		"    if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n"
24570 		"    {\n"
24571 		"        fs_out = vec4(0);\n"
24572 		"    }\n"
24573 		"}\n"
24574 		"\n";
24575 
24576 	static const GLchar* gs = "#version 430 core\n"
24577 							  "#extension GL_ARB_enhanced_layouts : require\n"
24578 							  "\n"
24579 							  "layout(points)                   in;\n"
24580 							  "layout(points, max_vertices = 1) out;\n"
24581 							  "\n"
24582 							  "INTERFACE"
24583 							  "\n"
24584 							  "void main()\n"
24585 							  "{\n"
24586 							  "ASSIGNMENTS"
24587 							  "    EmitVertex();\n"
24588 							  "}\n"
24589 							  "\n";
24590 
24591 	static const GLchar* tcs = "#version 430 core\n"
24592 							   "#extension GL_ARB_enhanced_layouts : require\n"
24593 							   "\n"
24594 							   "layout(vertices = 1) out;\n"
24595 							   "\n"
24596 							   "\n"
24597 							   "void main()\n"
24598 							   "{\n"
24599 							   "    gl_TessLevelOuter[0] = 1.0;\n"
24600 							   "    gl_TessLevelOuter[1] = 1.0;\n"
24601 							   "    gl_TessLevelOuter[2] = 1.0;\n"
24602 							   "    gl_TessLevelOuter[3] = 1.0;\n"
24603 							   "    gl_TessLevelInner[0] = 1.0;\n"
24604 							   "    gl_TessLevelInner[1] = 1.0;\n"
24605 							   "}\n"
24606 							   "\n";
24607 
24608 	static const GLchar* tes = "#version 430 core\n"
24609 							   "#extension GL_ARB_enhanced_layouts : require\n"
24610 							   "\n"
24611 							   "layout(isolines, point_mode) in;\n"
24612 							   "\n"
24613 							   "INTERFACE"
24614 							   "\n"
24615 							   "void main()\n"
24616 							   "{\n"
24617 							   "ASSIGNMENTS"
24618 							   "}\n"
24619 							   "\n";
24620 
24621 	static const GLchar* vs = "#version 430 core\n"
24622 							  "#extension GL_ARB_enhanced_layouts : require\n"
24623 							  "\n"
24624 							  "void main()\n"
24625 							  "{\n"
24626 							  "}\n"
24627 							  "\n";
24628 
24629 	static const GLchar* vs_tested = "#version 430 core\n"
24630 									 "#extension GL_ARB_enhanced_layouts : require\n"
24631 									 "\n"
24632 									 "INTERFACE"
24633 									 "\n"
24634 									 "void main()\n"
24635 									 "{\n"
24636 									 "ASSIGNMENTS"
24637 									 "}\n"
24638 									 "\n";
24639 
24640 	std::string		 source;
24641 	const _testCase& test_case = m_test_cases[test_case_index];
24642 	const GLchar*	type_name = test_case.m_type.GetGLSLTypeName();
24643 
24644 	if (test_case.m_stage == stage)
24645 	{
24646 		std::string assignments = "    chichi       = uni_chichi;\n"
24647 								  "    bulma        = uni_bulma;\n"
24648 								  "    vegeta.trunk = uni_trunk;\n"
24649 								  "    vegeta.bra   = uni_bra;\n"
24650 								  "    goku.gohan   = uni_gohan;\n"
24651 								  "    goku.goten   = uni_goten;\n";
24652 
24653 		std::string interface = "layout (xfb_buffer = 3) out;\n"
24654 								"\n"
24655 								"const uint type_size = SIZE;\n"
24656 								"\n"
24657 								"layout (                xfb_offset = 2 * type_size) flat out TYPE chichi;\n"
24658 								"layout (xfb_buffer = 1, xfb_offset = 0)             flat out TYPE bulma;\n"
24659 								"layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n"
24660 								"    flat TYPE trunk;\n"
24661 								"    flat TYPE bra;\n"
24662 								"} vegeta;\n"
24663 								"layout (                xfb_offset = 0)             out Goku {\n"
24664 								"    flat TYPE gohan;\n"
24665 								"    flat TYPE goten;\n"
24666 								"} goku;\n"
24667 								"\n"
24668 								// Uniform block must be declared with std140, otherwise each block member is not packed
24669 								"layout(binding = 0, std140) uniform block {\n"
24670 								"    TYPE uni_chichi;\n"
24671 								"    TYPE uni_bulma;\n"
24672 								"    TYPE uni_trunk;\n"
24673 								"    TYPE uni_bra;\n"
24674 								"    TYPE uni_gohan;\n"
24675 								"    TYPE uni_goten;\n"
24676 								"};\n";
24677 
24678 		/* Prepare interface string */
24679 		{
24680 			GLchar		 buffer[16];
24681 			size_t		 position  = 0;
24682 			const GLuint type_size = test_case.m_type.GetSize();
24683 
24684 			sprintf(buffer, "%d", type_size);
24685 
24686 			Utils::replaceToken("SIZE", position, buffer, interface);
24687 			Utils::replaceAllTokens("TYPE", type_name, interface);
24688 		}
24689 
24690 		switch (stage)
24691 		{
24692 		case Utils::Shader::GEOMETRY:
24693 			source = gs;
24694 			break;
24695 		case Utils::Shader::TESS_EVAL:
24696 			source = tes;
24697 			break;
24698 		case Utils::Shader::VERTEX:
24699 			source = vs_tested;
24700 			break;
24701 		default:
24702 			TCU_FAIL("Invalid enum");
24703 		}
24704 
24705 		/* Replace tokens */
24706 		{
24707 			size_t position = 0;
24708 
24709 			Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
24710 			Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
24711 		}
24712 	}
24713 	else
24714 	{
24715 		switch (test_case.m_stage)
24716 		{
24717 		case Utils::Shader::GEOMETRY:
24718 			switch (stage)
24719 			{
24720 			case Utils::Shader::FRAGMENT:
24721 				source = fs;
24722 				Utils::replaceAllTokens("TYPE", type_name, source);
24723 				break;
24724 			case Utils::Shader::VERTEX:
24725 				source = vs;
24726 				break;
24727 			default:
24728 				source = "";
24729 			}
24730 			break;
24731 		case Utils::Shader::TESS_EVAL:
24732 			switch (stage)
24733 			{
24734 			case Utils::Shader::FRAGMENT:
24735 				source = fs;
24736 				Utils::replaceAllTokens("TYPE", type_name, source);
24737 				break;
24738 			case Utils::Shader::TESS_CTRL:
24739 				source = tcs;
24740 				break;
24741 			case Utils::Shader::VERTEX:
24742 				source = vs;
24743 				break;
24744 			default:
24745 				source = "";
24746 			}
24747 			break;
24748 		case Utils::Shader::VERTEX:
24749 			switch (stage)
24750 			{
24751 			case Utils::Shader::FRAGMENT:
24752 				source = fs;
24753 				Utils::replaceAllTokens("TYPE", type_name, source);
24754 				break;
24755 			default:
24756 				source = "";
24757 			}
24758 			break;
24759 		default:
24760 			TCU_FAIL("Invalid enum");
24761 		}
24762 	}
24763 
24764 	return source;
24765 }
24766 
24767 /** Get name of test case
24768  *
24769  * @param test_case_index Index of test case
24770  *
24771  * @return Name of case
24772  **/
24773 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index)
24774 {
24775 	std::string		 name;
24776 	const _testCase& test_case = m_test_cases[test_case_index];
24777 
24778 	name = "Tested stage: ";
24779 	name.append(Utils::Shader::GetStageName(test_case.m_stage));
24780 	name.append(". Tested type: ");
24781 	name.append(test_case.m_type.GetGLSLTypeName());
24782 
24783 	return name;
24784 }
24785 
24786 /** Get number of cases
24787  *
24788  * @return Number of test cases
24789  **/
24790 GLuint XFBGlobalBufferTest::getTestCaseNumber()
24791 {
24792 	return static_cast<GLuint>(m_test_cases.size());
24793 }
24794 
24795 /** Prepare set of test cases
24796  *
24797  **/
24798 void XFBGlobalBufferTest::testInit()
24799 {
24800 	GLuint n_types = getTypesNumber();
24801 
24802 	for (GLuint i = 0; i < n_types; ++i)
24803 	{
24804 		const Utils::Type& type = getType(i);
24805 		/*
24806 		 When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will
24807 		 cause a link time error.
24808 		 */
24809 		if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 ||
24810 			strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0)
24811 		{
24812 			continue;
24813 		}
24814 		const _testCase test_cases[] = { { Utils::Shader::VERTEX, type },
24815 										 { Utils::Shader::GEOMETRY, type },
24816 										 { Utils::Shader::TESS_EVAL, type } };
24817 
24818 		m_test_cases.push_back(test_cases[0]);
24819 		m_test_cases.push_back(test_cases[1]);
24820 		m_test_cases.push_back(test_cases[2]);
24821 	}
24822 }
24823 
24824 /** Constructor
24825  *
24826  * @param context Test context
24827  **/
24828 XFBStrideTest::XFBStrideTest(deqp::Context& context)
24829 	: BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types")
24830 {
24831 	/* Nothing to be done here */
24832 }
24833 
24834 /** Execute drawArrays for single vertex
24835  *
24836  * @param test_case_index
24837  *
24838  * @return true
24839  **/
24840 bool XFBStrideTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
24841 {
24842 	const Functions& gl				= m_context.getRenderContext().getFunctions();
24843 	GLenum			 primitive_type = GL_PATCHES;
24844 	const testCase&  test_case		= m_test_cases[test_case_index];
24845 
24846 	if (Utils::Shader::VERTEX == test_case.m_stage)
24847 	{
24848 		primitive_type = GL_POINTS;
24849 	}
24850 
24851 	gl.disable(GL_RASTERIZER_DISCARD);
24852 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
24853 
24854 	gl.beginTransformFeedback(GL_POINTS);
24855 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
24856 
24857 	gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
24858 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
24859 
24860 	gl.endTransformFeedback();
24861 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
24862 
24863 	return true;
24864 }
24865 
24866 /** Get descriptors of buffers necessary for test
24867  *
24868  * @param test_case_index Index of test case
24869  * @param out_descriptors Descriptors of buffers used by test
24870  **/
24871 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24872 {
24873 	const testCase&	test_case = m_test_cases[test_case_index];
24874 	const Utils::Type& type		 = test_case.m_type;
24875 
24876 	/* Test needs single uniform and xfb */
24877 	out_descriptors.resize(2);
24878 
24879 	/* Get references */
24880 	bufferDescriptor& uniform = out_descriptors[0];
24881 	bufferDescriptor& xfb	 = out_descriptors[1];
24882 
24883 	/* Index */
24884 	uniform.m_index = 0;
24885 	xfb.m_index		= 0;
24886 
24887 	/* Target */
24888 	uniform.m_target = Utils::Buffer::Uniform;
24889 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
24890 
24891 	/* Data */
24892 	const GLuint				rand_start   = Utils::s_rand;
24893 	const std::vector<GLubyte>& uniform_data = type.GenerateData();
24894 
24895 	Utils::s_rand						 = rand_start;
24896 	const std::vector<GLubyte>& xfb_data = type.GenerateDataPacked();
24897 
24898 	const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
24899 	const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
24900 	/*
24901 	 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
24902 	 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
24903 	 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
24904 	 only one valid data should be initialized in xfb.m_expected_data
24905 	 */
24906 	const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
24907 	/* Uniform data */
24908 	uniform.m_initial_data.resize(uni_type_size);
24909 	memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
24910 
24911 	/* XFB data */
24912 	xfb.m_initial_data.resize(xfb_data_size);
24913 	xfb.m_expected_data.resize(xfb_data_size);
24914 
24915 	for (GLuint i = 0; i < xfb_data_size; ++i)
24916 	{
24917 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
24918 		xfb.m_expected_data[i] = (glw::GLubyte)i;
24919 	}
24920 
24921 	if (test_case.m_stage == Utils::Shader::VERTEX)
24922 	{
24923 		memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24924 	}
24925 	else
24926 	{
24927 		memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24928 		memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
24929 	}
24930 }
24931 
24932 /** Get body of main function for given shader stage
24933  *
24934  * @param test_case_index  Index of test case
24935  * @param stage            Shader stage
24936  * @param out_assignments  Set to empty
24937  * @param out_calculations Set to empty
24938  **/
24939 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments,
24940 								  std::string& out_calculations)
24941 {
24942 	const testCase& test_case = m_test_cases[test_case_index];
24943 
24944 	out_calculations = "";
24945 
24946 	static const GLchar* vs_tes_gs = "    goku = uni_goku;\n";
24947 	static const GLchar* fs		   = "    fs_out = vec4(1, 0.25, 0.5, 0.75);\n"
24948 							  "    if (TYPE(0) == goku)\n"
24949 							  "    {\n"
24950 							  "         fs_out = vec4(1, 0.75, 0.5, 0.5);\n"
24951 							  "    }\n";
24952 
24953 	const GLchar* assignments = "";
24954 
24955 	if (test_case.m_stage == stage)
24956 	{
24957 		switch (stage)
24958 		{
24959 		case Utils::Shader::GEOMETRY:
24960 			assignments = vs_tes_gs;
24961 			break;
24962 		case Utils::Shader::TESS_EVAL:
24963 			assignments = vs_tes_gs;
24964 			break;
24965 		case Utils::Shader::VERTEX:
24966 			assignments = vs_tes_gs;
24967 			break;
24968 		default:
24969 			TCU_FAIL("Invalid enum");
24970 		}
24971 	}
24972 	else
24973 	{
24974 		switch (stage)
24975 		{
24976 		case Utils::Shader::FRAGMENT:
24977 			assignments = fs;
24978 			break;
24979 		case Utils::Shader::GEOMETRY:
24980 		case Utils::Shader::TESS_CTRL:
24981 		case Utils::Shader::TESS_EVAL:
24982 		case Utils::Shader::VERTEX:
24983 			break;
24984 		default:
24985 			TCU_FAIL("Invalid enum");
24986 		}
24987 	}
24988 
24989 	out_assignments = assignments;
24990 
24991 	if (Utils::Shader::FRAGMENT == stage)
24992 	{
24993 		Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
24994 	}
24995 }
24996 
24997 /** Get interface of shader
24998  *
24999  * @param test_case_index  Index of test case
25000  * @param stage            Shader stage
25001  * @param out_interface    Set to ""
25002  **/
25003 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface)
25004 {
25005 	static const GLchar* vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n"
25006 									 "\n"
25007 									 "layout(std140, binding = 0) uniform Goku {\n"
25008 									 "    TYPE uni_goku;\n"
25009 									 "};\n";
25010 	static const GLchar* fs = "FLAT in TYPE goku;\n"
25011 							  "\n"
25012 							  "out vec4 fs_out;\n";
25013 
25014 	const testCase& test_case = m_test_cases[test_case_index];
25015 	const GLchar*   interface = "";
25016 	const GLchar*   flat	  = "";
25017 
25018 	if (test_case.m_stage == stage)
25019 	{
25020 		switch (stage)
25021 		{
25022 		case Utils::Shader::GEOMETRY:
25023 			interface = vs_tes_gs;
25024 			break;
25025 		case Utils::Shader::TESS_EVAL:
25026 			interface = vs_tes_gs;
25027 			break;
25028 		case Utils::Shader::VERTEX:
25029 			interface = vs_tes_gs;
25030 			break;
25031 		default:
25032 			TCU_FAIL("Invalid enum");
25033 		}
25034 	}
25035 	else
25036 	{
25037 		switch (stage)
25038 		{
25039 		case Utils::Shader::FRAGMENT:
25040 			interface = fs;
25041 			break;
25042 		case Utils::Shader::GEOMETRY:
25043 		case Utils::Shader::TESS_CTRL:
25044 		case Utils::Shader::TESS_EVAL:
25045 		case Utils::Shader::VERTEX:
25046 			break;
25047 		default:
25048 			TCU_FAIL("Invalid enum");
25049 		}
25050 	}
25051 
25052 	out_interface = interface;
25053 
25054 	if (Utils::Type::Float != test_case.m_type.m_basic_type)
25055 	{
25056 		flat = "flat";
25057 	}
25058 
25059 	Utils::replaceAllTokens("FLAT", flat, out_interface);
25060 	Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
25061 }
25062 
25063 /** Get source code of shader
25064  *
25065  * @param test_case_index Index of test case
25066  * @param stage           Shader stage
25067  *
25068  * @return Source
25069  **/
25070 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25071 {
25072 	std::string		source;
25073 	const testCase& test_case = m_test_cases[test_case_index];
25074 
25075 	switch (test_case.m_stage)
25076 	{
25077 	case Utils::Shader::VERTEX:
25078 		switch (stage)
25079 		{
25080 		case Utils::Shader::FRAGMENT:
25081 		case Utils::Shader::VERTEX:
25082 			source = BufferTestBase::getShaderSource(test_case_index, stage);
25083 			break;
25084 		default:
25085 			break;
25086 		}
25087 		break;
25088 
25089 	case Utils::Shader::TESS_EVAL:
25090 		switch (stage)
25091 		{
25092 		case Utils::Shader::FRAGMENT:
25093 		case Utils::Shader::TESS_CTRL:
25094 		case Utils::Shader::TESS_EVAL:
25095 		case Utils::Shader::VERTEX:
25096 			source = BufferTestBase::getShaderSource(test_case_index, stage);
25097 			break;
25098 		default:
25099 			break;
25100 		}
25101 		break;
25102 
25103 	case Utils::Shader::GEOMETRY:
25104 		source = BufferTestBase::getShaderSource(test_case_index, stage);
25105 		break;
25106 
25107 	default:
25108 		TCU_FAIL("Invalid enum");
25109 	}
25110 
25111 	/* */
25112 	return source;
25113 }
25114 
25115 /** Get name of test case
25116  *
25117  * @param test_case_index Index of test case
25118  *
25119  * @return Name of tested stage
25120  **/
25121 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index)
25122 {
25123 	std::stringstream stream;
25124 	const testCase&   test_case = m_test_cases[test_case_index];
25125 
25126 	stream << "Type: " << test_case.m_type.GetGLSLTypeName()
25127 		   << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25128 
25129 	return stream.str();
25130 }
25131 
25132 /** Returns number of test cases
25133  *
25134  * @return TEST_MAX
25135  **/
25136 glw::GLuint XFBStrideTest::getTestCaseNumber()
25137 {
25138 	return static_cast<GLuint>(m_test_cases.size());
25139 }
25140 
25141 /** Prepare all test cases
25142  *
25143  **/
25144 void XFBStrideTest::testInit()
25145 {
25146 	const GLuint n_types = getTypesNumber();
25147 
25148 	for (GLuint i = 0; i < n_types; ++i)
25149 	{
25150 		const Utils::Type& type = getType(i);
25151 
25152 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25153 		{
25154 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
25155 				(Utils::Shader::TESS_CTRL == stage))
25156 			{
25157 				continue;
25158 			}
25159 
25160 			testCase test_case = { (Utils::Shader::STAGES)stage, type };
25161 
25162 			m_test_cases.push_back(test_case);
25163 		}
25164 	}
25165 }
25166 
25167 /** Constructor
25168  *
25169  * @param context Test framework context
25170  **/
25171 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context& context)
25172 	: NegativeTestBase(
25173 		  context, "xfb_block_member_buffer",
25174 		  "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer")
25175 {
25176 }
25177 
25178 /** Source for given test case and stage
25179  *
25180  * @param test_case_index Index of test case
25181  * @param stage           Shader stage
25182  *
25183  * @return Shader source
25184  **/
25185 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25186 {
25187 	static const GLchar* var_definition = "layout (xfb_offset = 0) out Goku {\n"
25188 										  "                            vec4 gohan;\n"
25189 #if DEBUG_NEG_REMOVE_ERROR
25190 										  "    /* layout (xfb_buffer = 1) */ vec4 goten;\n"
25191 #else
25192 										  "    layout (xfb_buffer = 1) vec4 goten;\n"
25193 #endif /* DEBUG_NEG_REMOVE_ERROR */
25194 										  "} goku;\n";
25195 	static const GLchar* var_use = "    goku.gohan = result / 2;\n"
25196 								   "    goku.goten = result / 4;\n";
25197 	static const GLchar* fs = "#version 430 core\n"
25198 							  "#extension GL_ARB_enhanced_layouts : require\n"
25199 							  "\n"
25200 							  "in  vec4 any_fs;\n"
25201 							  "out vec4 fs_out;\n"
25202 							  "\n"
25203 							  "void main()\n"
25204 							  "{\n"
25205 							  "    fs_out = any_fs;\n"
25206 							  "}\n"
25207 							  "\n";
25208 	static const GLchar* gs_tested = "#version 430 core\n"
25209 									 "#extension GL_ARB_enhanced_layouts : require\n"
25210 									 "\n"
25211 									 "layout(points)                           in;\n"
25212 									 "layout(triangle_strip, max_vertices = 4) out;\n"
25213 									 "\n"
25214 									 "VAR_DEFINITION"
25215 									 "\n"
25216 									 "in  vec4 vs_any[];\n"
25217 									 "out vec4 any_fs;\n"
25218 									 "\n"
25219 									 "void main()\n"
25220 									 "{\n"
25221 									 "    vec4 result = vs_any[0];\n"
25222 									 "\n"
25223 									 "VARIABLE_USE"
25224 									 "\n"
25225 									 "    any_fs = result;\n"
25226 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
25227 									 "    EmitVertex();\n"
25228 									 "    any_fs = result;\n"
25229 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
25230 									 "    EmitVertex();\n"
25231 									 "    any_fs = result;\n"
25232 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
25233 									 "    EmitVertex();\n"
25234 									 "    any_fs = result;\n"
25235 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
25236 									 "    EmitVertex();\n"
25237 									 "}\n"
25238 									 "\n";
25239 	static const GLchar* tcs = "#version 430 core\n"
25240 							   "#extension GL_ARB_enhanced_layouts : require\n"
25241 							   "\n"
25242 							   "layout(vertices = 1) out;\n"
25243 							   "\n"
25244 							   "in  vec4 vs_any[];\n"
25245 							   "out vec4 tcs_tes[];\n"
25246 							   "\n"
25247 							   "void main()\n"
25248 							   "{\n"
25249 							   "\n"
25250 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
25251 							   "\n"
25252 							   "    gl_TessLevelOuter[0] = 1.0;\n"
25253 							   "    gl_TessLevelOuter[1] = 1.0;\n"
25254 							   "    gl_TessLevelOuter[2] = 1.0;\n"
25255 							   "    gl_TessLevelOuter[3] = 1.0;\n"
25256 							   "    gl_TessLevelInner[0] = 1.0;\n"
25257 							   "    gl_TessLevelInner[1] = 1.0;\n"
25258 							   "}\n"
25259 							   "\n";
25260 	static const GLchar* tes_tested = "#version 430 core\n"
25261 									  "#extension GL_ARB_enhanced_layouts : require\n"
25262 									  "\n"
25263 									  "layout(isolines, point_mode) in;\n"
25264 									  "\n"
25265 									  "VAR_DEFINITION"
25266 									  "\n"
25267 									  "in  vec4 tcs_tes[];\n"
25268 									  "out vec4 any_fs;\n"
25269 									  "\n"
25270 									  "void main()\n"
25271 									  "{\n"
25272 									  "    vec4 result = tcs_tes[0];\n"
25273 									  "\n"
25274 									  "VARIABLE_USE"
25275 									  "\n"
25276 									  "    any_fs += result;\n"
25277 									  "}\n"
25278 									  "\n";
25279 	static const GLchar* vs = "#version 430 core\n"
25280 							  "#extension GL_ARB_enhanced_layouts : require\n"
25281 							  "\n"
25282 							  "in  vec4 in_vs;\n"
25283 							  "out vec4 vs_any;\n"
25284 							  "\n"
25285 							  "void main()\n"
25286 							  "{\n"
25287 							  "    vs_any = in_vs;\n"
25288 							  "}\n"
25289 							  "\n";
25290 	static const GLchar* vs_tested = "#version 430 core\n"
25291 									 "#extension GL_ARB_enhanced_layouts : require\n"
25292 									 "\n"
25293 									 "VAR_DEFINITION"
25294 									 "\n"
25295 									 "in  vec4 in_vs;\n"
25296 									 "out vec4 any_fs;\n"
25297 									 "\n"
25298 									 "void main()\n"
25299 									 "{\n"
25300 									 "    vec4 result = in_vs;\n"
25301 									 "\n"
25302 									 "VARIABLE_USE"
25303 									 "\n"
25304 									 "    any_fs = result;\n"
25305 									 "}\n"
25306 									 "\n";
25307 
25308 	std::string source;
25309 	testCase&   test_case = m_test_cases[test_case_index];
25310 
25311 	if (test_case.m_stage == stage)
25312 	{
25313 		size_t		  position = 0;
25314 
25315 		switch (stage)
25316 		{
25317 		case Utils::Shader::GEOMETRY:
25318 			source = gs_tested;
25319 			break;
25320 		case Utils::Shader::TESS_EVAL:
25321 			source = tes_tested;
25322 			break;
25323 		case Utils::Shader::VERTEX:
25324 			source = vs_tested;
25325 			break;
25326 		default:
25327 			TCU_FAIL("Invalid enum");
25328 		}
25329 
25330 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25331 		position = 0;
25332 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25333 	}
25334 	else
25335 	{
25336 		switch (test_case.m_stage)
25337 		{
25338 		case Utils::Shader::GEOMETRY:
25339 			switch (stage)
25340 			{
25341 			case Utils::Shader::FRAGMENT:
25342 				source = fs;
25343 				break;
25344 			case Utils::Shader::VERTEX:
25345 				source = vs;
25346 				break;
25347 			default:
25348 				source = "";
25349 			}
25350 			break;
25351 		case Utils::Shader::TESS_EVAL:
25352 			switch (stage)
25353 			{
25354 			case Utils::Shader::FRAGMENT:
25355 				source = fs;
25356 				break;
25357 			case Utils::Shader::TESS_CTRL:
25358 				source = tcs;
25359 				break;
25360 			case Utils::Shader::VERTEX:
25361 				source = vs;
25362 				break;
25363 			default:
25364 				source = "";
25365 			}
25366 			break;
25367 		case Utils::Shader::VERTEX:
25368 			switch (stage)
25369 			{
25370 			case Utils::Shader::FRAGMENT:
25371 				source = fs;
25372 				break;
25373 			default:
25374 				source = "";
25375 			}
25376 			break;
25377 		default:
25378 			TCU_FAIL("Invalid enum");
25379 		}
25380 	}
25381 
25382 	return source;
25383 }
25384 
25385 /** Get description of test case
25386  *
25387  * @param test_case_index Index of test case
25388  *
25389  * @return Test case description
25390  **/
25391 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index)
25392 {
25393 	std::stringstream stream;
25394 	testCase&		  test_case = m_test_cases[test_case_index];
25395 
25396 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25397 
25398 	return stream.str();
25399 }
25400 
25401 /** Get number of test cases
25402  *
25403  * @return Number of test cases
25404  **/
25405 GLuint XFBBlockMemberBufferTest::getTestCaseNumber()
25406 {
25407 	return static_cast<GLuint>(m_test_cases.size());
25408 }
25409 
25410 /** Selects if "compute" stage is relevant for test
25411  *
25412  * @param ignored
25413  *
25414  * @return false
25415  **/
25416 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */)
25417 {
25418 	return false;
25419 }
25420 
25421 /** Prepare all test cases
25422  *
25423  **/
25424 void XFBBlockMemberBufferTest::testInit()
25425 {
25426 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25427 	{
25428 		if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25429 			(Utils::Shader::FRAGMENT == stage))
25430 		{
25431 			continue;
25432 		}
25433 
25434 		testCase test_case = { (Utils::Shader::STAGES)stage };
25435 
25436 		m_test_cases.push_back(test_case);
25437 	}
25438 }
25439 
25440 /** Constructor
25441  *
25442  * @param context Test framework context
25443  **/
25444 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context& context)
25445 	: NegativeTestBase(context, "xfb_output_overlapping",
25446 					   "Test verifies that compiler reports error when two xfb qualified outputs overlap")
25447 {
25448 }
25449 
25450 /** Source for given test case and stage
25451  *
25452  * @param test_case_index Index of test case
25453  * @param stage           Shader stage
25454  *
25455  * @return Shader source
25456  **/
25457 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25458 {
25459 	static const GLchar* var_definition = "layout (xfb_offset = 0) out TYPE gohan;\n"
25460 #if DEBUG_NEG_REMOVE_ERROR
25461 										  "/* layout (xfb_offset = OFFSET) */ out TYPE goten;\n";
25462 #else
25463 										  "layout (xfb_offset = OFFSET) out TYPE goten;\n";
25464 #endif /* DEBUG_NEG_REMOVE_ERROR */
25465 	static const GLchar* var_use = "    gohan = TYPE(0);\n"
25466 								   "    goten = TYPE(1);\n"
25467 								   "    if (vec4(0) == result)\n"
25468 								   "    {\n"
25469 								   "        gohan = TYPE(1);\n"
25470 								   "        goten = TYPE(0);\n"
25471 								   "    }\n";
25472 	static const GLchar* fs = "#version 430 core\n"
25473 							  "#extension GL_ARB_enhanced_layouts : require\n"
25474 							  "\n"
25475 							  "in  vec4 any_fs;\n"
25476 							  "out vec4 fs_out;\n"
25477 							  "\n"
25478 							  "void main()\n"
25479 							  "{\n"
25480 							  "    fs_out = any_fs;\n"
25481 							  "}\n"
25482 							  "\n";
25483 	static const GLchar* gs_tested = "#version 430 core\n"
25484 									 "#extension GL_ARB_enhanced_layouts : require\n"
25485 									 "\n"
25486 									 "layout(points)                           in;\n"
25487 									 "layout(triangle_strip, max_vertices = 4) out;\n"
25488 									 "\n"
25489 									 "VAR_DEFINITION"
25490 									 "\n"
25491 									 "in  vec4 vs_any[];\n"
25492 									 "out vec4 any_fs;\n"
25493 									 "\n"
25494 									 "void main()\n"
25495 									 "{\n"
25496 									 "    vec4 result = vs_any[0];\n"
25497 									 "\n"
25498 									 "VARIABLE_USE"
25499 									 "\n"
25500 									 "    any_fs = result;\n"
25501 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
25502 									 "    EmitVertex();\n"
25503 									 "    any_fs = result;\n"
25504 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
25505 									 "    EmitVertex();\n"
25506 									 "    any_fs = result;\n"
25507 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
25508 									 "    EmitVertex();\n"
25509 									 "    any_fs = result;\n"
25510 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
25511 									 "    EmitVertex();\n"
25512 									 "}\n"
25513 									 "\n";
25514 	static const GLchar* tcs = "#version 430 core\n"
25515 							   "#extension GL_ARB_enhanced_layouts : require\n"
25516 							   "\n"
25517 							   "layout(vertices = 1) out;\n"
25518 							   "\n"
25519 							   "in  vec4 vs_any[];\n"
25520 							   "out vec4 tcs_tes[];\n"
25521 							   "\n"
25522 							   "void main()\n"
25523 							   "{\n"
25524 							   "\n"
25525 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
25526 							   "\n"
25527 							   "    gl_TessLevelOuter[0] = 1.0;\n"
25528 							   "    gl_TessLevelOuter[1] = 1.0;\n"
25529 							   "    gl_TessLevelOuter[2] = 1.0;\n"
25530 							   "    gl_TessLevelOuter[3] = 1.0;\n"
25531 							   "    gl_TessLevelInner[0] = 1.0;\n"
25532 							   "    gl_TessLevelInner[1] = 1.0;\n"
25533 							   "}\n"
25534 							   "\n";
25535 	static const GLchar* tes_tested = "#version 430 core\n"
25536 									  "#extension GL_ARB_enhanced_layouts : require\n"
25537 									  "\n"
25538 									  "layout(isolines, point_mode) in;\n"
25539 									  "\n"
25540 									  "VAR_DEFINITION"
25541 									  "\n"
25542 									  "in  vec4 tcs_tes[];\n"
25543 									  "out vec4 any_fs;\n"
25544 									  "\n"
25545 									  "void main()\n"
25546 									  "{\n"
25547 									  "    vec4 result = tcs_tes[0];\n"
25548 									  "\n"
25549 									  "VARIABLE_USE"
25550 									  "\n"
25551 									  "    any_fs += result;\n"
25552 									  "}\n"
25553 									  "\n";
25554 	static const GLchar* vs = "#version 430 core\n"
25555 							  "#extension GL_ARB_enhanced_layouts : require\n"
25556 							  "\n"
25557 							  "in  vec4 in_vs;\n"
25558 							  "out vec4 vs_any;\n"
25559 							  "\n"
25560 							  "void main()\n"
25561 							  "{\n"
25562 							  "    vs_any = in_vs;\n"
25563 							  "}\n"
25564 							  "\n";
25565 	static const GLchar* vs_tested = "#version 430 core\n"
25566 									 "#extension GL_ARB_enhanced_layouts : require\n"
25567 									 "\n"
25568 									 "VAR_DEFINITION"
25569 									 "\n"
25570 									 "in  vec4 in_vs;\n"
25571 									 "out vec4 any_fs;\n"
25572 									 "\n"
25573 									 "void main()\n"
25574 									 "{\n"
25575 									 "    vec4 result = in_vs;\n"
25576 									 "\n"
25577 									 "VARIABLE_USE"
25578 									 "\n"
25579 									 "    any_fs = result;\n"
25580 									 "}\n"
25581 									 "\n";
25582 
25583 	std::string source;
25584 	testCase&   test_case = m_test_cases[test_case_index];
25585 
25586 	if (test_case.m_stage == stage)
25587 	{
25588 		GLchar		  offset[16];
25589 		size_t		  position		 = 0;
25590 		const GLchar* type_name		 = test_case.m_type.GetGLSLTypeName();
25591 
25592 		sprintf(offset, "%d", test_case.m_offset);
25593 
25594 		switch (stage)
25595 		{
25596 		case Utils::Shader::GEOMETRY:
25597 			source = gs_tested;
25598 			break;
25599 		case Utils::Shader::TESS_EVAL:
25600 			source = tes_tested;
25601 			break;
25602 		case Utils::Shader::VERTEX:
25603 			source = vs_tested;
25604 			break;
25605 		default:
25606 			TCU_FAIL("Invalid enum");
25607 		}
25608 
25609 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25610 		position = 0;
25611 		Utils::replaceToken("OFFSET", position, offset, source);
25612 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25613 
25614 		Utils::replaceAllTokens("TYPE", type_name, source);
25615 	}
25616 	else
25617 	{
25618 		switch (test_case.m_stage)
25619 		{
25620 		case Utils::Shader::GEOMETRY:
25621 			switch (stage)
25622 			{
25623 			case Utils::Shader::FRAGMENT:
25624 				source = fs;
25625 				break;
25626 			case Utils::Shader::VERTEX:
25627 				source = vs;
25628 				break;
25629 			default:
25630 				source = "";
25631 			}
25632 			break;
25633 		case Utils::Shader::TESS_EVAL:
25634 			switch (stage)
25635 			{
25636 			case Utils::Shader::FRAGMENT:
25637 				source = fs;
25638 				break;
25639 			case Utils::Shader::TESS_CTRL:
25640 				source = tcs;
25641 				break;
25642 			case Utils::Shader::VERTEX:
25643 				source = vs;
25644 				break;
25645 			default:
25646 				source = "";
25647 			}
25648 			break;
25649 		case Utils::Shader::VERTEX:
25650 			switch (stage)
25651 			{
25652 			case Utils::Shader::FRAGMENT:
25653 				source = fs;
25654 				break;
25655 			default:
25656 				source = "";
25657 			}
25658 			break;
25659 		default:
25660 			TCU_FAIL("Invalid enum");
25661 		}
25662 	}
25663 
25664 	return source;
25665 }
25666 
25667 /** Get description of test case
25668  *
25669  * @param test_case_index Index of test case
25670  *
25671  * @return Test case description
25672  **/
25673 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index)
25674 {
25675 	std::stringstream stream;
25676 	testCase&		  test_case = m_test_cases[test_case_index];
25677 
25678 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25679 		   << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25680 
25681 	return stream.str();
25682 }
25683 
25684 /** Get number of test cases
25685  *
25686  * @return Number of test cases
25687  **/
25688 GLuint XFBOutputOverlappingTest::getTestCaseNumber()
25689 {
25690 	return static_cast<GLuint>(m_test_cases.size());
25691 }
25692 
25693 /** Selects if "compute" stage is relevant for test
25694  *
25695  * @param ignored
25696  *
25697  * @return false
25698  **/
25699 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */)
25700 {
25701 	return false;
25702 }
25703 
25704 /** Prepare all test cases
25705  *
25706  **/
25707 void XFBOutputOverlappingTest::testInit()
25708 {
25709 	const GLuint n_types = getTypesNumber();
25710 
25711 	for (GLuint i = 0; i < n_types; ++i)
25712 	{
25713 		const Utils::Type& type			  = getType(i);
25714 		const GLuint	   basic_type_size = Utils::Type::GetTypeSize(type.m_basic_type);
25715 
25716 		/* Skip scalars, not applicable as:
25717 		 *
25718 		 *     The offset must be a multiple of the size of the first component of the first
25719 		 *     qualified variable or block member, or a compile-time error results.
25720 		 */
25721 		if ((1 == type.m_n_columns) && (1 == type.m_n_rows))
25722 		{
25723 			continue;
25724 		}
25725 
25726 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25727 		{
25728 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25729 				(Utils::Shader::FRAGMENT == stage))
25730 			{
25731 				continue;
25732 			}
25733 
25734 			testCase test_case = { basic_type_size /* offset */, (Utils::Shader::STAGES)stage, type };
25735 
25736 			m_test_cases.push_back(test_case);
25737 		}
25738 	}
25739 }
25740 
25741 /** Constructor
25742  *
25743  * @param context Test framework context
25744  **/
25745 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context& context)
25746 	: NegativeTestBase(context, "xfb_invalid_offset_alignment",
25747 					   "Test verifies that compiler reports error when xfb_offset has invalid alignment")
25748 {
25749 }
25750 
25751 /** Source for given test case and stage
25752  *
25753  * @param test_case_index Index of test case
25754  * @param stage           Shader stage
25755  *
25756  * @return Shader source
25757  **/
25758 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25759 {
25760 #if DEBUG_NEG_REMOVE_ERROR
25761 	static const GLchar* var_definition = "/* layout (xfb_offset = OFFSET) */ out TYPE gohan;\n";
25762 #else
25763 	static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohan;\n";
25764 #endif /* DEBUG_NEG_REMOVE_ERROR */
25765 	static const GLchar* var_use = "    gohan = TYPE(0);\n"
25766 								   "    if (vec4(0) == result)\n"
25767 								   "    {\n"
25768 								   "        gohan = TYPE(1);\n"
25769 								   "    }\n";
25770 	static const GLchar* fs = "#version 430 core\n"
25771 							  "#extension GL_ARB_enhanced_layouts : require\n"
25772 							  "\n"
25773 							  "in  vec4 any_fs;\n"
25774 							  "out vec4 fs_out;\n"
25775 							  "\n"
25776 							  "void main()\n"
25777 							  "{\n"
25778 							  "    fs_out = any_fs;\n"
25779 							  "}\n"
25780 							  "\n";
25781 	static const GLchar* gs_tested = "#version 430 core\n"
25782 									 "#extension GL_ARB_enhanced_layouts : require\n"
25783 									 "\n"
25784 									 "layout(points)                           in;\n"
25785 									 "layout(triangle_strip, max_vertices = 4) out;\n"
25786 									 "\n"
25787 									 "VAR_DEFINITION"
25788 									 "\n"
25789 									 "in  vec4 vs_any[];\n"
25790 									 "out vec4 any_fs;\n"
25791 									 "\n"
25792 									 "void main()\n"
25793 									 "{\n"
25794 									 "    vec4 result = vs_any[0];\n"
25795 									 "\n"
25796 									 "VARIABLE_USE"
25797 									 "\n"
25798 									 "    any_fs = result;\n"
25799 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
25800 									 "    EmitVertex();\n"
25801 									 "    any_fs = result;\n"
25802 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
25803 									 "    EmitVertex();\n"
25804 									 "    any_fs = result;\n"
25805 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
25806 									 "    EmitVertex();\n"
25807 									 "    any_fs = result;\n"
25808 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
25809 									 "    EmitVertex();\n"
25810 									 "}\n"
25811 									 "\n";
25812 	static const GLchar* tcs = "#version 430 core\n"
25813 							   "#extension GL_ARB_enhanced_layouts : require\n"
25814 							   "\n"
25815 							   "layout(vertices = 1) out;\n"
25816 							   "\n"
25817 							   "in  vec4 vs_any[];\n"
25818 							   "out vec4 tcs_tes[];\n"
25819 							   "\n"
25820 							   "void main()\n"
25821 							   "{\n"
25822 							   "\n"
25823 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
25824 							   "\n"
25825 							   "    gl_TessLevelOuter[0] = 1.0;\n"
25826 							   "    gl_TessLevelOuter[1] = 1.0;\n"
25827 							   "    gl_TessLevelOuter[2] = 1.0;\n"
25828 							   "    gl_TessLevelOuter[3] = 1.0;\n"
25829 							   "    gl_TessLevelInner[0] = 1.0;\n"
25830 							   "    gl_TessLevelInner[1] = 1.0;\n"
25831 							   "}\n"
25832 							   "\n";
25833 	static const GLchar* tes_tested = "#version 430 core\n"
25834 									  "#extension GL_ARB_enhanced_layouts : require\n"
25835 									  "\n"
25836 									  "layout(isolines, point_mode) in;\n"
25837 									  "\n"
25838 									  "VAR_DEFINITION"
25839 									  "\n"
25840 									  "in  vec4 tcs_tes[];\n"
25841 									  "out vec4 any_fs;\n"
25842 									  "\n"
25843 									  "void main()\n"
25844 									  "{\n"
25845 									  "    vec4 result = tcs_tes[0];\n"
25846 									  "\n"
25847 									  "VARIABLE_USE"
25848 									  "\n"
25849 									  "    any_fs += result;\n"
25850 									  "}\n"
25851 									  "\n";
25852 	static const GLchar* vs = "#version 430 core\n"
25853 							  "#extension GL_ARB_enhanced_layouts : require\n"
25854 							  "\n"
25855 							  "in  vec4 in_vs;\n"
25856 							  "out vec4 vs_any;\n"
25857 							  "\n"
25858 							  "void main()\n"
25859 							  "{\n"
25860 							  "    vs_any = in_vs;\n"
25861 							  "}\n"
25862 							  "\n";
25863 	static const GLchar* vs_tested = "#version 430 core\n"
25864 									 "#extension GL_ARB_enhanced_layouts : require\n"
25865 									 "\n"
25866 									 "VAR_DEFINITION"
25867 									 "\n"
25868 									 "in  vec4 in_vs;\n"
25869 									 "out vec4 any_fs;\n"
25870 									 "\n"
25871 									 "void main()\n"
25872 									 "{\n"
25873 									 "    vec4 result = in_vs;\n"
25874 									 "\n"
25875 									 "VARIABLE_USE"
25876 									 "\n"
25877 									 "    any_fs = result;\n"
25878 									 "}\n"
25879 									 "\n";
25880 
25881 	std::string source;
25882 	testCase&   test_case = m_test_cases[test_case_index];
25883 
25884 	if (test_case.m_stage == stage)
25885 	{
25886 		GLchar		  offset[16];
25887 		size_t		  position		 = 0;
25888 		const GLchar* type_name		 = test_case.m_type.GetGLSLTypeName();
25889 
25890 		sprintf(offset, "%d", test_case.m_offset);
25891 
25892 		switch (stage)
25893 		{
25894 		case Utils::Shader::GEOMETRY:
25895 			source = gs_tested;
25896 			break;
25897 		case Utils::Shader::TESS_EVAL:
25898 			source = tes_tested;
25899 			break;
25900 		case Utils::Shader::VERTEX:
25901 			source = vs_tested;
25902 			break;
25903 		default:
25904 			TCU_FAIL("Invalid enum");
25905 		}
25906 
25907 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25908 		position = 0;
25909 		Utils::replaceToken("OFFSET", position, offset, source);
25910 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25911 
25912 		Utils::replaceAllTokens("TYPE", type_name, source);
25913 	}
25914 	else
25915 	{
25916 		switch (test_case.m_stage)
25917 		{
25918 		case Utils::Shader::GEOMETRY:
25919 			switch (stage)
25920 			{
25921 			case Utils::Shader::FRAGMENT:
25922 				source = fs;
25923 				break;
25924 			case Utils::Shader::VERTEX:
25925 				source = vs;
25926 				break;
25927 			default:
25928 				source = "";
25929 			}
25930 			break;
25931 		case Utils::Shader::TESS_EVAL:
25932 			switch (stage)
25933 			{
25934 			case Utils::Shader::FRAGMENT:
25935 				source = fs;
25936 				break;
25937 			case Utils::Shader::TESS_CTRL:
25938 				source = tcs;
25939 				break;
25940 			case Utils::Shader::VERTEX:
25941 				source = vs;
25942 				break;
25943 			default:
25944 				source = "";
25945 			}
25946 			break;
25947 		case Utils::Shader::VERTEX:
25948 			switch (stage)
25949 			{
25950 			case Utils::Shader::FRAGMENT:
25951 				source = fs;
25952 				break;
25953 			default:
25954 				source = "";
25955 			}
25956 			break;
25957 		default:
25958 			TCU_FAIL("Invalid enum");
25959 		}
25960 	}
25961 
25962 	return source;
25963 }
25964 
25965 /** Get description of test case
25966  *
25967  * @param test_case_index Index of test case
25968  *
25969  * @return Test case description
25970  **/
25971 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
25972 {
25973 	std::stringstream stream;
25974 	testCase&		  test_case = m_test_cases[test_case_index];
25975 
25976 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25977 		   << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25978 
25979 	return stream.str();
25980 }
25981 
25982 /** Get number of test cases
25983  *
25984  * @return Number of test cases
25985  **/
25986 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber()
25987 {
25988 	return static_cast<GLuint>(m_test_cases.size());
25989 }
25990 
25991 /** Selects if "compute" stage is relevant for test
25992  *
25993  * @param ignored
25994  *
25995  * @return false
25996  **/
25997 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */)
25998 {
25999 	return false;
26000 }
26001 
26002 /** Prepare all test cases
26003  *
26004  **/
26005 void XFBInvalidOffsetAlignmentTest::testInit()
26006 {
26007 	const GLuint n_types = getTypesNumber();
26008 
26009 	for (GLuint i = 0; i < n_types; ++i)
26010 	{
26011 		const Utils::Type& type			  = getType(i);
26012 		const GLuint	   basic_type_size = Utils::Type::GetTypeSize(type.m_basic_type);
26013 
26014 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
26015 		{
26016 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
26017 				(Utils::Shader::FRAGMENT == stage))
26018 			{
26019 				continue;
26020 			}
26021 
26022 			for (GLuint offset = basic_type_size + 1; offset < 2 * basic_type_size; ++offset)
26023 			{
26024 				testCase test_case = { offset, (Utils::Shader::STAGES)stage, type };
26025 
26026 				m_test_cases.push_back(test_case);
26027 			}
26028 		}
26029 	}
26030 }
26031 
26032 /** Constructor
26033  *
26034  * @param context Test context
26035  **/
26036 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context& context)
26037 	: BufferTestBase(context, "xfb_capture_inactive_output_variable",
26038 					 "Test verifies that inactive variables are captured")
26039 {
26040 	/* Nothing to be done here */
26041 }
26042 
26043 /** Execute drawArrays for single vertex
26044  *
26045  * @param test_case_index
26046  *
26047  * @return true
26048  **/
26049 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26050 {
26051 	const Functions& gl				= m_context.getRenderContext().getFunctions();
26052 	GLenum			 primitive_type = GL_PATCHES;
26053 
26054 	if (TEST_VS == test_case_index)
26055 	{
26056 		primitive_type = GL_POINTS;
26057 	}
26058 
26059 	gl.disable(GL_RASTERIZER_DISCARD);
26060 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26061 
26062 	gl.beginTransformFeedback(GL_POINTS);
26063 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26064 
26065 	gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26066 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26067 
26068 	gl.endTransformFeedback();
26069 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26070 
26071 	return true;
26072 }
26073 
26074 /** Get descriptors of buffers necessary for test
26075  *
26076  * @param ignored
26077  * @param out_descriptors Descriptors of buffers used by test
26078  **/
26079 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26080 																bufferDescriptor::Vector& out_descriptors)
26081 {
26082 	const Utils::Type& type = Utils::Type::vec4;
26083 
26084 	/* Test needs single uniform and xfb */
26085 	out_descriptors.resize(2);
26086 
26087 	/* Get references */
26088 	bufferDescriptor& uniform = out_descriptors[0];
26089 	bufferDescriptor& xfb	 = out_descriptors[1];
26090 
26091 	/* Index */
26092 	uniform.m_index = 0;
26093 	xfb.m_index		= 0;
26094 
26095 	/* Target */
26096 	uniform.m_target = Utils::Buffer::Uniform;
26097 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
26098 
26099 	/* Data */
26100 	const std::vector<GLubyte>& gohan_data = type.GenerateData();
26101 	const std::vector<GLubyte>& goten_data = type.GenerateData();
26102 
26103 	const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26104 
26105 	/* Uniform data */
26106 	uniform.m_initial_data.resize(2 * type_size);
26107 	memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26108 	memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size);
26109 
26110 	/* XFB data */
26111 	xfb.m_initial_data.resize(3 * type_size);
26112 	xfb.m_expected_data.resize(3 * type_size);
26113 
26114 	for (GLuint i = 0; i < 3 * type_size; ++i)
26115 	{
26116 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
26117 		xfb.m_expected_data[i] = (glw::GLubyte)i;
26118 	}
26119 
26120 	memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size);
26121 	memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size);
26122 }
26123 
26124 /** Get body of main function for given shader stage
26125  *
26126  * @param test_case_index  Index of test case
26127  * @param stage            Shader stage
26128  * @param out_assignments  Set to empty
26129  * @param out_calculations Set to empty
26130  **/
26131 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26132 														 std::string& out_assignments, std::string& out_calculations)
26133 {
26134 	out_calculations = "";
26135 
26136 	static const GLchar* vs_tes_gs = "    goten = uni_goten;\n"
26137 									 "    gohan = uni_gohan;\n";
26138 	static const GLchar* fs = "    fs_out = goku + gohan + goten;\n";
26139 
26140 	const GLchar* assignments = "";
26141 
26142 	switch (stage)
26143 	{
26144 	case Utils::Shader::FRAGMENT:
26145 		assignments = fs;
26146 		break;
26147 
26148 	case Utils::Shader::GEOMETRY:
26149 		if (TEST_GS == test_case_index)
26150 		{
26151 			assignments = vs_tes_gs;
26152 		}
26153 		break;
26154 
26155 	case Utils::Shader::TESS_CTRL:
26156 		break;
26157 
26158 	case Utils::Shader::TESS_EVAL:
26159 		if (TEST_TES == test_case_index)
26160 		{
26161 			assignments = vs_tes_gs;
26162 		}
26163 		break;
26164 
26165 	case Utils::Shader::VERTEX:
26166 		if (TEST_VS == test_case_index)
26167 		{
26168 			assignments = vs_tes_gs;
26169 		}
26170 		break;
26171 
26172 	default:
26173 		TCU_FAIL("Invalid enum");
26174 	}
26175 
26176 	out_assignments = assignments;
26177 }
26178 
26179 /** Get interface of shader
26180  *
26181  * @param test_case_index  Index of test case
26182  * @param stage            Shader stage
26183  * @param out_interface    Set to ""
26184  **/
26185 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26186 															  std::string& out_interface)
26187 {
26188 	static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26189 									 "\n"
26190 									 "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n"
26191 									 "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n"
26192 									 "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n"
26193 									 "\n"
26194 									 "layout(binding = 0) uniform block {\n"
26195 									 "    vec4 uni_gohan;\n"
26196 									 "    vec4 uni_goten;\n"
26197 									 "};\n";
26198 	static const GLchar* fs = "in vec4 goku;\n"
26199 							  "in vec4 gohan;\n"
26200 							  "in vec4 goten;\n"
26201 							  "out vec4 fs_out;\n";
26202 
26203 	const GLchar* interface = "";
26204 
26205 	switch (stage)
26206 	{
26207 	case Utils::Shader::FRAGMENT:
26208 		interface = fs;
26209 		break;
26210 
26211 	case Utils::Shader::GEOMETRY:
26212 		if (TEST_GS == test_case_index)
26213 		{
26214 			interface = vs_tes_gs;
26215 		}
26216 		break;
26217 
26218 	case Utils::Shader::TESS_CTRL:
26219 		break;
26220 
26221 	case Utils::Shader::TESS_EVAL:
26222 		if (TEST_TES == test_case_index)
26223 		{
26224 			interface = vs_tes_gs;
26225 		}
26226 		break;
26227 
26228 	case Utils::Shader::VERTEX:
26229 		if (TEST_VS == test_case_index)
26230 		{
26231 			interface = vs_tes_gs;
26232 		}
26233 		break;
26234 
26235 	default:
26236 		TCU_FAIL("Invalid enum");
26237 	}
26238 
26239 	out_interface = interface;
26240 }
26241 
26242 /** Get source code of shader
26243  *
26244  * @param test_case_index Index of test case
26245  * @param stage           Shader stage
26246  *
26247  * @return Source
26248  **/
26249 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26250 {
26251 	std::string source;
26252 
26253 	switch (test_case_index)
26254 	{
26255 	case TEST_VS:
26256 		switch (stage)
26257 		{
26258 		case Utils::Shader::FRAGMENT:
26259 		case Utils::Shader::VERTEX:
26260 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26261 			break;
26262 		default:
26263 			break;
26264 		}
26265 		break;
26266 
26267 	case TEST_TES:
26268 		switch (stage)
26269 		{
26270 		case Utils::Shader::FRAGMENT:
26271 		case Utils::Shader::TESS_CTRL:
26272 		case Utils::Shader::TESS_EVAL:
26273 		case Utils::Shader::VERTEX:
26274 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26275 			break;
26276 		default:
26277 			break;
26278 		}
26279 		break;
26280 
26281 	case TEST_GS:
26282 		source = BufferTestBase::getShaderSource(test_case_index, stage);
26283 		break;
26284 
26285 	default:
26286 		TCU_FAIL("Invalid enum");
26287 	}
26288 
26289 	/* */
26290 	return source;
26291 }
26292 
26293 /** Get name of test case
26294  *
26295  * @param test_case_index Index of test case
26296  *
26297  * @return Name of tested stage
26298  **/
26299 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index)
26300 {
26301 	const GLchar* name = 0;
26302 
26303 	switch (test_case_index)
26304 	{
26305 	case TEST_VS:
26306 		name = "vertex";
26307 		break;
26308 	case TEST_TES:
26309 		name = "tessellation evaluation";
26310 		break;
26311 	case TEST_GS:
26312 		name = "geometry";
26313 		break;
26314 	default:
26315 		TCU_FAIL("Invalid enum");
26316 	}
26317 
26318 	return name;
26319 }
26320 
26321 /** Returns number of test cases
26322  *
26323  * @return TEST_MAX
26324  **/
26325 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber()
26326 {
26327 	return TEST_MAX;
26328 }
26329 
26330 /** Inspects program to check if all resources are as expected
26331  *
26332  * @param ignored
26333  * @param program         Program instance
26334  * @param out_stream      Error message
26335  *
26336  * @return true if everything is ok, false otherwise
26337  **/
26338 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program& program,
26339 														  std::stringstream& out_stream)
26340 {
26341 	GLint			   stride	= 0;
26342 	const Utils::Type& type		 = Utils::Type::vec4;
26343 	const GLuint	   type_size = type.GetSize();
26344 
26345 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
26346 						1 /* buf_size */, &stride);
26347 
26348 	if ((GLint)(3 * type_size) != stride)
26349 	{
26350 		out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
26351 
26352 		return false;
26353 	}
26354 
26355 	return true;
26356 }
26357 
26358 /** Verify contents of buffers
26359  *
26360  * @param buffers Collection of buffers to be verified
26361  *
26362  * @return true if everything is as expected, false otherwise
26363  **/
26364 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection& buffers)
26365 {
26366 	bool result = true;
26367 
26368 	bufferCollection::pair& pair	   = buffers.m_vector[1] /* xfb */;
26369 	Utils::Buffer*			buffer	 = pair.m_buffer;
26370 	bufferDescriptor*		descriptor = pair.m_descriptor;
26371 
26372 	/* Get pointer to contents of buffer */
26373 	buffer->Bind();
26374 	GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26375 
26376 	/* Get pointer to expected data */
26377 	GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26378 
26379 	/* Compare */
26380 	static const GLuint vec4_size = 16;
26381 
26382 	int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size);
26383 	int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size);
26384 
26385 	if ((0 != res_gohan) || (0 != res_goten))
26386 	{
26387 		m_context.getTestContext().getLog()
26388 			<< tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26389 			<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26390 
26391 		result = false;
26392 	}
26393 
26394 	/* Release buffer mapping */
26395 	buffer->UnMap();
26396 
26397 	return result;
26398 }
26399 
26400 /** Constructor
26401  *
26402  * @param context Test context
26403  **/
26404 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context& context)
26405 	: BufferTestBase(context, "xfb_capture_inactive_output_component",
26406 					 "Test verifies that inactive components are not modified")
26407 {
26408 	/* Nothing to be done here */
26409 }
26410 
26411 /** Execute drawArrays for single vertex
26412  *
26413  * @param test_case_index
26414  *
26415  * @return true
26416  **/
26417 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26418 {
26419 	const Functions& gl				= m_context.getRenderContext().getFunctions();
26420 	GLenum			 primitive_type = GL_PATCHES;
26421 
26422 	if (TEST_VS == test_case_index)
26423 	{
26424 		primitive_type = GL_POINTS;
26425 	}
26426 
26427 	gl.disable(GL_RASTERIZER_DISCARD);
26428 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26429 
26430 	gl.beginTransformFeedback(GL_POINTS);
26431 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26432 
26433 	gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26434 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26435 
26436 	gl.endTransformFeedback();
26437 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26438 
26439 	return true;
26440 }
26441 
26442 /** Get descriptors of buffers necessary for test
26443  *
26444  * @param ignored
26445  * @param out_descriptors Descriptors of buffers used by test
26446  **/
26447 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26448 																 bufferDescriptor::Vector& out_descriptors)
26449 {
26450 	const Utils::Type& type = Utils::Type::vec4;
26451 
26452 	/* Test needs single uniform and xfb */
26453 	out_descriptors.resize(2);
26454 
26455 	/* Get references */
26456 	bufferDescriptor& uniform = out_descriptors[0];
26457 	bufferDescriptor& xfb	 = out_descriptors[1];
26458 
26459 	/* Index */
26460 	uniform.m_index = 0;
26461 	xfb.m_index		= 0;
26462 
26463 	/* Target */
26464 	uniform.m_target = Utils::Buffer::Uniform;
26465 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
26466 
26467 	/* Data */
26468 	const std::vector<GLubyte>& goku_data   = type.GenerateData();
26469 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
26470 	const std::vector<GLubyte>& goten_data  = type.GenerateData();
26471 	const std::vector<GLubyte>& chichi_data = type.GenerateData();
26472 	const std::vector<GLubyte>& vegeta_data = type.GenerateData();
26473 	const std::vector<GLubyte>& trunks_data = type.GenerateData();
26474 	const std::vector<GLubyte>& bra_data	= type.GenerateData();
26475 	const std::vector<GLubyte>& bulma_data  = type.GenerateData();
26476 
26477 	const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type);
26478 	const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26479 
26480 	/* Uniform data */
26481 	uniform.m_initial_data.resize(8 * type_size);
26482 	memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size);
26483 	memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size);
26484 	memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
26485 	memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size);
26486 	memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
26487 	memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size);
26488 	memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size);
26489 	memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size);
26490 
26491 	/* XFB data */
26492 	xfb.m_initial_data.resize(8 * type_size);
26493 	xfb.m_expected_data.resize(8 * type_size);
26494 
26495 	for (GLuint i = 0; i < 8 * type_size; ++i)
26496 	{
26497 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
26498 		xfb.m_expected_data[i] = (glw::GLubyte)i;
26499 	}
26500 
26501 	/* goku - x, z - 32 */
26502 	memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size);
26503 	memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size);
26504 
26505 	/* gohan - y, w - 0 */
26506 	memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size);
26507 	memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size);
26508 
26509 	/* goten - x, y - 16 */
26510 	memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size);
26511 	memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size);
26512 
26513 	/* chichi - z, w - 48 */
26514 	memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size);
26515 	memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size);
26516 
26517 	/* vegeta - x - 112 */
26518 	memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size);
26519 
26520 	/* trunks - y - 96 */
26521 	memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size);
26522 
26523 	/* bra - z - 80 */
26524 	memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size);
26525 
26526 	/* bulma - w - 64 */
26527 	memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size);
26528 }
26529 
26530 /** Get body of main function for given shader stage
26531  *
26532  * @param test_case_index  Index of test case
26533  * @param stage            Shader stage
26534  * @param out_assignments  Set to empty
26535  * @param out_calculations Set to empty
26536  **/
26537 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26538 														  std::string& out_assignments, std::string& out_calculations)
26539 {
26540 	out_calculations = "";
26541 
26542 	static const GLchar* vs_tes_gs = "    goku.x    = uni_goku.x   ;\n"
26543 									 "    goku.z    = uni_goku.z   ;\n"
26544 									 "    gohan.y   = uni_gohan.y  ;\n"
26545 									 "    gohan.w   = uni_gohan.w  ;\n"
26546 									 "    goten.x   = uni_goten.x  ;\n"
26547 									 "    goten.y   = uni_goten.y  ;\n"
26548 									 "    chichi.z  = uni_chichi.z ;\n"
26549 									 "    chichi.w  = uni_chichi.w ;\n"
26550 									 "    vegeta.x  = uni_vegeta.x ;\n"
26551 									 "    trunks.y  = uni_trunks.y ;\n"
26552 									 "    bra.z     = uni_bra.z    ;\n"
26553 									 "    bulma.w   = uni_bulma.w  ;\n";
26554 	static const GLchar* fs = "    fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n";
26555 
26556 	const GLchar* assignments = "";
26557 
26558 	switch (stage)
26559 	{
26560 	case Utils::Shader::FRAGMENT:
26561 		assignments = fs;
26562 		break;
26563 
26564 	case Utils::Shader::GEOMETRY:
26565 		if (TEST_GS == test_case_index)
26566 		{
26567 			assignments = vs_tes_gs;
26568 		}
26569 		break;
26570 
26571 	case Utils::Shader::TESS_CTRL:
26572 		break;
26573 
26574 	case Utils::Shader::TESS_EVAL:
26575 		if (TEST_TES == test_case_index)
26576 		{
26577 			assignments = vs_tes_gs;
26578 		}
26579 		break;
26580 
26581 	case Utils::Shader::VERTEX:
26582 		if (TEST_VS == test_case_index)
26583 		{
26584 			assignments = vs_tes_gs;
26585 		}
26586 		break;
26587 
26588 	default:
26589 		TCU_FAIL("Invalid enum");
26590 	}
26591 
26592 	out_assignments = assignments;
26593 }
26594 
26595 /** Get interface of shader
26596  *
26597  * @param test_case_index  Index of test case
26598  * @param stage            Shader stage
26599  * @param out_interface    Set to ""
26600  **/
26601 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26602 															   std::string& out_interface)
26603 {
26604 	static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26605 									 "\n"
26606 									 "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n"
26607 									 "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n"
26608 									 "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n"
26609 									 "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n"
26610 									 "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n"
26611 									 "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n"
26612 									 "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n"
26613 									 "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n"
26614 									 "\n"
26615 									 "layout(binding = 0) uniform block {\n"
26616 									 "    vec4 uni_goku;\n"
26617 									 "    vec4 uni_gohan;\n"
26618 									 "    vec4 uni_goten;\n"
26619 									 "    vec4 uni_chichi;\n"
26620 									 "    vec4 uni_vegeta;\n"
26621 									 "    vec4 uni_trunks;\n"
26622 									 "    vec4 uni_bra;\n"
26623 									 "    vec4 uni_bulma;\n"
26624 									 "};\n";
26625 	static const GLchar* fs = "in vec4 vegeta;\n"
26626 							  "in vec4 trunks;\n"
26627 							  "in vec4 bra;\n"
26628 							  "in vec4 bulma;\n"
26629 							  "in vec4 goku;\n"
26630 							  "in vec4 gohan;\n"
26631 							  "in vec4 goten;\n"
26632 							  "in vec4 chichi;\n"
26633 							  "\n"
26634 							  "out vec4 fs_out;\n";
26635 
26636 	const GLchar* interface = "";
26637 
26638 	switch (stage)
26639 	{
26640 	case Utils::Shader::FRAGMENT:
26641 		interface = fs;
26642 		break;
26643 
26644 	case Utils::Shader::GEOMETRY:
26645 		if (TEST_GS == test_case_index)
26646 		{
26647 			interface = vs_tes_gs;
26648 		}
26649 		break;
26650 
26651 	case Utils::Shader::TESS_CTRL:
26652 		break;
26653 
26654 	case Utils::Shader::TESS_EVAL:
26655 		if (TEST_TES == test_case_index)
26656 		{
26657 			interface = vs_tes_gs;
26658 		}
26659 		break;
26660 
26661 	case Utils::Shader::VERTEX:
26662 		if (TEST_VS == test_case_index)
26663 		{
26664 			interface = vs_tes_gs;
26665 		}
26666 		break;
26667 
26668 	default:
26669 		TCU_FAIL("Invalid enum");
26670 	}
26671 
26672 	out_interface = interface;
26673 }
26674 
26675 /** Get source code of shader
26676  *
26677  * @param test_case_index Index of test case
26678  * @param stage           Shader stage
26679  *
26680  * @return Source
26681  **/
26682 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26683 {
26684 	std::string source;
26685 
26686 	switch (test_case_index)
26687 	{
26688 	case TEST_VS:
26689 		switch (stage)
26690 		{
26691 		case Utils::Shader::FRAGMENT:
26692 		case Utils::Shader::VERTEX:
26693 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26694 			break;
26695 		default:
26696 			break;
26697 		}
26698 		break;
26699 
26700 	case TEST_TES:
26701 		switch (stage)
26702 		{
26703 		case Utils::Shader::FRAGMENT:
26704 		case Utils::Shader::TESS_CTRL:
26705 		case Utils::Shader::TESS_EVAL:
26706 		case Utils::Shader::VERTEX:
26707 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26708 			break;
26709 		default:
26710 			break;
26711 		}
26712 		break;
26713 
26714 	case TEST_GS:
26715 		source = BufferTestBase::getShaderSource(test_case_index, stage);
26716 		break;
26717 
26718 	default:
26719 		TCU_FAIL("Invalid enum");
26720 	}
26721 
26722 	/* */
26723 	return source;
26724 }
26725 
26726 /** Get name of test case
26727  *
26728  * @param test_case_index Index of test case
26729  *
26730  * @return Name of tested stage
26731  **/
26732 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index)
26733 {
26734 	const GLchar* name = 0;
26735 
26736 	switch (test_case_index)
26737 	{
26738 	case TEST_VS:
26739 		name = "vertex";
26740 		break;
26741 	case TEST_TES:
26742 		name = "tessellation evaluation";
26743 		break;
26744 	case TEST_GS:
26745 		name = "geometry";
26746 		break;
26747 	default:
26748 		TCU_FAIL("Invalid enum");
26749 	}
26750 
26751 	return name;
26752 }
26753 
26754 /** Returns number of test cases
26755  *
26756  * @return TEST_MAX
26757  **/
26758 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber()
26759 {
26760 	return TEST_MAX;
26761 }
26762 
26763 /** Verify contents of buffers
26764  *
26765  * @param buffers Collection of buffers to be verified
26766  *
26767  * @return true if everything is as expected, false otherwise
26768  **/
26769 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection& buffers)
26770 {
26771 	bool result = true;
26772 
26773 	bufferCollection::pair& pair	   = buffers.m_vector[1] /* xfb */;
26774 	Utils::Buffer*			buffer	 = pair.m_buffer;
26775 	bufferDescriptor*		descriptor = pair.m_descriptor;
26776 
26777 	/* Get pointer to contents of buffer */
26778 	buffer->Bind();
26779 	GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26780 
26781 	/* Get pointer to expected data */
26782 	GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26783 
26784 	/* Compare */
26785 	static const GLuint comp_size = 4;
26786 	static const GLuint vec4_size = 16;
26787 
26788 	int res_goku_x =
26789 		memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size);
26790 	int res_goku_z =
26791 		memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size);
26792 
26793 	int res_gohan_y =
26794 		memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size);
26795 	int res_gohan_w =
26796 		memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size);
26797 
26798 	int res_goten_x =
26799 		memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size);
26800 	int res_goten_y =
26801 		memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size);
26802 
26803 	int res_chichi_z =
26804 		memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size);
26805 	int res_chichi_w =
26806 		memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size);
26807 
26808 	int res_vegeta_x =
26809 		memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size);
26810 
26811 	int res_trunks_y =
26812 		memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size);
26813 
26814 	int res_bra_z =
26815 		memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size);
26816 
26817 	int res_bulma_w =
26818 		memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size);
26819 
26820 	if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) ||
26821 		(0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) ||
26822 		(0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w))
26823 	{
26824 		m_context.getTestContext().getLog()
26825 			<< tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26826 			<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26827 
26828 		result = false;
26829 	}
26830 
26831 	/* Release buffer mapping */
26832 	buffer->UnMap();
26833 
26834 	return result;
26835 }
26836 
26837 /** Constructor
26838  *
26839  * @param context Test context
26840  **/
26841 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context& context)
26842 	: BufferTestBase(context, "xfb_capture_inactive_output_block_member",
26843 					 "Test verifies that inactive block members are captured")
26844 {
26845 	/* Nothing to be done here */
26846 }
26847 
26848 /** Execute drawArrays for single vertex
26849  *
26850  * @param test_case_index
26851  *
26852  * @return true
26853  **/
26854 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26855 {
26856 	const Functions& gl				= m_context.getRenderContext().getFunctions();
26857 	GLenum			 primitive_type = GL_PATCHES;
26858 
26859 	if (TEST_VS == test_case_index)
26860 	{
26861 		primitive_type = GL_POINTS;
26862 	}
26863 
26864 	gl.disable(GL_RASTERIZER_DISCARD);
26865 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26866 
26867 	gl.beginTransformFeedback(GL_POINTS);
26868 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26869 
26870 	gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26871 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26872 
26873 	gl.endTransformFeedback();
26874 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26875 
26876 	return true;
26877 }
26878 
26879 /** Get descriptors of buffers necessary for test
26880  *
26881  * @param ignored
26882  * @param out_descriptors Descriptors of buffers used by test
26883  **/
26884 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26885 																   bufferDescriptor::Vector& out_descriptors)
26886 {
26887 	const Utils::Type& type = Utils::Type::vec4;
26888 
26889 	/* Test needs single uniform and xfb */
26890 	out_descriptors.resize(2);
26891 
26892 	/* Get references */
26893 	bufferDescriptor& uniform = out_descriptors[0];
26894 	bufferDescriptor& xfb	 = out_descriptors[1];
26895 
26896 	/* Index */
26897 	uniform.m_index = 0;
26898 	xfb.m_index		= 0;
26899 
26900 	/* Target */
26901 	uniform.m_target = Utils::Buffer::Uniform;
26902 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
26903 
26904 	/* Data */
26905 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
26906 	const std::vector<GLubyte>& chichi_data = type.GenerateData();
26907 
26908 	const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26909 
26910 	/* Uniform data */
26911 	uniform.m_initial_data.resize(2 * type_size);
26912 	memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26913 	memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26914 
26915 	/* XFB data */
26916 	xfb.m_initial_data.resize(4 * type_size);
26917 	xfb.m_expected_data.resize(4 * type_size);
26918 
26919 	for (GLuint i = 0; i < 4 * type_size; ++i)
26920 	{
26921 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
26922 		xfb.m_expected_data[i] = (glw::GLubyte)i;
26923 	}
26924 
26925 	memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26926 	memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
26927 }
26928 
26929 /** Get body of main function for given shader stage
26930  *
26931  * @param test_case_index  Index of test case
26932  * @param stage            Shader stage
26933  * @param out_assignments  Set to empty
26934  * @param out_calculations Set to empty
26935  **/
26936 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26937 															std::string& out_assignments, std::string& out_calculations)
26938 {
26939 	out_calculations = "";
26940 
26941 	static const GLchar* vs_tes_gs = "    chichi = uni_chichi;\n"
26942 									 "    gohan  = uni_gohan;\n";
26943 	static const GLchar* fs = "    fs_out = goten + gohan + chichi;\n";
26944 
26945 	const GLchar* assignments = "";
26946 
26947 	switch (stage)
26948 	{
26949 	case Utils::Shader::FRAGMENT:
26950 		assignments = fs;
26951 		break;
26952 
26953 	case Utils::Shader::GEOMETRY:
26954 		if (TEST_GS == test_case_index)
26955 		{
26956 			assignments = vs_tes_gs;
26957 		}
26958 		break;
26959 
26960 	case Utils::Shader::TESS_CTRL:
26961 		break;
26962 
26963 	case Utils::Shader::TESS_EVAL:
26964 		if (TEST_TES == test_case_index)
26965 		{
26966 			assignments = vs_tes_gs;
26967 		}
26968 		break;
26969 
26970 	case Utils::Shader::VERTEX:
26971 		if (TEST_VS == test_case_index)
26972 		{
26973 			assignments = vs_tes_gs;
26974 		}
26975 		break;
26976 
26977 	default:
26978 		TCU_FAIL("Invalid enum");
26979 	}
26980 
26981 	out_assignments = assignments;
26982 }
26983 
26984 /** Get interface of shader
26985  *
26986  * @param test_case_index  Index of test case
26987  * @param stage            Shader stage
26988  * @param out_interface    Set to ""
26989  **/
26990 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26991 																 std::string& out_interface)
26992 {
26993 	static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26994 									 "\n"
26995 									 "layout (xfb_offset = 1 * sizeof_type) out Goku {\n"
26996 									 "    vec4 gohan;\n"
26997 									 "    vec4 goten;\n"
26998 									 "    vec4 chichi;\n"
26999 									 "};\n"
27000 									 "\n"
27001 									 "layout(binding = 0) uniform block {\n"
27002 									 "    vec4 uni_gohan;\n"
27003 									 "    vec4 uni_chichi;\n"
27004 									 "};\n";
27005 	static const GLchar* fs = "in Goku {\n"
27006 							  "    vec4 gohan;\n"
27007 							  "    vec4 goten;\n"
27008 							  "    vec4 chichi;\n"
27009 							  "};\n"
27010 							  "out vec4 fs_out;\n";
27011 
27012 	const GLchar* interface = "";
27013 
27014 	switch (stage)
27015 	{
27016 	case Utils::Shader::FRAGMENT:
27017 		interface = fs;
27018 		break;
27019 
27020 	case Utils::Shader::GEOMETRY:
27021 		if (TEST_GS == test_case_index)
27022 		{
27023 			interface = vs_tes_gs;
27024 		}
27025 		break;
27026 
27027 	case Utils::Shader::TESS_CTRL:
27028 		break;
27029 
27030 	case Utils::Shader::TESS_EVAL:
27031 		if (TEST_TES == test_case_index)
27032 		{
27033 			interface = vs_tes_gs;
27034 		}
27035 		break;
27036 
27037 	case Utils::Shader::VERTEX:
27038 		if (TEST_VS == test_case_index)
27039 		{
27040 			interface = vs_tes_gs;
27041 		}
27042 		break;
27043 
27044 	default:
27045 		TCU_FAIL("Invalid enum");
27046 	}
27047 
27048 	out_interface = interface;
27049 }
27050 
27051 /** Get source code of shader
27052  *
27053  * @param test_case_index Index of test case
27054  * @param stage           Shader stage
27055  *
27056  * @return Source
27057  **/
27058 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint				   test_case_index,
27059 																	 Utils::Shader::STAGES stage)
27060 {
27061 	std::string source;
27062 
27063 	switch (test_case_index)
27064 	{
27065 	case TEST_VS:
27066 		switch (stage)
27067 		{
27068 		case Utils::Shader::FRAGMENT:
27069 		case Utils::Shader::VERTEX:
27070 			source = BufferTestBase::getShaderSource(test_case_index, stage);
27071 			break;
27072 		default:
27073 			break;
27074 		}
27075 		break;
27076 
27077 	case TEST_TES:
27078 		switch (stage)
27079 		{
27080 		case Utils::Shader::FRAGMENT:
27081 		case Utils::Shader::TESS_CTRL:
27082 		case Utils::Shader::TESS_EVAL:
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_GS:
27092 		source = BufferTestBase::getShaderSource(test_case_index, stage);
27093 		break;
27094 
27095 	default:
27096 		TCU_FAIL("Invalid enum");
27097 	}
27098 
27099 	/* */
27100 	return source;
27101 }
27102 
27103 /** Get name of test case
27104  *
27105  * @param test_case_index Index of test case
27106  *
27107  * @return Name of tested stage
27108  **/
27109 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index)
27110 {
27111 	const GLchar* name = 0;
27112 
27113 	switch (test_case_index)
27114 	{
27115 	case TEST_VS:
27116 		name = "vertex";
27117 		break;
27118 	case TEST_TES:
27119 		name = "tessellation evaluation";
27120 		break;
27121 	case TEST_GS:
27122 		name = "geometry";
27123 		break;
27124 	default:
27125 		TCU_FAIL("Invalid enum");
27126 	}
27127 
27128 	return name;
27129 }
27130 
27131 /** Returns number of test cases
27132  *
27133  * @return TEST_MAX
27134  **/
27135 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber()
27136 {
27137 	return TEST_MAX;
27138 }
27139 
27140 /** Verify contents of buffers
27141  *
27142  * @param buffers Collection of buffers to be verified
27143  *
27144  * @return true if everything is as expected, false otherwise
27145  **/
27146 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection& buffers)
27147 {
27148 	bool result = true;
27149 
27150 	bufferCollection::pair& pair	   = buffers.m_vector[1] /* xfb */;
27151 	Utils::Buffer*			buffer	 = pair.m_buffer;
27152 	bufferDescriptor*		descriptor = pair.m_descriptor;
27153 
27154 	/* Get pointer to contents of buffer */
27155 	buffer->Bind();
27156 	GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
27157 
27158 	/* Get pointer to expected data */
27159 	GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
27160 
27161 	/* Compare */
27162 	static const GLuint vec4_size = 16;
27163 
27164 	int res_before = memcmp(buffer_data, expected_data, vec4_size);
27165 	int res_gohan  = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27166 	int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27167 
27168 	if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27169 	{
27170 		m_context.getTestContext().getLog()
27171 			<< tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27172 			<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27173 
27174 		result = false;
27175 	}
27176 
27177 	/* Release buffer mapping */
27178 	buffer->UnMap();
27179 
27180 	return result;
27181 }
27182 
27183 /** Constructor
27184  *
27185  * @param context Test context
27186  **/
27187 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context& context)
27188 	: BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured")
27189 {
27190 	/* Nothing to be done here */
27191 }
27192 
27193 /** Execute drawArrays for single vertex
27194  *
27195  * @param test_case_index
27196  *
27197  * @return true
27198  **/
27199 bool XFBCaptureStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
27200 {
27201 	const Functions& gl				= m_context.getRenderContext().getFunctions();
27202 	GLenum			 primitive_type = GL_PATCHES;
27203 
27204 	if (TEST_VS == test_case_index)
27205 	{
27206 		primitive_type = GL_POINTS;
27207 	}
27208 
27209 	gl.disable(GL_RASTERIZER_DISCARD);
27210 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
27211 
27212 	gl.beginTransformFeedback(GL_POINTS);
27213 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
27214 
27215 	gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
27216 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
27217 
27218 	gl.endTransformFeedback();
27219 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
27220 
27221 	return true;
27222 }
27223 
27224 /** Get descriptors of buffers necessary for test
27225  *
27226  * @param ignored
27227  * @param out_descriptors Descriptors of buffers used by test
27228  **/
27229 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
27230 												bufferDescriptor::Vector& out_descriptors)
27231 {
27232 	const Utils::Type& type = Utils::Type::vec4;
27233 
27234 	/* Test needs single uniform and xfb */
27235 	out_descriptors.resize(2);
27236 
27237 	/* Get references */
27238 	bufferDescriptor& uniform = out_descriptors[0];
27239 	bufferDescriptor& xfb	 = out_descriptors[1];
27240 
27241 	/* Index */
27242 	uniform.m_index = 0;
27243 	xfb.m_index		= 0;
27244 
27245 	/* Target */
27246 	uniform.m_target = Utils::Buffer::Uniform;
27247 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
27248 
27249 	/* Data */
27250 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
27251 	const std::vector<GLubyte>& chichi_data = type.GenerateData();
27252 
27253 	const GLuint type_size = static_cast<GLuint>(gohan_data.size());
27254 
27255 	/* Uniform data */
27256 	uniform.m_initial_data.resize(2 * type_size);
27257 	memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
27258 	memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
27259 
27260 	/* XFB data */
27261 	xfb.m_initial_data.resize(4 * type_size);
27262 	xfb.m_expected_data.resize(4 * type_size);
27263 
27264 	for (GLuint i = 0; i < 4 * type_size; ++i)
27265 	{
27266 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
27267 		xfb.m_expected_data[i] = (glw::GLubyte)i;
27268 	}
27269 
27270 	memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
27271 	memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
27272 }
27273 
27274 /** Get body of main function for given shader stage
27275  *
27276  * @param test_case_index  Index of test case
27277  * @param stage            Shader stage
27278  * @param out_assignments  Set to empty
27279  * @param out_calculations Set to empty
27280  **/
27281 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27282 										 std::string& out_assignments, std::string& out_calculations)
27283 {
27284 	out_calculations = "";
27285 
27286 	static const GLchar* vs_tes_gs = "    goku.chichi = uni_chichi;\n"
27287 									 "    goku.gohan  = uni_gohan;\n";
27288 	static const GLchar* fs = "    fs_out = goku.goten + goku.gohan + goku.chichi;\n";
27289 
27290 	const GLchar* assignments = "";
27291 
27292 	switch (stage)
27293 	{
27294 	case Utils::Shader::FRAGMENT:
27295 		assignments = fs;
27296 		break;
27297 
27298 	case Utils::Shader::GEOMETRY:
27299 		if (TEST_GS == test_case_index)
27300 		{
27301 			assignments = vs_tes_gs;
27302 		}
27303 		break;
27304 
27305 	case Utils::Shader::TESS_CTRL:
27306 		break;
27307 
27308 	case Utils::Shader::TESS_EVAL:
27309 		if (TEST_TES == test_case_index)
27310 		{
27311 			assignments = vs_tes_gs;
27312 		}
27313 		break;
27314 
27315 	case Utils::Shader::VERTEX:
27316 		if (TEST_VS == test_case_index)
27317 		{
27318 			assignments = vs_tes_gs;
27319 		}
27320 		break;
27321 
27322 	default:
27323 		TCU_FAIL("Invalid enum");
27324 	}
27325 
27326 	out_assignments = assignments;
27327 }
27328 
27329 /** Get interface of shader
27330  *
27331  * @param test_case_index  Index of test case
27332  * @param stage            Shader stage
27333  * @param out_interface    Set to ""
27334  **/
27335 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27336 											  std::string& out_interface)
27337 {
27338 	static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
27339 									 "\n"
27340 									 "struct Goku {\n"
27341 									 "    vec4 gohan;\n"
27342 									 "    vec4 goten;\n"
27343 									 "    vec4 chichi;\n"
27344 									 "};\n"
27345 									 "\n"
27346 									 "layout (xfb_offset = sizeof_type) out Goku goku;\n"
27347 									 "\n"
27348 									 "layout(binding = 0, std140) uniform block {\n"
27349 									 "    vec4 uni_gohan;\n"
27350 									 "    vec4 uni_chichi;\n"
27351 									 "};\n";
27352 	static const GLchar* fs = "struct Goku {\n"
27353 							  "    vec4 gohan;\n"
27354 							  "    vec4 goten;\n"
27355 							  "    vec4 chichi;\n"
27356 							  "};\n"
27357 							  "\n"
27358 							  "in Goku goku;\n"
27359 							  "\n"
27360 							  "out vec4 fs_out;\n";
27361 
27362 	const GLchar* interface = "";
27363 
27364 	switch (stage)
27365 	{
27366 	case Utils::Shader::FRAGMENT:
27367 		interface = fs;
27368 		break;
27369 
27370 	case Utils::Shader::GEOMETRY:
27371 		if (TEST_GS == test_case_index)
27372 		{
27373 			interface = vs_tes_gs;
27374 		}
27375 		break;
27376 
27377 	case Utils::Shader::TESS_CTRL:
27378 		break;
27379 
27380 	case Utils::Shader::TESS_EVAL:
27381 		if (TEST_TES == test_case_index)
27382 		{
27383 			interface = vs_tes_gs;
27384 		}
27385 		break;
27386 
27387 	case Utils::Shader::VERTEX:
27388 		if (TEST_VS == test_case_index)
27389 		{
27390 			interface = vs_tes_gs;
27391 		}
27392 		break;
27393 
27394 	default:
27395 		TCU_FAIL("Invalid enum");
27396 	}
27397 
27398 	out_interface = interface;
27399 }
27400 
27401 /** Get source code of shader
27402  *
27403  * @param test_case_index Index of test case
27404  * @param stage           Shader stage
27405  *
27406  * @return Source
27407  **/
27408 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27409 {
27410 	std::string source;
27411 
27412 	switch (test_case_index)
27413 	{
27414 	case TEST_VS:
27415 		switch (stage)
27416 		{
27417 		case Utils::Shader::FRAGMENT:
27418 		case Utils::Shader::VERTEX:
27419 			source = BufferTestBase::getShaderSource(test_case_index, stage);
27420 			break;
27421 		default:
27422 			break;
27423 		}
27424 		break;
27425 
27426 	case TEST_TES:
27427 		switch (stage)
27428 		{
27429 		case Utils::Shader::FRAGMENT:
27430 		case Utils::Shader::TESS_CTRL:
27431 		case Utils::Shader::TESS_EVAL:
27432 		case Utils::Shader::VERTEX:
27433 			source = BufferTestBase::getShaderSource(test_case_index, stage);
27434 			break;
27435 		default:
27436 			break;
27437 		}
27438 		break;
27439 
27440 	case TEST_GS:
27441 		source = BufferTestBase::getShaderSource(test_case_index, stage);
27442 		break;
27443 
27444 	default:
27445 		TCU_FAIL("Invalid enum");
27446 	}
27447 
27448 	/* */
27449 	return source;
27450 }
27451 
27452 /** Get name of test case
27453  *
27454  * @param test_case_index Index of test case
27455  *
27456  * @return Name of tested stage
27457  **/
27458 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index)
27459 {
27460 	const GLchar* name = 0;
27461 
27462 	switch (test_case_index)
27463 	{
27464 	case TEST_VS:
27465 		name = "vertex";
27466 		break;
27467 	case TEST_TES:
27468 		name = "tessellation evaluation";
27469 		break;
27470 	case TEST_GS:
27471 		name = "geometry";
27472 		break;
27473 	default:
27474 		TCU_FAIL("Invalid enum");
27475 	}
27476 
27477 	return name;
27478 }
27479 
27480 /** Returns number of test cases
27481  *
27482  * @return TEST_MAX
27483  **/
27484 glw::GLuint XFBCaptureStructTest::getTestCaseNumber()
27485 {
27486 	return TEST_MAX;
27487 }
27488 
27489 /** Verify contents of buffers
27490  *
27491  * @param buffers Collection of buffers to be verified
27492  *
27493  * @return true if everything is as expected, false otherwise
27494  **/
27495 bool XFBCaptureStructTest::verifyBuffers(bufferCollection& buffers)
27496 {
27497 	bool result = true;
27498 
27499 	bufferCollection::pair& pair	   = buffers.m_vector[1] /* xfb */;
27500 	Utils::Buffer*			buffer	 = pair.m_buffer;
27501 	bufferDescriptor*		descriptor = pair.m_descriptor;
27502 
27503 	/* Get pointer to contents of buffer */
27504 	buffer->Bind();
27505 	GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
27506 
27507 	/* Get pointer to expected data */
27508 	GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
27509 
27510 	/* Compare */
27511 	static const GLuint vec4_size = 16;
27512 
27513 	int res_before = memcmp(buffer_data, expected_data, vec4_size);
27514 	int res_gohan  = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27515 	int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27516 
27517 	if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27518 	{
27519 		m_context.getTestContext().getLog()
27520 			<< tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27521 			<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27522 
27523 		result = false;
27524 	}
27525 
27526 	/* Release buffer mapping */
27527 	buffer->UnMap();
27528 
27529 	return result;
27530 }
27531 
27532 /** Constructor
27533  *
27534  * @param context Test framework context
27535  **/
27536 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context& context)
27537 	: NegativeTestBase(context, "xfb_capture_unsized_array",
27538 					   "Test verifies that compiler reports error when unsized array is qualified with xfb_offset")
27539 {
27540 }
27541 
27542 /** Source for given test case and stage
27543  *
27544  * @param test_case_index Index of test case
27545  * @param stage           Shader stage
27546  *
27547  * @return Shader source
27548  **/
27549 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27550 {
27551 #if DEBUG_NEG_REMOVE_ERROR
27552 	static const GLchar* var_definition = "/* layout (xfb_offset = 0) */ out vec4 goku[];\n";
27553 #else
27554 	static const GLchar* var_definition = "layout (xfb_offset = 0) out vec4 goku[];\n";
27555 #endif /* DEBUG_NEG_REMOVE_ERROR */
27556 	static const GLchar* var_use = "    goku[0] = result / 2;\n";
27557 	static const GLchar* fs		 = "#version 430 core\n"
27558 							  "#extension GL_ARB_enhanced_layouts : require\n"
27559 							  "\n"
27560 							  "in  vec4 any_fs;\n"
27561 							  "out vec4 fs_out;\n"
27562 							  "\n"
27563 							  "void main()\n"
27564 							  "{\n"
27565 							  "    fs_out = any_fs;\n"
27566 							  "}\n"
27567 							  "\n";
27568 	static const GLchar* vs_tested = "#version 430 core\n"
27569 									 "#extension GL_ARB_enhanced_layouts : require\n"
27570 									 "\n"
27571 									 "VAR_DEFINITION"
27572 									 "\n"
27573 									 "in  vec4 in_vs;\n"
27574 									 "out vec4 any_fs;\n"
27575 									 "\n"
27576 									 "void main()\n"
27577 									 "{\n"
27578 									 "    vec4 result = in_vs;\n"
27579 									 "\n"
27580 									 "VARIABLE_USE"
27581 									 "\n"
27582 									 "    any_fs = result;\n"
27583 									 "}\n"
27584 									 "\n";
27585 
27586 	std::string source;
27587 	testCase&   test_case = m_test_cases[test_case_index];
27588 
27589 	if (test_case.m_stage == stage)
27590 	{
27591 		size_t		  position = 0;
27592 
27593 		switch (stage)
27594 		{
27595 		case Utils::Shader::VERTEX:
27596 			source = vs_tested;
27597 			break;
27598 		default:
27599 			TCU_FAIL("Invalid enum");
27600 		}
27601 
27602 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
27603 		position = 0;
27604 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
27605 	}
27606 	else
27607 	{
27608 		switch (test_case.m_stage)
27609 		{
27610 		case Utils::Shader::VERTEX:
27611 			switch (stage)
27612 			{
27613 			case Utils::Shader::FRAGMENT:
27614 				source = fs;
27615 				break;
27616 			default:
27617 				source = "";
27618 			}
27619 			break;
27620 		default:
27621 			TCU_FAIL("Invalid enum");
27622 		}
27623 	}
27624 
27625 	return source;
27626 }
27627 
27628 /** Get description of test case
27629  *
27630  * @param test_case_index Index of test case
27631  *
27632  * @return Test case description
27633  **/
27634 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index)
27635 {
27636 	std::stringstream stream;
27637 	testCase&		  test_case = m_test_cases[test_case_index];
27638 
27639 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
27640 
27641 	return stream.str();
27642 }
27643 
27644 /** Get number of test cases
27645  *
27646  * @return Number of test cases
27647  **/
27648 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber()
27649 {
27650 	return static_cast<GLuint>(m_test_cases.size());
27651 }
27652 
27653 /** Selects if "compute" stage is relevant for test
27654  *
27655  * @param ignored
27656  *
27657  * @return false
27658  **/
27659 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */)
27660 {
27661 	return false;
27662 }
27663 
27664 /** Prepare all test cases
27665  *
27666  **/
27667 void XFBCaptureUnsizedArrayTest::testInit()
27668 {
27669 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
27670 	{
27671 		/* Not aplicable for */
27672 		if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
27673 			(Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage) ||
27674 			(Utils::Shader::TESS_EVAL == stage))
27675 		{
27676 			continue;
27677 		}
27678 
27679 		testCase test_case = { (Utils::Shader::STAGES)stage };
27680 
27681 		m_test_cases.push_back(test_case);
27682 	}
27683 }
27684 
27685 /** Constructor
27686  *
27687  * @param context Test context
27688  **/
27689 XFBExplicitLocationTest::XFBExplicitLocationTest(deqp::Context& context)
27690 	: BufferTestBase(context, "xfb_explicit_location", "Test verifies that explicit location on matrices and arrays does not impact xfb output")
27691 {
27692 	/* Nothing to be done here */
27693 }
27694 
27695 /** Execute drawArrays for single vertex
27696  *
27697  * @param test_case_index
27698  *
27699  * @return true
27700  **/
27701 bool XFBExplicitLocationTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
27702 {
27703 	const Functions& gl				= m_context.getRenderContext().getFunctions();
27704 	GLenum			 primitive_type = GL_PATCHES;
27705 	const testCase&  test_case		= m_test_cases[test_case_index];
27706 
27707 	if (Utils::Shader::VERTEX == test_case.m_stage)
27708 	{
27709 		primitive_type = GL_POINTS;
27710 	}
27711 
27712 	gl.disable(GL_RASTERIZER_DISCARD);
27713 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
27714 
27715 	gl.beginTransformFeedback(GL_POINTS);
27716 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
27717 
27718 	gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
27719 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
27720 
27721 	gl.endTransformFeedback();
27722 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
27723 
27724 	return true;
27725 }
27726 
27727 /** Get descriptors of buffers necessary for test
27728  *
27729  * @param test_case_index Index of test case
27730  * @param out_descriptors Descriptors of buffers used by test
27731  **/
27732 void XFBExplicitLocationTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
27733 {
27734 	const testCase&	test_case = m_test_cases[test_case_index];
27735 	const Utils::Type& type		 = test_case.m_type;
27736 
27737 	/* Test needs single uniform and xfb */
27738 	out_descriptors.resize(2);
27739 
27740 	/* Get references */
27741 	bufferDescriptor& uniform	= out_descriptors[0];
27742 	bufferDescriptor& xfb		= out_descriptors[1];
27743 
27744 	/* Index */
27745 	uniform.m_index = 0;
27746 	xfb.m_index		= 0;
27747 
27748 	/* Target */
27749 	uniform.m_target = Utils::Buffer::Uniform;
27750 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
27751 
27752 	/* Data */
27753 	const GLuint			rand_start   = Utils::s_rand;
27754 	std::vector<GLubyte>	uniform_data;
27755 
27756 	for (GLuint i = 0; i < std::max(test_case.m_array_size, 1u); i++)
27757 	{
27758 		const std::vector<GLubyte>& type_uniform_data = type.GenerateData();
27759 		/**
27760 		 * Rule 4 of Section 7.6.2.2:
27761 		 *
27762 		 * If the member is an array of scalars or vectors, the base alignment and array stride
27763 		 * are set to match the base alignment of a single array element, according to rules (1),
27764 		 * (2), and (3), and rounded up to the base alignment of a vec4.
27765 		 */
27766 		uniform_data.resize(Utils::align(uniform_data.size(), 16));
27767 		uniform_data.insert(uniform_data.end(), type_uniform_data.begin(), type_uniform_data.end());
27768 	}
27769 
27770 	Utils::s_rand = rand_start;
27771 	std::vector<GLubyte>	xfb_data;
27772 
27773 	for (GLuint i = 0; i < std::max(test_case.m_array_size, 1u); i++)
27774 	{
27775 		const std::vector<GLubyte>& type_xfb_data = type.GenerateDataPacked();
27776 		xfb_data.insert(xfb_data.end(), type_xfb_data.begin(), type_xfb_data.end());
27777 	}
27778 
27779 	const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
27780 	const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
27781 	/*
27782 	 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
27783 	 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
27784 	 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
27785 	 only one valid data should be initialized in xfb.m_expected_data
27786 	 */
27787 	const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
27788 	/* Uniform data */
27789 	uniform.m_initial_data.resize(uni_type_size);
27790 	memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
27791 
27792 	/* XFB data */
27793 	xfb.m_initial_data.resize(xfb_data_size, 0);
27794 	xfb.m_expected_data.resize(xfb_data_size);
27795 
27796 	if (test_case.m_stage == Utils::Shader::VERTEX)
27797 	{
27798 		memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
27799 	}
27800 	else
27801 	{
27802 		memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
27803 		memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
27804 	}
27805 }
27806 
27807 /** Get body of main function for given shader stage
27808  *
27809  * @param test_case_index  Index of test case
27810  * @param stage            Shader stage
27811  * @param out_assignments  Set to empty
27812  * @param out_calculations Set to empty
27813  **/
27814 void XFBExplicitLocationTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments,
27815 								  std::string& out_calculations)
27816 {
27817 	const testCase& test_case = m_test_cases[test_case_index];
27818 
27819 	out_calculations = "";
27820 
27821 	static const GLchar* vs_tes_gs = "    goku = uni_goku;\n";
27822 
27823 	const GLchar* assignments = "";
27824 
27825 	if (test_case.m_stage == stage)
27826 	{
27827 		switch (stage)
27828 		{
27829 		case Utils::Shader::GEOMETRY:
27830 			assignments = vs_tes_gs;
27831 			break;
27832 		case Utils::Shader::TESS_EVAL:
27833 			assignments = vs_tes_gs;
27834 			break;
27835 		case Utils::Shader::VERTEX:
27836 			assignments = vs_tes_gs;
27837 			break;
27838 		default:
27839 			TCU_FAIL("Invalid enum");
27840 		}
27841 	}
27842 	else
27843 	{
27844 		switch (stage)
27845 		{
27846 		case Utils::Shader::FRAGMENT:
27847 			assignments = "";
27848 			break;
27849 		case Utils::Shader::GEOMETRY:
27850 		case Utils::Shader::TESS_CTRL:
27851 		case Utils::Shader::TESS_EVAL:
27852 		case Utils::Shader::VERTEX:
27853 			break;
27854 		default:
27855 			TCU_FAIL("Invalid enum");
27856 		}
27857 	}
27858 
27859 	out_assignments = assignments;
27860 
27861 	if (Utils::Shader::FRAGMENT == stage)
27862 	{
27863 		Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
27864 	}
27865 }
27866 
27867 /** Get interface of shader
27868  *
27869  * @param test_case_index  Index of test case
27870  * @param stage            Shader stage
27871  * @param out_interface    Set to ""
27872  **/
27873 void XFBExplicitLocationTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface)
27874 {
27875 	static const GLchar* vs_tes_gs = "layout (location = 0, xfb_offset = 0) FLAT out TYPE gokuARRAY;\n"
27876 									 "\n"
27877 									 "layout(std140, binding = 0) uniform Goku {\n"
27878 									 "    TYPE uni_gokuARRAY;\n"
27879 									 "};\n";
27880 
27881 	const testCase& test_case = m_test_cases[test_case_index];
27882 	const GLchar*   interface = "";
27883 	const GLchar*   flat	  = "";
27884 
27885 	if (test_case.m_stage == stage)
27886 	{
27887 		switch (stage)
27888 		{
27889 		case Utils::Shader::GEOMETRY:
27890 			interface = vs_tes_gs;
27891 			break;
27892 		case Utils::Shader::TESS_EVAL:
27893 			interface = vs_tes_gs;
27894 			break;
27895 		case Utils::Shader::VERTEX:
27896 			interface = vs_tes_gs;
27897 			break;
27898 		default:
27899 			TCU_FAIL("Invalid enum");
27900 		}
27901 	}
27902 	else
27903 	{
27904 		switch (stage)
27905 		{
27906 		case Utils::Shader::FRAGMENT:
27907 			interface = "";
27908 			break;
27909 		case Utils::Shader::GEOMETRY:
27910 		case Utils::Shader::TESS_CTRL:
27911 		case Utils::Shader::TESS_EVAL:
27912 		case Utils::Shader::VERTEX:
27913 			break;
27914 		default:
27915 			TCU_FAIL("Invalid enum");
27916 		}
27917 	}
27918 
27919 	out_interface = interface;
27920 
27921 	if (Utils::Type::Float != test_case.m_type.m_basic_type)
27922 	{
27923 		flat = "flat";
27924 	}
27925 
27926 	/* Array size */
27927 	if (0 == test_case.m_array_size)
27928 	{
27929 		Utils::replaceAllTokens("ARRAY", "", out_interface);
27930 	}
27931 	else
27932 	{
27933 		char buffer[16];
27934 		sprintf(buffer, "[%d]", test_case.m_array_size);
27935 
27936 		Utils::replaceAllTokens("ARRAY", buffer, out_interface);
27937 	}
27938 
27939 	Utils::replaceAllTokens("FLAT", flat, out_interface);
27940 	Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
27941 }
27942 
27943 /** Get source code of shader
27944  *
27945  * @param test_case_index Index of test case
27946  * @param stage           Shader stage
27947  *
27948  * @return Source
27949  **/
27950 std::string XFBExplicitLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27951 {
27952 	std::string		source;
27953 	const testCase& test_case = m_test_cases[test_case_index];
27954 
27955 	switch (test_case.m_stage)
27956 	{
27957 	case Utils::Shader::VERTEX:
27958 		switch (stage)
27959 		{
27960 		case Utils::Shader::FRAGMENT:
27961 		case Utils::Shader::VERTEX:
27962 			source = BufferTestBase::getShaderSource(test_case_index, stage);
27963 			break;
27964 		default:
27965 			break;
27966 		}
27967 		break;
27968 
27969 	case Utils::Shader::TESS_EVAL:
27970 		switch (stage)
27971 		{
27972 		case Utils::Shader::FRAGMENT:
27973 		case Utils::Shader::TESS_CTRL:
27974 		case Utils::Shader::TESS_EVAL:
27975 		case Utils::Shader::VERTEX:
27976 			source = BufferTestBase::getShaderSource(test_case_index, stage);
27977 			break;
27978 		default:
27979 			break;
27980 		}
27981 		break;
27982 
27983 	case Utils::Shader::GEOMETRY:
27984 		source = BufferTestBase::getShaderSource(test_case_index, stage);
27985 		break;
27986 
27987 	default:
27988 		TCU_FAIL("Invalid enum");
27989 	}
27990 
27991 	/* */
27992 	return source;
27993 }
27994 
27995 /** Get name of test case
27996  *
27997  * @param test_case_index Index of test case
27998  *
27999  * @return Name of tested stage
28000  **/
28001 std::string XFBExplicitLocationTest::getTestCaseName(glw::GLuint test_case_index)
28002 {
28003 	std::stringstream stream;
28004 	const testCase&   test_case = m_test_cases[test_case_index];
28005 
28006 	stream << "Type: " << test_case.m_type.GetGLSLTypeName()
28007 		   << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
28008 
28009 	return stream.str();
28010 }
28011 
28012 /** Returns number of test cases
28013  *
28014  * @return TEST_MAX
28015  **/
28016 glw::GLuint XFBExplicitLocationTest::getTestCaseNumber()
28017 {
28018 	return static_cast<GLuint>(m_test_cases.size());
28019 }
28020 
28021 /** Prepare all test cases
28022  *
28023  **/
28024 void XFBExplicitLocationTest::testInit()
28025 {
28026 	const Functions& gl = m_context.getRenderContext().getFunctions();
28027 	GLint			 max_xfb_int;
28028 
28029 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
28030 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
28031 
28032 	const GLuint n_types = getTypesNumber();
28033 
28034 	for (GLuint i = 0; i < n_types; ++i)
28035 	{
28036 		const Utils::Type& type = getType(i);
28037 
28038 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
28039 		{
28040 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
28041 				(Utils::Shader::TESS_CTRL == stage))
28042 			{
28043 				continue;
28044 			}
28045 
28046 			if (type.m_n_columns > 1)
28047 			{
28048 				testCase test_case = { (Utils::Shader::STAGES)stage, type, 0 };
28049 
28050 				m_test_cases.push_back(test_case);
28051 			}
28052 
28053 			for (GLuint array_size = 3; array_size > 1; array_size--)
28054 			{
28055 				if (type.GetNumComponents() * array_size <= GLuint(max_xfb_int))
28056 				{
28057 					testCase test_case = { (Utils::Shader::STAGES)stage, type, array_size };
28058 
28059 					m_test_cases.push_back(test_case);
28060 
28061 					break;
28062 				}
28063 			}
28064 		}
28065 	}
28066 }
28067 
28068 /** Constructor
28069  *
28070  * @param context Test context
28071  **/
28072 XFBExplicitLocationStructTest::XFBExplicitLocationStructTest(deqp::Context& context)
28073 	: BufferTestBase(context, "xfb_struct_explicit_location", "Test verifies that explicit location on structs does not impact xfb output")
28074 {
28075 	/* Nothing to be done here */
28076 }
28077 
28078 /** Execute drawArrays for single vertex
28079  *
28080  * @param test_case_index
28081  *
28082  * @return true
28083  **/
28084 bool XFBExplicitLocationStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
28085 {
28086 	const Functions& gl				= m_context.getRenderContext().getFunctions();
28087 	GLenum			 primitive_type = GL_PATCHES;
28088 	const testCase&  test_case		= m_test_cases[test_case_index];
28089 
28090 	if (Utils::Shader::VERTEX == test_case.m_stage)
28091 	{
28092 		primitive_type = GL_POINTS;
28093 	}
28094 
28095 	gl.disable(GL_RASTERIZER_DISCARD);
28096 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
28097 
28098 	gl.beginTransformFeedback(GL_POINTS);
28099 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
28100 
28101 	gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
28102 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
28103 
28104 	gl.endTransformFeedback();
28105 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
28106 
28107 	return true;
28108 }
28109 
28110 /** Get descriptors of buffers necessary for test
28111  *
28112  * @param test_case_index Index of test case
28113  * @param out_descriptors Descriptors of buffers used by test
28114  **/
28115 void XFBExplicitLocationStructTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
28116 {
28117 	const testCase&	test_case = m_test_cases[test_case_index];
28118 
28119 	/* Test needs single uniform and xfb */
28120 	out_descriptors.resize(2);
28121 
28122 	/* Get references */
28123 	bufferDescriptor& uniform	= out_descriptors[0];
28124 	bufferDescriptor& xfb		= out_descriptors[1];
28125 
28126 	/* Index */
28127 	uniform.m_index = 0;
28128 	xfb.m_index		= 0;
28129 
28130 	/* Target */
28131 	uniform.m_target = Utils::Buffer::Uniform;
28132 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
28133 
28134 	/* Data */
28135 	const GLuint			rand_start   = Utils::s_rand;
28136 	std::vector<GLubyte>	uniform_data;
28137 	GLuint max_aligment = 1;
28138 
28139 	for (const testType& type : test_case.m_types)
28140 	{
28141 		GLuint base_aligment = type.m_type.GetBaseAlignment(false);
28142 		if (type.m_array_size > 0)
28143 		{
28144 			/**
28145 			 * Rule 4 of Section 7.6.2.2:
28146 			 *
28147 			 * If the member is an array of scalars or vectors, the base alignment and array stride
28148 			 * are set to match the base alignment of a single array element, according to rules (1),
28149 			 * (2), and (3), and rounded up to the base alignment of a vec4.
28150 			 */
28151 			base_aligment = Utils::align(base_aligment, Utils::Type::vec4.GetBaseAlignment(false));
28152 		}
28153 
28154 		max_aligment = std::max(base_aligment, max_aligment);
28155 
28156 		uniform_data.resize(Utils::align(uniform_data.size(), base_aligment), 0);
28157 
28158 		for (GLuint i = 0; i < std::max(type.m_array_size, 1u); i++)
28159 		{
28160 			const std::vector<GLubyte>& type_uniform_data = type.m_type.GenerateData();
28161 			uniform_data.insert(uniform_data.end(), type_uniform_data.begin(), type_uniform_data.end());
28162 
28163 			if (type.m_array_size > 0)
28164 			{
28165 				uniform_data.resize(Utils::align(uniform_data.size(), base_aligment), 0);
28166 			}
28167 		}
28168 	}
28169 
28170 	const GLuint struct_aligment = Utils::align(max_aligment, Utils::Type::vec4.GetBaseAlignment(false));
28171 
28172 	if (test_case.m_nested_struct)
28173 	{
28174 		uniform_data.resize(Utils::align(uniform_data.size(), struct_aligment), 0);
28175 
28176 		const GLuint old_size = uniform_data.size();
28177 		uniform_data.resize(2 * old_size);
28178 		std::copy_n(uniform_data.begin(), old_size, uniform_data.begin() + old_size);
28179 	}
28180 
28181 	uniform_data.resize(Utils::align(uniform_data.size(), struct_aligment), 0);
28182 
28183 	Utils::s_rand = rand_start;
28184 	std::vector<GLubyte>	xfb_data;
28185 
28186 	GLuint max_type_size = 1;
28187 	for (const testType& type : test_case.m_types)
28188 	{
28189 		const GLuint basic_type_size = Utils::Type::GetTypeSize(type.m_type.m_basic_type);
28190 		max_type_size = std::max(max_type_size, basic_type_size);
28191 
28192 		/* Align per current type's aligment requirements */
28193 		xfb_data.resize(Utils::align(xfb_data.size(), basic_type_size), 0);
28194 
28195 		for (GLuint i = 0; i < std::max(type.m_array_size, 1u); i++)
28196 		{
28197 			const std::vector<GLubyte>& type_xfb_data = type.m_type.GenerateDataPacked();
28198 			xfb_data.insert(xfb_data.end(), type_xfb_data.begin(), type_xfb_data.end());
28199 		}
28200 	}
28201 
28202 	if (test_case.m_nested_struct)
28203 	{
28204 		/* Struct has aligment requirement equal to largest requirement of its members */
28205 		xfb_data.resize(Utils::align(xfb_data.size(), max_type_size), 0);
28206 
28207 		const GLuint old_size = xfb_data.size();
28208 		xfb_data.resize(2 * old_size);
28209 		std::copy_n(xfb_data.begin(), old_size, xfb_data.begin() + old_size);
28210 	}
28211 
28212 	xfb_data.resize(Utils::align(xfb_data.size(), max_type_size), 0);
28213 
28214 	const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
28215 	const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
28216 
28217 	/* Do not exceed the minimum value of MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS */
28218 	DE_ASSERT(xfb_type_size <= 64 * sizeof(GLuint));
28219 
28220 	/*
28221 	 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
28222 	 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
28223 	 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
28224 	 only one valid data should be initialized in xfb.m_expected_data
28225 	 */
28226 	const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
28227 	/* Uniform data */
28228 	uniform.m_initial_data.resize(uni_type_size);
28229 	memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
28230 
28231 	/* XFB data */
28232 	xfb.m_initial_data.resize(xfb_data_size, 0);
28233 	xfb.m_expected_data.resize(xfb_data_size);
28234 
28235 	if (test_case.m_stage == Utils::Shader::VERTEX)
28236 	{
28237 		memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
28238 	}
28239 	else
28240 	{
28241 		memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
28242 		memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
28243 	}
28244 }
28245 
28246 /** Get body of main function for given shader stage
28247  *
28248  * @param test_case_index  Index of test case
28249  * @param stage            Shader stage
28250  * @param out_assignments  Set to empty
28251  * @param out_calculations Set to empty
28252  **/
28253 void XFBExplicitLocationStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments,
28254 								  std::string& out_calculations)
28255 {
28256 	const testCase& test_case = m_test_cases[test_case_index];
28257 
28258 	out_calculations = "";
28259 
28260 	static const GLchar* vs_tes_gs = "    goku = uni_goku;\n";
28261 	static const GLchar* vs_tes_gs_nested = "    goku.inner_struct_a = uni_goku;\n"
28262 											"    goku.inner_struct_b = uni_goku;\n";
28263 
28264 	const GLchar* assignments = "";
28265 
28266 	if (test_case.m_stage == stage)
28267 	{
28268 		switch (stage)
28269 		{
28270 		case Utils::Shader::GEOMETRY:
28271 		case Utils::Shader::TESS_EVAL:
28272 		case Utils::Shader::VERTEX:
28273 			if (test_case.m_nested_struct)
28274 			{
28275 				assignments = vs_tes_gs_nested;
28276 			}
28277 			else
28278 			{
28279 				assignments = vs_tes_gs;
28280 			}
28281 			break;
28282 		default:
28283 			TCU_FAIL("Invalid enum");
28284 		}
28285 	}
28286 	else
28287 	{
28288 		switch (stage)
28289 		{
28290 		case Utils::Shader::FRAGMENT:
28291 			assignments = "";
28292 			break;
28293 		case Utils::Shader::GEOMETRY:
28294 		case Utils::Shader::TESS_CTRL:
28295 		case Utils::Shader::TESS_EVAL:
28296 		case Utils::Shader::VERTEX:
28297 			break;
28298 		default:
28299 			TCU_FAIL("Invalid enum");
28300 		}
28301 	}
28302 
28303 	out_assignments = assignments;
28304 }
28305 
28306 /** Get interface of shader
28307  *
28308  * @param test_case_index  Index of test case
28309  * @param stage            Shader stage
28310  * @param out_interface    Set to ""
28311  **/
28312 void XFBExplicitLocationStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface)
28313 {
28314 	static const GLchar* vs_tes_gs = "struct TestStruct {\n"
28315 									 "STRUCT_MEMBERS"
28316 									 "};\n"
28317 									 "layout (location = 0, xfb_offset = 0) flat out TestStruct goku;\n"
28318 									 "\n"
28319 									 "layout(std140, binding = 0) uniform Goku {\n"
28320 									 "    TestStruct uni_goku;\n"
28321 									 "};\n";
28322 
28323 	static const GLchar* vs_tes_gs_nested = "struct TestStruct {\n"
28324 											"STRUCT_MEMBERS"
28325 											"};\n"
28326 											"struct OuterStruct {\n"
28327 											"    TestStruct inner_struct_a;\n"
28328 											"    TestStruct inner_struct_b;\n"
28329 											"};\n"
28330 											"layout (location = 0, xfb_offset = 0) flat out OuterStruct goku;\n"
28331 											"\n"
28332 											"layout(std140, binding = 0) uniform Goku {\n"
28333 											"    TestStruct uni_goku;\n"
28334 											"};\n";
28335 
28336 	const testCase& test_case = m_test_cases[test_case_index];
28337 	const GLchar*   interface = "";
28338 
28339 	if (test_case.m_stage == stage)
28340 	{
28341 		switch (stage)
28342 		{
28343 		case Utils::Shader::GEOMETRY:
28344 		case Utils::Shader::TESS_EVAL:
28345 		case Utils::Shader::VERTEX:
28346 			if (test_case.m_nested_struct)
28347 			{
28348 				interface = vs_tes_gs_nested;
28349 			}
28350 			else
28351 			{
28352 				interface = vs_tes_gs;
28353 			}
28354 			break;
28355 		default:
28356 			TCU_FAIL("Invalid enum");
28357 		}
28358 	}
28359 	else
28360 	{
28361 		switch (stage)
28362 		{
28363 		case Utils::Shader::FRAGMENT:
28364 			interface = "";
28365 			break;
28366 		case Utils::Shader::GEOMETRY:
28367 		case Utils::Shader::TESS_CTRL:
28368 		case Utils::Shader::TESS_EVAL:
28369 		case Utils::Shader::VERTEX:
28370 			break;
28371 		default:
28372 			TCU_FAIL("Invalid enum");
28373 		}
28374 	}
28375 
28376 	out_interface = interface;
28377 
28378 	std::stringstream stream;
28379 
28380 	char member_name = 'a';
28381 	for (const testType& type : test_case.m_types)
28382 	{
28383 		stream << "   " << type.m_type.GetGLSLTypeName() << " " << member_name++;
28384 		if (type.m_array_size > 0)
28385 		{
28386 			stream << "[" << type.m_array_size << "]";
28387 		}
28388 		stream << ";\n";
28389 	}
28390 
28391 	Utils::replaceAllTokens("STRUCT_MEMBERS", stream.str().c_str(), out_interface);
28392 }
28393 
28394 /** Get source code of shader
28395  *
28396  * @param test_case_index Index of test case
28397  * @param stage           Shader stage
28398  *
28399  * @return Source
28400  **/
28401 std::string XFBExplicitLocationStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
28402 {
28403 	std::string		source;
28404 	const testCase& test_case = m_test_cases[test_case_index];
28405 
28406 	switch (test_case.m_stage)
28407 	{
28408 	case Utils::Shader::VERTEX:
28409 		switch (stage)
28410 		{
28411 		case Utils::Shader::FRAGMENT:
28412 		case Utils::Shader::VERTEX:
28413 			source = BufferTestBase::getShaderSource(test_case_index, stage);
28414 			break;
28415 		default:
28416 			break;
28417 		}
28418 		break;
28419 
28420 	case Utils::Shader::TESS_EVAL:
28421 		switch (stage)
28422 		{
28423 		case Utils::Shader::FRAGMENT:
28424 		case Utils::Shader::TESS_CTRL:
28425 		case Utils::Shader::TESS_EVAL:
28426 		case Utils::Shader::VERTEX:
28427 			source = BufferTestBase::getShaderSource(test_case_index, stage);
28428 			break;
28429 		default:
28430 			break;
28431 		}
28432 		break;
28433 
28434 	case Utils::Shader::GEOMETRY:
28435 		source = BufferTestBase::getShaderSource(test_case_index, stage);
28436 		break;
28437 
28438 	default:
28439 		TCU_FAIL("Invalid enum");
28440 	}
28441 
28442 	/* */
28443 	return source;
28444 }
28445 
28446 /** Get name of test case
28447  *
28448  * @param test_case_index Index of test case
28449  *
28450  * @return Name of tested stage
28451  **/
28452 std::string XFBExplicitLocationStructTest::getTestCaseName(glw::GLuint test_case_index)
28453 {
28454 	std::stringstream stream;
28455 	const testCase&   test_case = m_test_cases[test_case_index];
28456 
28457 	stream << "Struct: { ";
28458 
28459 	for (const testType& type : test_case.m_types)
28460 	{
28461 		stream << type.m_type.GetGLSLTypeName() << "@" << type.m_array_size << ", ";
28462 	}
28463 
28464 	stream << "}, stage: " << Utils::Shader::GetStageName(test_case.m_stage);
28465 
28466 	return stream.str();
28467 }
28468 
28469 /** Returns number of test cases
28470  *
28471  * @return TEST_MAX
28472  **/
28473 glw::GLuint XFBExplicitLocationStructTest::getTestCaseNumber()
28474 {
28475 	return static_cast<GLuint>(m_test_cases.size());
28476 }
28477 
28478 /** Prepare all test cases
28479  *
28480  **/
28481 void XFBExplicitLocationStructTest::testInit()
28482 {
28483 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
28484 	{
28485 		if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
28486 			(Utils::Shader::TESS_CTRL == stage))
28487 		{
28488 			continue;
28489 		}
28490 
28491 		const GLuint n_types = getTypesNumber();
28492 
28493 		for (GLuint i = 0; i < n_types; ++i)
28494 		{
28495 			const Utils::Type& type = getType(i);
28496 
28497 			m_test_cases.push_back(testCase{(Utils::Shader::STAGES) stage, { {Utils::Type::_float, 0}, {type, 0} }, false });
28498 		}
28499 
28500 		for (bool is_nested_struct : {false, true})
28501 		{
28502 			m_test_cases.push_back(testCase{(Utils::Shader::STAGES) stage, { {Utils::Type::_double, 0}, {Utils::Type::dvec2, 0}, {Utils::Type::dmat3, 0} }, is_nested_struct });
28503 			m_test_cases.push_back(testCase{(Utils::Shader::STAGES) stage, { {Utils::Type::_double, 0}, {Utils::Type::vec3, 0} }, is_nested_struct });
28504 			m_test_cases.push_back(testCase{(Utils::Shader::STAGES) stage, { {Utils::Type::dvec3, 0}, {Utils::Type::mat4x3, 0} }, is_nested_struct });
28505 			m_test_cases.push_back(testCase{(Utils::Shader::STAGES) stage, { {Utils::Type::_float, 0}, {Utils::Type::dvec3, 0}, {Utils::Type::_float, 0}, {Utils::Type::_double, 0} }, is_nested_struct });
28506 			m_test_cases.push_back(testCase{(Utils::Shader::STAGES) stage, { {Utils::Type::vec2, 0}, {Utils::Type::dvec3, 0}, {Utils::Type::_float, 0}, {Utils::Type::_double, 0} }, is_nested_struct });
28507 			m_test_cases.push_back(testCase{(Utils::Shader::STAGES) stage, { {Utils::Type::_double, 0}, {Utils::Type::_float, 0}, {Utils::Type::dvec2, 0}, {Utils::Type::vec3, 0} }, is_nested_struct });
28508 			m_test_cases.push_back(testCase{(Utils::Shader::STAGES) stage, { {Utils::Type::dmat3x4, 0}, {Utils::Type::_double, 0}, {Utils::Type::_float, 0}, {Utils::Type::dvec2, 0} }, is_nested_struct });
28509 
28510 			m_test_cases.push_back(testCase{(Utils::Shader::STAGES) stage, { {Utils::Type::_float, 3}, {Utils::Type::dvec3, 0}, {Utils::Type::_double, 2} }, is_nested_struct });
28511 			m_test_cases.push_back(testCase{(Utils::Shader::STAGES) stage, { {Utils::Type::_int, 1}, {Utils::Type::_double, 1}, {Utils::Type::_float, 1}, {Utils::Type::dmat2x4, 1} }, is_nested_struct });
28512 			m_test_cases.push_back(testCase{(Utils::Shader::STAGES) stage, { {Utils::Type::_int, 5}, {Utils::Type::dvec3, 2}, {Utils::Type::uvec3, 0}, {Utils::Type::_double, 1} }, is_nested_struct });
28513 			m_test_cases.push_back(testCase{(Utils::Shader::STAGES) stage, { {Utils::Type::mat2x3, 3}, {Utils::Type::uvec4, 1}, {Utils::Type::dvec4, 0} }, is_nested_struct });
28514 		}
28515 
28516 		m_test_cases.push_back(testCase{(Utils::Shader::STAGES) stage, { {Utils::Type::dmat2x3, 2}, {Utils::Type::mat2x3, 2}, {Utils::Type::dvec2, 0} }, false });
28517 	}
28518 }
28519 } /* EnhancedLayouts namespace */
28520 
28521 /** Constructor.
28522  *
28523  *  @param context Rendering context.
28524  **/
EnhancedLayoutsTests(deqp::Context & context)28525 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context& context)
28526 	: TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality")
28527 {
28528 	/* Left blank on purpose */
28529 }
28530 
28531 /** Initializes a texture_storage_multisample test group.
28532  *
28533  **/
init(void)28534 void EnhancedLayoutsTests::init(void)
28535 {
28536 	addChild(new EnhancedLayouts::APIConstantValuesTest(m_context));
28537 	addChild(new EnhancedLayouts::APIErrorsTest(m_context));
28538 	addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context));
28539 	addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context));
28540 	addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context));
28541 	addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context));
28542 	addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context));
28543 	addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context));
28544 	addChild(new EnhancedLayouts::VaryingInvalidValueComponentTest(m_context));
28545 	addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context));
28546 	addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context));
28547 	addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context));
28548 	addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context));
28549 	addChild(new EnhancedLayouts::XFBInputTest(m_context));
28550 	addChild(new EnhancedLayouts::XFBAllStagesTest(m_context));
28551 	addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context));
28552 	addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context));
28553 	addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context));
28554 	addChild(new EnhancedLayouts::XFBStrideTest(m_context));
28555 
28556 	addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context));
28557 	addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context));
28558 	addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context));
28559 	addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context));
28560 	addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context));
28561 	addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context));
28562 	addChild(new EnhancedLayouts::SSBAlignmentTest(m_context));
28563 	addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context));
28564 	addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context));
28565 	addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context));
28566 	addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context));
28567 	addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context));
28568 	addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context));
28569 	addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context));
28570 	addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context));
28571 	addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context));
28572 	addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context));
28573 	addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context));
28574 	addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context));
28575 	addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context));
28576 	addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context));
28577 	addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context));
28578 	addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context));
28579 	addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context));
28580 	addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context));
28581 	addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context));
28582 	addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context));
28583 	addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context));
28584 	addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context));
28585 	addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context));
28586 	addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context));
28587 	addChild(new EnhancedLayouts::VaryingLocationsTest(m_context));
28588 	addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context));
28589 	addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context));
28590 	addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context));
28591 	addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context));
28592 	addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context));
28593 	addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context));
28594 	addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context));
28595 	addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context));
28596 	addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context));
28597 	addChild(new EnhancedLayouts::XFBExplicitLocationTest(m_context));
28598 	addChild(new EnhancedLayouts::XFBExplicitLocationStructTest(m_context));
28599 	addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context));
28600 	addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context));
28601 	addChild(new EnhancedLayouts::VaryingComponentsTest(m_context));
28602 	addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context));
28603 }
28604 
28605 } /* gl4cts namespace */
28606