1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2015-2016 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */ /*!
20 * \file
21 * \brief
22 */ /*-------------------------------------------------------------------*/
23
24 /**
25 * \file gl4cEnhancedLayoutsTests.cpp
26 * \brief Implements conformance tests for "Enhanced Layouts" functionality.
27 */ /*-------------------------------------------------------------------*/
28
29 #include "gl4cEnhancedLayoutsTests.hpp"
30
31 #include "gluContextInfo.hpp"
32 #include "gluDefs.hpp"
33 #include "gluShaderUtil.hpp"
34 #include "gluStrUtil.hpp"
35 #include "glwEnums.hpp"
36 #include "glwFunctions.hpp"
37 #include "tcuTestLog.hpp"
38
39 #include <algorithm>
40 #include <iomanip>
41 #include <string>
42 #include <vector>
43
44 /* DEBUG */
45 #define USE_NSIGHT 0
46 #define DEBUG_ENBALE_MESSAGE_CALLBACK 0
47 #define DEBUG_NEG_LOG_ERROR 0
48 #define DEBUG_NEG_REMOVE_ERROR 0
49 #define DEBUG_REPLACE_TOKEN 0
50 #define DEBUG_REPEAT_TEST_CASE 0
51 #define DEBUG_REPEATED_TEST_CASE 0
52
53 /* Texture test base */
54 #define DEBUG_TTB_VERIFICATION_SNIPPET_STAGE 0
55 #define DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE 0
56
57 /* Tests */
58 #define DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE 0
59
60 /* WORKAROUNDS */
61 #define WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST 0
62 #define WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST 0
63 #define WRKARD_UNIFORMBLOCKALIGNMENT 0
64 #define WRKARD_VARYINGLOCATIONSTEST 0
65
66 using namespace glw;
67
68 namespace gl4cts
69 {
70 namespace EnhancedLayouts
71 {
72 namespace Utils
73 {
74 /** Constants used by "random" generators **/
75 static const GLuint s_rand_start = 3;
76 static const GLuint s_rand_max = 16;
77 static const GLuint s_rand_max_half = s_rand_max / 2;
78
79 /** Seed used by "random" generators **/
80 static GLuint s_rand = s_rand_start;
81
82 /** Get "random" unsigned int value
83 *
84 * @return Value
85 **/
GetRandUint()86 static GLuint GetRandUint()
87 {
88 const GLuint rand = s_rand++;
89
90 if (s_rand_max <= s_rand)
91 {
92 s_rand = s_rand_start;
93 }
94
95 return rand;
96 }
97
98 /** Get "random" int value
99 *
100 * @return Value
101 **/
GetRandInt()102 GLint GetRandInt()
103 {
104 const GLint rand = GetRandUint() - s_rand_max_half;
105
106 return rand;
107 }
108
109 /** Get "random" double value
110 *
111 * @return Value
112 **/
GetRandDouble()113 GLdouble GetRandDouble()
114 {
115 const GLint rand = GetRandInt();
116
117 GLdouble result = (GLfloat)rand / (GLdouble)s_rand_max_half;
118
119 return result;
120 }
121
122 /** Get "random" float value
123 *
124 * @return Value
125 **/
GetRandFloat()126 GLfloat GetRandFloat()
127 {
128 const GLint rand = GetRandInt();
129
130 GLfloat result = (GLfloat)rand / (GLfloat)s_rand_max_half;
131
132 return result;
133 }
134
135 /** String used by list routines **/
136 static const GLchar *const g_list = "LIST";
137
138 /** Type constants **/
139 const Type Type::_double = Type::GetType(Type::Double, 1, 1);
140 const Type Type::dmat2 = Type::GetType(Type::Double, 2, 2);
141 const Type Type::dmat2x3 = Type::GetType(Type::Double, 2, 3);
142 const Type Type::dmat2x4 = Type::GetType(Type::Double, 2, 4);
143 const Type Type::dmat3x2 = Type::GetType(Type::Double, 3, 2);
144 const Type Type::dmat3 = Type::GetType(Type::Double, 3, 3);
145 const Type Type::dmat3x4 = Type::GetType(Type::Double, 3, 4);
146 const Type Type::dmat4x2 = Type::GetType(Type::Double, 4, 2);
147 const Type Type::dmat4x3 = Type::GetType(Type::Double, 4, 3);
148 const Type Type::dmat4 = Type::GetType(Type::Double, 4, 4);
149 const Type Type::dvec2 = Type::GetType(Type::Double, 1, 2);
150 const Type Type::dvec3 = Type::GetType(Type::Double, 1, 3);
151 const Type Type::dvec4 = Type::GetType(Type::Double, 1, 4);
152 const Type Type::_int = Type::GetType(Type::Int, 1, 1);
153 const Type Type::ivec2 = Type::GetType(Type::Int, 1, 2);
154 const Type Type::ivec3 = Type::GetType(Type::Int, 1, 3);
155 const Type Type::ivec4 = Type::GetType(Type::Int, 1, 4);
156 const Type Type::_float = Type::GetType(Type::Float, 1, 1);
157 const Type Type::mat2 = Type::GetType(Type::Float, 2, 2);
158 const Type Type::mat2x3 = Type::GetType(Type::Float, 2, 3);
159 const Type Type::mat2x4 = Type::GetType(Type::Float, 2, 4);
160 const Type Type::mat3x2 = Type::GetType(Type::Float, 3, 2);
161 const Type Type::mat3 = Type::GetType(Type::Float, 3, 3);
162 const Type Type::mat3x4 = Type::GetType(Type::Float, 3, 4);
163 const Type Type::mat4x2 = Type::GetType(Type::Float, 4, 2);
164 const Type Type::mat4x3 = Type::GetType(Type::Float, 4, 3);
165 const Type Type::mat4 = Type::GetType(Type::Float, 4, 4);
166 const Type Type::vec2 = Type::GetType(Type::Float, 1, 2);
167 const Type Type::vec3 = Type::GetType(Type::Float, 1, 3);
168 const Type Type::vec4 = Type::GetType(Type::Float, 1, 4);
169 const Type Type::uint = Type::GetType(Type::Uint, 1, 1);
170 const Type Type::uvec2 = Type::GetType(Type::Uint, 1, 2);
171 const Type Type::uvec3 = Type::GetType(Type::Uint, 1, 3);
172 const Type Type::uvec4 = Type::GetType(Type::Uint, 1, 4);
173
174 /** Generate data for type. This routine follows STD140 rules
175 *
176 * @return Vector of bytes filled with data
177 **/
GenerateData() const178 std::vector<GLubyte> Type::GenerateData() const
179 {
180 const GLuint alignment = GetActualAlignment(0, false);
181 const GLuint padding = alignment - GetTypeSize(m_basic_type) * m_n_rows;
182 const GLuint data_size = alignment * m_n_columns - padding;
183
184 std::vector<GLubyte> data;
185 data.resize(data_size);
186
187 for (GLuint column = 0; column < m_n_columns; ++column)
188 {
189 GLvoid *ptr = (GLvoid *)&data[column * alignment];
190
191 switch (m_basic_type)
192 {
193 case Double:
194 {
195 GLdouble *d_ptr = (GLdouble *)ptr;
196
197 for (GLuint i = 0; i < m_n_rows; ++i)
198 {
199 d_ptr[i] = GetRandDouble();
200 }
201 }
202 break;
203 case Float:
204 {
205 GLfloat *f_ptr = (GLfloat *)ptr;
206
207 for (GLuint i = 0; i < m_n_rows; ++i)
208 {
209 f_ptr[i] = GetRandFloat();
210 }
211 }
212 break;
213 case Int:
214 {
215 GLint *i_ptr = (GLint *)ptr;
216
217 for (GLuint i = 0; i < m_n_rows; ++i)
218 {
219 i_ptr[i] = GetRandInt();
220 }
221 }
222 break;
223 case Uint:
224 {
225 GLuint *ui_ptr = (GLuint *)ptr;
226
227 for (GLuint i = 0; i < m_n_rows; ++i)
228 {
229 ui_ptr[i] = GetRandUint();
230 }
231 }
232 break;
233 }
234 }
235
236 return data;
237 }
238
239 /** Generate data for type. This routine packs data tightly.
240 *
241 * @return Vector of bytes filled with data
242 **/
GenerateDataPacked() const243 std::vector<GLubyte> Type::GenerateDataPacked() const
244 {
245 const GLuint basic_size = GetTypeSize(m_basic_type);
246 const GLuint n_elements = m_n_columns * m_n_rows;
247 const GLuint size = basic_size * n_elements;
248
249 std::vector<GLubyte> data;
250 data.resize(size);
251
252 GLvoid *ptr = (GLvoid *)&data[0];
253
254 switch (m_basic_type)
255 {
256 case Double:
257 {
258 GLdouble *d_ptr = (GLdouble *)ptr;
259
260 for (GLuint i = 0; i < n_elements; ++i)
261 {
262 d_ptr[i] = GetRandDouble();
263 }
264 }
265 break;
266 case Float:
267 {
268 GLfloat *f_ptr = (GLfloat *)ptr;
269
270 for (GLuint i = 0; i < n_elements; ++i)
271 {
272 f_ptr[i] = GetRandFloat();
273 }
274 }
275 break;
276 case Int:
277 {
278 GLint *i_ptr = (GLint *)ptr;
279
280 for (GLuint i = 0; i < n_elements; ++i)
281 {
282 i_ptr[i] = GetRandInt();
283 }
284 }
285 break;
286 case Uint:
287 {
288 GLuint *ui_ptr = (GLuint *)ptr;
289
290 for (GLuint i = 0; i < n_elements; ++i)
291 {
292 ui_ptr[i] = GetRandUint();
293 }
294 }
295 break;
296 }
297
298 return data;
299 }
300
301 /** Calculate "actual alignment". It work under assumption that align value is valid
302 *
303 * @param align Requested alignment, eg with "align" qualifier
304 * @param is_array Selects if an array of type or single instance should be considered
305 *
306 * @return Calculated value
307 **/
GetActualAlignment(GLuint align,bool is_array) const308 GLuint Type::GetActualAlignment(GLuint align, bool is_array) const
309 {
310 const GLuint base_alignment = GetBaseAlignment(is_array);
311
312 return std::max(align, base_alignment);
313 }
314
315 /** Align given ofset with specified alignment
316 *
317 * @param offset Offset
318 * @param alignment Alignment
319 *
320 * @return Calculated value
321 **/
align(GLuint offset,GLuint alignment)322 GLuint align(GLuint offset, GLuint alignment)
323 {
324 const GLuint rest = offset % alignment;
325
326 if (0 != rest)
327 {
328 GLuint missing = alignment - rest;
329 offset += missing;
330 }
331
332 return offset;
333 }
334
335 /** Calculate "actual offset"
336 *
337 * @param start_offset Requested offset
338 * @param actual_alignment Actual alignemnt
339 *
340 * @return Calculated value
341 **/
GetActualOffset(GLuint start_offset,GLuint actual_alignment)342 GLuint Type::GetActualOffset(GLuint start_offset, GLuint actual_alignment)
343 {
344 GLuint offset = align(start_offset, actual_alignment);
345
346 return offset;
347 }
348
349 /** Calculate "base alignment" for given type
350 *
351 * @param is_array Select if array or single instance should be considered
352 *
353 * @return Calculated value
354 **/
GetBaseAlignment(bool is_array) const355 GLuint Type::GetBaseAlignment(bool is_array) const
356 {
357 GLuint elements = 1;
358
359 switch (m_n_rows)
360 {
361 case 2:
362 elements = 2;
363 break;
364 case 3:
365 case 4:
366 elements = 4;
367 break;
368 default:
369 break;
370 }
371
372 GLuint N = GetTypeSize(m_basic_type);
373 GLuint alignment = N * elements;
374
375 if ((true == is_array) || (1 != m_n_columns))
376 {
377 alignment = align(alignment, 16 /* vec4 alignment */);
378 }
379
380 return alignment;
381 }
382
383 /** Returns string representing GLSL constructor of type with arguments provided in data
384 *
385 * @param data Array of values that will be used as construcotr arguments.
386 * It is interpreted as tightly packed array of type matching this type.
387 *
388 * @return String in form "Type(args)"
389 **/
GetGLSLConstructor(const GLvoid * data) const390 std::string Type::GetGLSLConstructor(const GLvoid *data) const
391 {
392 const GLchar *type = GetGLSLTypeName();
393
394 std::stringstream stream;
395
396 stream << type << "(";
397
398 /* Scalar or vector */
399 if (1 == m_n_columns)
400 {
401 for (GLuint row = 0; row < m_n_rows; ++row)
402 {
403 switch (m_basic_type)
404 {
405 case Double:
406 stream << ((GLdouble *)data)[row];
407 break;
408 case Float:
409 stream << ((GLfloat *)data)[row];
410 break;
411 case Int:
412 stream << ((GLint *)data)[row];
413 break;
414 case Uint:
415 stream << ((GLuint *)data)[row];
416 break;
417 }
418
419 if (row + 1 != m_n_rows)
420 {
421 stream << ", ";
422 }
423 }
424 }
425 else /* Matrix: mat(vec(), vec() .. ) */
426 {
427 const GLuint basic_size = GetTypeSize(m_basic_type);
428 // Very indescoverable defect, the column stride should be calculated by rows, such as mat2x3, which is 2, columns 3 rows, its column stride should be 3 * sizeof(float)
429 const GLuint column_stride = m_n_rows * basic_size;
430 const Type column_type = GetType(m_basic_type, 1, m_n_rows);
431
432 for (GLuint column = 0; column < m_n_columns; ++column)
433 {
434 const GLuint column_offset = column * column_stride;
435 const GLvoid *column_data = (GLubyte *)data + column_offset;
436
437 stream << column_type.GetGLSLConstructor(column_data);
438
439 if (column + 1 != m_n_columns)
440 {
441 stream << ", ";
442 }
443 }
444 }
445
446 stream << ")";
447
448 return stream.str();
449 }
450
451 /** Get glsl name of the type
452 *
453 * @return Name of glsl type
454 **/
GetGLSLTypeName() const455 const glw::GLchar *Type::GetGLSLTypeName() const
456 {
457 static const GLchar *float_lut[4][4] = {
458 {"float", "vec2", "vec3", "vec4"},
459 {0, "mat2", "mat2x3", "mat2x4"},
460 {0, "mat3x2", "mat3", "mat3x4"},
461 {0, "mat4x2", "mat4x3", "mat4"},
462 };
463
464 static const GLchar *double_lut[4][4] = {
465 {"double", "dvec2", "dvec3", "dvec4"},
466 {0, "dmat2", "dmat2x3", "dmat2x4"},
467 {0, "dmat3x2", "dmat3", "dmat3x4"},
468 {0, "dmat4x2", "dmat4x3", "dmat4"},
469 };
470
471 static const GLchar *int_lut[4] = {"int", "ivec2", "ivec3", "ivec4"};
472
473 static const GLchar *uint_lut[4] = {"uint", "uvec2", "uvec3", "uvec4"};
474
475 const GLchar *result = 0;
476
477 if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
478 {
479 return 0;
480 }
481
482 switch (m_basic_type)
483 {
484 case Float:
485 result = float_lut[m_n_columns - 1][m_n_rows - 1];
486 break;
487 case Double:
488 result = double_lut[m_n_columns - 1][m_n_rows - 1];
489 break;
490 case Int:
491 result = int_lut[m_n_rows - 1];
492 break;
493 case Uint:
494 result = uint_lut[m_n_rows - 1];
495 break;
496 default:
497 TCU_FAIL("Invalid enum");
498 }
499
500 return result;
501 }
502
503 /** Get number of locations required for the type
504 *
505 * @return Number of columns times:
506 * - 2 when type is double with 3 or 4 rows,
507 * - 1 otherwise or if it's a vertex shader input.
508 **/
GetLocations(bool is_vs_input) const509 GLuint Type::GetLocations(bool is_vs_input) const
510 {
511 GLuint n_loc_per_column;
512
513 /* 1 or 2 doubles any for rest */
514 if ((2 >= m_n_rows) || (Double != m_basic_type) || is_vs_input)
515 {
516 n_loc_per_column = 1;
517 }
518 else
519 {
520 /* 3 and 4 doubles */
521 n_loc_per_column = 2;
522 }
523
524 return n_loc_per_column * m_n_columns;
525 }
526
527 /** Get size of the type in bytes.
528 * Note that this routine doesn't consider arrays and assumes
529 * column_major matrices.
530 *
531 * @return Formula:
532 * - If std140 packaging and matrix; number of columns * base alignment
533 * - Otherwise; number of elements * sizeof(base_type)
534 **/
GetSize(const bool is_std140) const535 GLuint Type::GetSize(const bool is_std140) const
536 {
537 const GLuint basic_type_size = GetTypeSize(m_basic_type);
538 const GLuint n_elements = m_n_columns * m_n_rows;
539
540 if (is_std140 && m_n_columns > 1)
541 {
542 return m_n_columns * GetBaseAlignment(false);
543 }
544
545 return basic_type_size * n_elements;
546 }
547
548 /** Get GLenum representing the type
549 *
550 * @return GLenum
551 **/
GetTypeGLenum() const552 GLenum Type::GetTypeGLenum() const
553 {
554 static const GLenum float_lut[4][4] = {
555 {GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4},
556 {0, GL_FLOAT_MAT2, GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4},
557 {0, GL_FLOAT_MAT3x2, GL_FLOAT_MAT3, GL_FLOAT_MAT3x4},
558 {0, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3, GL_FLOAT_MAT4},
559 };
560
561 static const GLenum double_lut[4][4] = {
562 {GL_DOUBLE, GL_DOUBLE_VEC2, GL_DOUBLE_VEC3, GL_DOUBLE_VEC4},
563 {0, GL_DOUBLE_MAT2, GL_DOUBLE_MAT2x3, GL_DOUBLE_MAT2x4},
564 {0, GL_DOUBLE_MAT3x2, GL_DOUBLE_MAT3, GL_DOUBLE_MAT3x4},
565 {0, GL_DOUBLE_MAT4x2, GL_DOUBLE_MAT4x3, GL_DOUBLE_MAT4},
566 };
567
568 static const GLenum int_lut[4] = {GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4};
569
570 static const GLenum uint_lut[4] = {GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
571 GL_UNSIGNED_INT_VEC4};
572
573 GLenum result = 0;
574
575 if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
576 {
577 return 0;
578 }
579
580 switch (m_basic_type)
581 {
582 case Float:
583 result = float_lut[m_n_columns - 1][m_n_rows - 1];
584 break;
585 case Double:
586 result = double_lut[m_n_columns - 1][m_n_rows - 1];
587 break;
588 case Int:
589 result = int_lut[m_n_rows - 1];
590 break;
591 case Uint:
592 result = uint_lut[m_n_rows - 1];
593 break;
594 default:
595 TCU_FAIL("Invalid enum");
596 }
597
598 return result;
599 }
600
601 /** Calculate the number of components consumed by a type
602 * according to 11.1.2.1 Output Variables
603 *
604 * @return Calculated number of components for the type
605 **/
GetNumComponents() const606 GLuint Type::GetNumComponents() const
607 {
608 // Rule 3 of Section 7.6.2.2
609 // If the member is a three-component vector with components consuming N
610 // basic machine units, the base alignment is 4N.
611 GLuint num_components = (m_n_rows == 3 ? 4 : m_n_rows) * m_n_columns;
612
613 if (m_basic_type == Double)
614 {
615 num_components *= 2;
616 }
617
618 return num_components;
619 }
620
621 /** Calculate the valid values to use with the component qualifier
622 *
623 * @return Vector with the valid values, in growing order, or empty if
624 * the component qualifier is not allowed
625 **/
GetValidComponents() const626 std::vector<GLuint> Type::GetValidComponents() const
627 {
628 const GLuint component_size = Utils::Type::Double == m_basic_type ? 2 : 1;
629 const GLuint n_components_per_location = Utils::Type::Double == m_basic_type ? 2 : 4;
630 const GLuint n_req_components = m_n_rows;
631 const GLint max_valid_component = (GLint)n_components_per_location - (GLint)n_req_components;
632 std::vector<GLuint> data;
633
634 /* The component qualifier cannot be used for matrices */
635 if (1 != m_n_columns)
636 {
637 return data;
638 }
639
640 /* The component qualifier cannot be used for dvec3/dvec4 */
641 if (max_valid_component < 0)
642 {
643 return data;
644 }
645
646 for (GLuint i = 0; i <= (GLuint)max_valid_component; ++i)
647 {
648 data.push_back(i * component_size);
649 }
650
651 return data;
652 }
653
654 /** Calculate stride for the type according to std140 rules
655 *
656 * @param alignment Alignment of type
657 * @param n_columns Number of columns
658 * @param n_array_elements Number of elements in array
659 *
660 * @return Calculated value
661 **/
CalculateStd140Stride(GLuint alignment,GLuint n_columns,GLuint n_array_elements)662 GLuint Type::CalculateStd140Stride(GLuint alignment, GLuint n_columns, GLuint n_array_elements)
663 {
664 GLuint stride = alignment * n_columns;
665 if (0 != n_array_elements)
666 {
667 stride *= n_array_elements;
668 }
669
670 return stride;
671 }
672
673 /** Check if glsl support matrices for specific basic type
674 *
675 * @param type Basic type
676 *
677 * @return true if matrices of <type> are supported, false otherwise
678 **/
DoesTypeSupportMatrix(TYPES type)679 bool Type::DoesTypeSupportMatrix(TYPES type)
680 {
681 bool result = false;
682
683 switch (type)
684 {
685 case Float:
686 case Double:
687 result = true;
688 break;
689 case Int:
690 case Uint:
691 result = false;
692 break;
693 default:
694 TCU_FAIL("Invalid enum");
695 }
696
697 return result;
698 }
699
700 /** Creates instance of Type
701 *
702 * @param basic_type Select basic type of instance
703 * @param n_columns Number of columns
704 * @param n_rows Number of rows
705 *
706 * @return Type instance
707 **/
GetType(TYPES basic_type,glw::GLuint n_columns,glw::GLuint n_rows)708 Type Type::GetType(TYPES basic_type, glw::GLuint n_columns, glw::GLuint n_rows)
709 {
710 Type type = {basic_type, n_columns, n_rows};
711
712 return type;
713 }
714
715 /** Get Size of given type in bytes
716 *
717 * @param type
718 *
719 * @return Size of type
720 **/
GetTypeSize(TYPES type)721 GLuint Type::GetTypeSize(TYPES type)
722 {
723 GLuint result = 0;
724
725 switch (type)
726 {
727 case Float:
728 result = sizeof(GLfloat);
729 break;
730 case Double:
731 result = sizeof(GLdouble);
732 break;
733 case Int:
734 result = sizeof(GLint);
735 break;
736 case Uint:
737 result = sizeof(GLuint);
738 break;
739 default:
740 TCU_FAIL("Invalid enum");
741 }
742
743 return result;
744 }
745
746 /** Get GLenum representing given type
747 *
748 * @param type
749 *
750 * @return GLenum value
751 **/
GetTypeGLenum(TYPES type)752 GLenum Type::GetTypeGLenum(TYPES type)
753 {
754 GLenum result = 0;
755
756 switch (type)
757 {
758 case Float:
759 result = GL_FLOAT;
760 break;
761 case Double:
762 result = GL_DOUBLE;
763 break;
764 case Int:
765 result = GL_INT;
766 break;
767 case Uint:
768 result = GL_UNSIGNED_INT;
769 break;
770 default:
771 TCU_FAIL("Invalid enum");
772 }
773
774 return result;
775 }
776
777 /** Check if two types can share the same location, based on the underlying numerical type and bit width
778 *
779 * @param first First type to compare
780 * @param second Second type to compare
781 *
782 * @return true if the types can share the same location
783 **/
CanTypesShareLocation(TYPES first,TYPES second)784 bool Type::CanTypesShareLocation(TYPES first, TYPES second)
785 {
786 if (first == second)
787 {
788 return true;
789 }
790
791 if (Float == first || Float == second || Double == first || Double == second)
792 {
793 return false;
794 }
795
796 return true;
797 }
798
799 /** Get proper glUniformNdv routine for vectors with specified number of rows
800 *
801 * @param gl GL functions
802 * @param n_rows Number of rows
803 *
804 * @return Function address
805 **/
getUniformNdv(const glw::Functions & gl,glw::GLuint n_rows)806 uniformNdv getUniformNdv(const glw::Functions &gl, glw::GLuint n_rows)
807 {
808 uniformNdv result = 0;
809
810 switch (n_rows)
811 {
812 case 1:
813 result = gl.uniform1dv;
814 break;
815 case 2:
816 result = gl.uniform2dv;
817 break;
818 case 3:
819 result = gl.uniform3dv;
820 break;
821 case 4:
822 result = gl.uniform4dv;
823 break;
824 default:
825 TCU_FAIL("Invalid number of rows");
826 }
827
828 return result;
829 }
830
831 /** Get proper glUniformNfv routine for vectors with specified number of rows
832 *
833 * @param gl GL functions
834 * @param n_rows Number of rows
835 *
836 * @return Function address
837 **/
getUniformNfv(const glw::Functions & gl,glw::GLuint n_rows)838 uniformNfv getUniformNfv(const glw::Functions &gl, glw::GLuint n_rows)
839 {
840 uniformNfv result = 0;
841
842 switch (n_rows)
843 {
844 case 1:
845 result = gl.uniform1fv;
846 break;
847 case 2:
848 result = gl.uniform2fv;
849 break;
850 case 3:
851 result = gl.uniform3fv;
852 break;
853 case 4:
854 result = gl.uniform4fv;
855 break;
856 default:
857 TCU_FAIL("Invalid number of rows");
858 }
859
860 return result;
861 }
862
863 /** Get proper glUniformNiv routine for vectors with specified number of rows
864 *
865 * @param gl GL functions
866 * @param n_rows Number of rows
867 *
868 * @return Function address
869 **/
getUniformNiv(const glw::Functions & gl,glw::GLuint n_rows)870 uniformNiv getUniformNiv(const glw::Functions &gl, glw::GLuint n_rows)
871 {
872 uniformNiv result = 0;
873
874 switch (n_rows)
875 {
876 case 1:
877 result = gl.uniform1iv;
878 break;
879 case 2:
880 result = gl.uniform2iv;
881 break;
882 case 3:
883 result = gl.uniform3iv;
884 break;
885 case 4:
886 result = gl.uniform4iv;
887 break;
888 default:
889 TCU_FAIL("Invalid number of rows");
890 }
891
892 return result;
893 }
894
895 /** Get proper glUniformNuiv routine for vectors with specified number of rows
896 *
897 * @param gl GL functions
898 * @param n_rows Number of rows
899 *
900 * @return Function address
901 **/
getUniformNuiv(const glw::Functions & gl,glw::GLuint n_rows)902 uniformNuiv getUniformNuiv(const glw::Functions &gl, glw::GLuint n_rows)
903 {
904 uniformNuiv result = 0;
905
906 switch (n_rows)
907 {
908 case 1:
909 result = gl.uniform1uiv;
910 break;
911 case 2:
912 result = gl.uniform2uiv;
913 break;
914 case 3:
915 result = gl.uniform3uiv;
916 break;
917 case 4:
918 result = gl.uniform4uiv;
919 break;
920 default:
921 TCU_FAIL("Invalid number of rows");
922 }
923
924 return result;
925 }
926
927 /** Get proper glUniformMatrixNdv routine for matrix with specified number of columns and rows
928 *
929 * @param gl GL functions
930 * @param n_rows Number of rows
931 *
932 * @return Function address
933 **/
getUniformMatrixNdv(const glw::Functions & gl,glw::GLuint n_columns,glw::GLuint n_rows)934 uniformMatrixNdv getUniformMatrixNdv(const glw::Functions &gl, glw::GLuint n_columns, glw::GLuint n_rows)
935 {
936 uniformMatrixNdv result = 0;
937
938 switch (n_columns)
939 {
940 case 2:
941 switch (n_rows)
942 {
943 case 2:
944 result = gl.uniformMatrix2dv;
945 break;
946 case 3:
947 result = gl.uniformMatrix2x3dv;
948 break;
949 case 4:
950 result = gl.uniformMatrix2x4dv;
951 break;
952 default:
953 TCU_FAIL("Invalid number of rows");
954 }
955 break;
956 case 3:
957 switch (n_rows)
958 {
959 case 2:
960 result = gl.uniformMatrix3x2dv;
961 break;
962 case 3:
963 result = gl.uniformMatrix3dv;
964 break;
965 case 4:
966 result = gl.uniformMatrix3x4dv;
967 break;
968 default:
969 TCU_FAIL("Invalid number of rows");
970 }
971 break;
972 case 4:
973 switch (n_rows)
974 {
975 case 2:
976 result = gl.uniformMatrix4x2dv;
977 break;
978 case 3:
979 result = gl.uniformMatrix4x3dv;
980 break;
981 case 4:
982 result = gl.uniformMatrix4dv;
983 break;
984 default:
985 TCU_FAIL("Invalid number of rows");
986 }
987 break;
988 default:
989 TCU_FAIL("Invalid number of columns");
990 }
991
992 return result;
993 }
994
995 /** Get proper glUniformMatrixNfv routine for vectors with specified number of columns and rows
996 *
997 * @param gl GL functions
998 * @param n_rows Number of rows
999 *
1000 * @return Function address
1001 **/
getUniformMatrixNfv(const glw::Functions & gl,glw::GLuint n_columns,glw::GLuint n_rows)1002 uniformMatrixNfv getUniformMatrixNfv(const glw::Functions &gl, glw::GLuint n_columns, glw::GLuint n_rows)
1003 {
1004 uniformMatrixNfv result = 0;
1005
1006 switch (n_columns)
1007 {
1008 case 2:
1009 switch (n_rows)
1010 {
1011 case 2:
1012 result = gl.uniformMatrix2fv;
1013 break;
1014 case 3:
1015 result = gl.uniformMatrix2x3fv;
1016 break;
1017 case 4:
1018 result = gl.uniformMatrix2x4fv;
1019 break;
1020 default:
1021 TCU_FAIL("Invalid number of rows");
1022 }
1023 break;
1024 case 3:
1025 switch (n_rows)
1026 {
1027 case 2:
1028 result = gl.uniformMatrix3x2fv;
1029 break;
1030 case 3:
1031 result = gl.uniformMatrix3fv;
1032 break;
1033 case 4:
1034 result = gl.uniformMatrix3x4fv;
1035 break;
1036 default:
1037 TCU_FAIL("Invalid number of rows");
1038 }
1039 break;
1040 case 4:
1041 switch (n_rows)
1042 {
1043 case 2:
1044 result = gl.uniformMatrix4x2fv;
1045 break;
1046 case 3:
1047 result = gl.uniformMatrix4x3fv;
1048 break;
1049 case 4:
1050 result = gl.uniformMatrix4fv;
1051 break;
1052 default:
1053 TCU_FAIL("Invalid number of rows");
1054 }
1055 break;
1056 default:
1057 TCU_FAIL("Invalid number of columns");
1058 }
1059
1060 return result;
1061 }
1062
verifyVarying(Program & program,const std::string & parent_name,const Variable::Descriptor & desc,std::stringstream & stream,bool is_input)1063 bool verifyVarying(Program &program, const std::string &parent_name, const Variable::Descriptor &desc,
1064 std::stringstream &stream, bool is_input)
1065 {
1066 GLint component = 0;
1067 GLuint index = 0;
1068 GLenum interface = GL_PROGRAM_INPUT;
1069 GLint location = 0;
1070
1071 if (false == is_input)
1072 {
1073 interface = GL_PROGRAM_OUTPUT;
1074 }
1075
1076 const std::string &name = Utils::Variable::GetReference(parent_name, desc, Utils::Variable::BASIC, 0);
1077
1078 try
1079 {
1080 index = program.GetResourceIndex(name, interface);
1081
1082 program.GetResource(interface, index, GL_LOCATION, 1 /* size */, &location);
1083 program.GetResource(interface, index, GL_LOCATION_COMPONENT, 1 /* size */, &component);
1084 }
1085 catch (std::exception &exc)
1086 {
1087 stream << "Failed to query program for varying: " << desc.m_name << ". Reason: " << exc.what() << "\n";
1088
1089 return false;
1090 }
1091
1092 bool result = true;
1093
1094 if (location != desc.m_expected_location)
1095 {
1096 stream << "Attribute: " << desc.m_name << " - invalid location: " << location
1097 << " expected: " << desc.m_expected_location << std::endl;
1098 result = false;
1099 }
1100 if (component != desc.m_expected_component)
1101 {
1102 stream << "Attribute: " << desc.m_name << " - invalid component: " << component
1103 << " expected: " << desc.m_expected_component << std::endl;
1104 result = false;
1105 }
1106
1107 return result;
1108 }
1109
1110 /** Query program resource for given variable and verify that everything is as expected
1111 *
1112 * @param program Program object
1113 * @param variable Variable object
1114 * @param stream Stream that will be used to log any error
1115 * @param is_input Selects if varying is input or output
1116 *
1117 * @return true if verification is positive, false otherwise
1118 **/
checkVarying(Program & program,Shader::STAGES stage,const Variable & variable,std::stringstream & stream,bool is_input)1119 bool checkVarying(Program &program, Shader::STAGES stage, const Variable &variable, std::stringstream &stream,
1120 bool is_input)
1121 {
1122 bool result = true;
1123
1124 if (variable.IsBlock())
1125 {
1126 Utils::Interface *interface = variable.m_descriptor.m_interface;
1127 const size_t n_members = interface->m_members.size();
1128
1129 for (size_t i = 0; i < n_members; ++i)
1130 {
1131 const Variable::Descriptor &member = interface->m_members[i];
1132 bool member_result = verifyVarying(program, interface->m_name, member, stream, is_input);
1133
1134 if (false == member_result)
1135 {
1136 result = false;
1137 }
1138 }
1139 }
1140 /*
1141 To query the the location of struct member by glGetProgramResource, we need pass the variable name "gs_fs_output[0].single",
1142 but in original implementation, the test pass the name "Data.single", which can't get any valid result.
1143 struct Data {
1144 dmat2 single;
1145 dmat2 array[1];
1146 };
1147 layout (location = 0) in Data gs_fs_output[1];
1148 */
1149 else if (variable.IsStruct())
1150 {
1151 Utils::Interface *interface = variable.m_descriptor.m_interface;
1152 const size_t n_members = interface->m_members.size();
1153 std::string structVariable = variable.m_descriptor.m_name;
1154
1155 switch (Variable::GetFlavour(stage, is_input ? Variable::INPUT : Variable::OUTPUT))
1156 {
1157 case Variable::ARRAY:
1158 case Variable::INDEXED_BY_INVOCATION_ID:
1159 structVariable.append("[0]");
1160 break;
1161 default:
1162 break;
1163 }
1164
1165 // If struct variable is an array
1166 if (0 != variable.m_descriptor.m_n_array_elements)
1167 {
1168 for (GLuint i = 0; i < variable.m_descriptor.m_n_array_elements; i++)
1169 {
1170 GLchar buffer[16];
1171 sprintf(buffer, "%d", i);
1172 structVariable.append("[");
1173 structVariable.append(buffer);
1174 structVariable.append("]");
1175 for (size_t j = 0; j < n_members; ++j)
1176 {
1177 const Variable::Descriptor &member = interface->m_members[j];
1178 bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1179
1180 if (false == member_result)
1181 {
1182 result = false;
1183 }
1184 }
1185 }
1186 }
1187 else
1188 {
1189 for (GLuint i = 0; i < n_members; ++i)
1190 {
1191 const Variable::Descriptor &member = interface->m_members[i];
1192 bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1193
1194 if (false == member_result)
1195 {
1196 result = false;
1197 }
1198 }
1199 }
1200 }
1201 else
1202 {
1203 result = verifyVarying(program, "", variable.m_descriptor, stream, is_input);
1204 }
1205 return result;
1206 }
1207
1208 /** Query program resource for given variable and verify that everything is as expected
1209 *
1210 * @param program Program object
1211 * @param variable Variable object
1212 * @param stream Stream that will be used to log any error
1213 *
1214 * @return true if verification is positive, false otherwise
1215 **/
checkUniform(Program & program,const Utils::Variable & variable,std::stringstream & stream)1216 bool checkUniform(Program &program, const Utils::Variable &variable, std::stringstream &stream)
1217 {
1218 bool result = true;
1219
1220 if (false == variable.IsBlock())
1221 {
1222 TCU_FAIL("Not implemented");
1223 }
1224 else
1225 {
1226 Utils::Interface *interface = variable.m_descriptor.m_interface;
1227
1228 size_t size = interface->m_members.size();
1229
1230 std::vector<GLuint> indices;
1231 std::vector<const char *> names;
1232 std::vector<std::string> names_str;
1233 std::vector<GLint> offsets;
1234
1235 indices.resize(size);
1236 names.resize(size);
1237 names_str.resize(size);
1238 offsets.resize(size);
1239
1240 for (size_t i = 0; i < size; ++i)
1241 {
1242 indices[i] = 0;
1243 offsets[i] = 0;
1244
1245 const std::string &name =
1246 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1247
1248 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1249 {
1250 const std::string &member_name = Utils::Variable::GetReference(
1251 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1252
1253 names_str[i] = member_name;
1254 }
1255 else
1256 {
1257 names_str[i] = name;
1258 }
1259
1260 names[i] = names_str[i].c_str();
1261 }
1262
1263 try
1264 {
1265 program.GetUniformIndices(static_cast<glw::GLsizei>(size), &names[0], &indices[0]);
1266 program.GetActiveUniformsiv(static_cast<glw::GLsizei>(size), &indices[0], GL_UNIFORM_OFFSET, &offsets[0]);
1267 }
1268 catch (std::exception &exc)
1269 {
1270 stream << "Failed to query program for uniforms in block: " << variable.m_descriptor.m_name
1271 << ". Reason: " << exc.what() << "\n";
1272
1273 return false;
1274 }
1275
1276 for (size_t i = 0; i < size; ++i)
1277 {
1278 Utils::Variable::Descriptor &desc = interface->m_members[i];
1279
1280 if (offsets[i] != (GLint)desc.m_offset)
1281 {
1282 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offsets[i]
1283 << " expected: " << desc.m_offset << std::endl;
1284 result = false;
1285 }
1286 }
1287 }
1288
1289 return result;
1290 }
1291
1292 /** Query program resource for given variable and verify that everything is as expected
1293 *
1294 * @param program Program object
1295 * @param variable Variable object
1296 * @param stream Stream that will be used to log any error
1297 *
1298 * @return true if verification is positive, false otherwise
1299 **/
checkSSB(Program & program,const Utils::Variable & variable,std::stringstream & stream)1300 bool checkSSB(Program &program, const Utils::Variable &variable, std::stringstream &stream)
1301 {
1302 bool result = true;
1303
1304 if (false == variable.IsBlock())
1305 {
1306 TCU_FAIL("Not implemented");
1307 }
1308 else
1309 {
1310 Utils::Interface *interface = variable.m_descriptor.m_interface;
1311
1312 size_t size = interface->m_members.size();
1313
1314 for (size_t i = 0; i < size; ++i)
1315 {
1316 GLuint index = 0;
1317 std::string name_str = "";
1318 GLint offset = 0;
1319
1320 const std::string &name =
1321 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1322
1323 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1324 {
1325 const std::string &member_name = Utils::Variable::GetReference(
1326 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1327
1328 name_str = member_name;
1329 }
1330 else
1331 {
1332 name_str = name;
1333 }
1334
1335 try
1336 {
1337 index = program.GetResourceIndex(name_str, GL_BUFFER_VARIABLE);
1338
1339 program.GetResource(GL_BUFFER_VARIABLE, index, GL_OFFSET, 1, &offset);
1340 }
1341 catch (std::exception &exc)
1342 {
1343 stream << "Failed to query program for buffer variable: " << variable.m_descriptor.m_name
1344 << ". Reason: " << exc.what() << "\n";
1345
1346 return false;
1347 }
1348
1349 Utils::Variable::Descriptor &desc = interface->m_members[i];
1350
1351 if (offset != (GLint)desc.m_offset)
1352 {
1353 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offset
1354 << " expected: " << desc.m_offset << std::endl;
1355 result = false;
1356 }
1357 }
1358 }
1359
1360 return result;
1361 }
1362
1363 /** Query program resources at given stage and verifies results
1364 *
1365 * @param program Program object
1366 * @param program_interface Definition of program interface
1367 * @param stage Stage to be verified
1368 * @param check_inputs Select if inputs should be verified
1369 * @param check_outputs Select if output should be verified
1370 * @param check_uniforms Select if uniforms should be verified
1371 * @param check_ssbs Select if buffers should be verified
1372 * @param stream Stream that will be used to log any error
1373 *
1374 * @return true if verification is positive, false otherwise
1375 **/
checkProgramStage(Program & program,const ProgramInterface & program_interface,Utils::Shader::STAGES stage,bool check_inputs,bool check_outputs,bool check_uniforms,bool check_ssbs,std::stringstream & stream)1376 bool checkProgramStage(Program &program, const ProgramInterface &program_interface, Utils::Shader::STAGES stage,
1377 bool check_inputs, bool check_outputs, bool check_uniforms, bool check_ssbs,
1378 std::stringstream &stream)
1379 {
1380 typedef Variable::PtrVector::const_iterator const_iterator;
1381
1382 const ShaderInterface &interface = program_interface.GetShaderInterface(stage);
1383
1384 bool result = true;
1385
1386 /* Inputs */
1387 if (true == check_inputs)
1388 {
1389 const Variable::PtrVector &inputs = interface.m_inputs;
1390
1391 for (const_iterator it = inputs.begin(); it != inputs.end(); ++it)
1392 {
1393 if (false == checkVarying(program, stage, **it, stream, true))
1394 {
1395 result = false;
1396 }
1397 }
1398 }
1399
1400 /* Outputs */
1401 if (true == check_outputs)
1402 {
1403 const Variable::PtrVector &outputs = interface.m_outputs;
1404
1405 for (const_iterator it = outputs.begin(); it != outputs.end(); ++it)
1406 {
1407 if (false == checkVarying(program, stage, **it, stream, false))
1408 {
1409 result = false;
1410 }
1411 }
1412 }
1413
1414 /* Uniforms */
1415 if (true == check_uniforms)
1416 {
1417 const Variable::PtrVector &uniforms = interface.m_uniforms;
1418
1419 for (const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
1420 {
1421 if (false == checkUniform(program, **it, stream))
1422 {
1423 result = false;
1424 }
1425 }
1426 }
1427
1428 /* SSBs */
1429 if (true == check_ssbs)
1430 {
1431 const Variable::PtrVector &ssbs = interface.m_ssb_blocks;
1432
1433 for (const_iterator it = ssbs.begin(); it != ssbs.end(); ++it)
1434 {
1435 if (false == checkSSB(program, **it, stream))
1436 {
1437 result = false;
1438 }
1439 }
1440 }
1441
1442 return result;
1443 }
1444
1445 /** Query resources of monolithic compute program and verifies results
1446 *
1447 * @param program Program object
1448 * @param program_interface Definition of program interface
1449 * @param stream Stream that will be used to log any error
1450 *
1451 * @return true if verification is positive, false otherwise
1452 **/
checkMonolithicComputeProgramInterface(Program & program,const ProgramInterface & program_interface,std::stringstream & stream)1453 bool checkMonolithicComputeProgramInterface(Program &program, const ProgramInterface &program_interface,
1454 std::stringstream &stream)
1455 {
1456 bool result = true;
1457
1458 if (false == checkProgramStage(program, program_interface, Shader::COMPUTE, false, false, true, true, stream))
1459 {
1460 result = false;
1461 }
1462
1463 /* Done */
1464 return result;
1465 }
1466
1467 /** Query resources of monolithic draw program and verifies results
1468 *
1469 * @param program Program object
1470 * @param program_interface Definition of program interface
1471 * @param stream Stream that will be used to log any error
1472 *
1473 * @return true if verification is positive, false otherwise
1474 **/
checkMonolithicDrawProgramInterface(Program & program,const ProgramInterface & program_interface,std::stringstream & stream)1475 bool checkMonolithicDrawProgramInterface(Program &program, const ProgramInterface &program_interface,
1476 std::stringstream &stream)
1477 {
1478 bool result = true;
1479
1480 if (false == checkProgramStage(program, program_interface, Shader::VERTEX, true, false, true, true, stream))
1481 {
1482 result = false;
1483 }
1484
1485 /* Done */
1486 return result;
1487 }
1488
1489 /** Query resources of separable draw program and verifies results
1490 *
1491 * @param program Program object
1492 * @param program_interface Definition of program interface
1493 * @param stream Stream that will be used to log any error
1494 *
1495 * @return true if verification is positive, false otherwise
1496 **/
checkSeparableDrawProgramInterface(Program & program,const ProgramInterface & program_interface,Utils::Shader::STAGES stage,std::stringstream & stream)1497 bool checkSeparableDrawProgramInterface(Program &program, const ProgramInterface &program_interface,
1498 Utils::Shader::STAGES stage, std::stringstream &stream)
1499 {
1500 bool result = true;
1501
1502 if (false == checkProgramStage(program, program_interface, stage, true, true, true, true, stream))
1503 {
1504 result = false;
1505 }
1506
1507 /* Done */
1508 return result;
1509 }
1510
1511 /** Check if extension is supported
1512 *
1513 * @param context Test context
1514 * @param extension_name Name of extension
1515 *
1516 * @return true if extension is supported, false otherwise
1517 **/
isExtensionSupported(deqp::Context & context,const GLchar * extension_name)1518 bool isExtensionSupported(deqp::Context &context, const GLchar *extension_name)
1519 {
1520 const std::vector<std::string> &extensions = context.getContextInfo().getExtensions();
1521
1522 if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end())
1523 {
1524 return false;
1525 }
1526
1527 return true;
1528 }
1529
1530 /** Check if GL context meets version requirements
1531 *
1532 * @param gl Functions
1533 * @param required_major Minimum required MAJOR_VERSION
1534 * @param required_minor Minimum required MINOR_VERSION
1535 *
1536 * @return true if GL context version is at least as requested, false otherwise
1537 **/
isGLVersionAtLeast(const Functions & gl,GLint required_major,GLint required_minor)1538 bool isGLVersionAtLeast(const Functions &gl, GLint required_major, GLint required_minor)
1539 {
1540 glw::GLint major = 0;
1541 glw::GLint minor = 0;
1542
1543 gl.getIntegerv(GL_MAJOR_VERSION, &major);
1544 gl.getIntegerv(GL_MINOR_VERSION, &minor);
1545
1546 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1547
1548 if (major > required_major)
1549 {
1550 /* Major is higher than required one */
1551 return true;
1552 }
1553 else if (major == required_major)
1554 {
1555 if (minor >= required_minor)
1556 {
1557 /* Major is equal to required one */
1558 /* Minor is higher than or equal to required one */
1559 return true;
1560 }
1561 else
1562 {
1563 /* Major is equal to required one */
1564 /* Minor is lower than required one */
1565 return false;
1566 }
1567 }
1568 else
1569 {
1570 /* Major is lower than required one */
1571 return false;
1572 }
1573 }
1574
1575 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
1576 *
1577 * @param token Token string
1578 * @param search_position Position at which find will start, it is updated to position at which replaced text ends
1579 * @param text String that will be used as replacement for <token>
1580 * @param string String to work on
1581 **/
replaceToken(const GLchar * token,size_t & search_position,const GLchar * text,std::string & string)1582 void replaceToken(const GLchar *token, size_t &search_position, const GLchar *text, std::string &string)
1583 {
1584 const size_t text_length = strlen(text);
1585 const size_t token_length = strlen(token);
1586 const size_t token_position = string.find(token, search_position);
1587
1588 #if DEBUG_REPLACE_TOKEN
1589 if (std::string::npos == token_position)
1590 {
1591 string.append("\n\nInvalid token: ");
1592 string.append(token);
1593
1594 TCU_FAIL(string.c_str());
1595 }
1596 #endif /* DEBUG_REPLACE_TOKEN */
1597
1598 string.replace(token_position, token_length, text, text_length);
1599
1600 search_position = token_position + text_length;
1601 }
1602
1603 /** Replace all occurances of <token> with <text> in <string>
1604 *
1605 * @param token Token string
1606 * @param text String that will be used as replacement for <token>
1607 * @param string String to work on
1608 **/
replaceAllTokens(const GLchar * token,const GLchar * text,std::string & string)1609 void replaceAllTokens(const GLchar *token, const GLchar *text, std::string &string)
1610 {
1611 const size_t text_length = strlen(text);
1612 const size_t token_length = strlen(token);
1613
1614 size_t search_position = 0;
1615
1616 while (1)
1617 {
1618 const size_t token_position = string.find(token, search_position);
1619
1620 if (std::string::npos == token_position)
1621 {
1622 break;
1623 }
1624
1625 search_position = token_position + text_length;
1626
1627 string.replace(token_position, token_length, text, text_length);
1628 }
1629 }
1630
1631 /** Rounds up the value to the next power of 2.
1632 * This routine does not work for 0, see the url for explanations.
1633 *
1634 * @param value Starting point
1635 *
1636 * @return Calculated value
1637 **/
roundUpToPowerOf2(glw::GLuint value)1638 glw::GLuint roundUpToPowerOf2(glw::GLuint value)
1639 {
1640 /* Taken from: graphics.stanford.edu/~seander/bithacks.html */
1641 --value;
1642
1643 value |= value >> 1;
1644 value |= value >> 2;
1645 value |= value >> 4;
1646 value |= value >> 8;
1647 value |= value >> 16;
1648
1649 ++value;
1650
1651 return value;
1652 }
1653
1654 /** Insert elements of list into string.
1655 * List in string is represented either by token "LIST" or "SEPARATORLIST".
1656 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>.
1657 * LIST is replaced with <element>SEPARATORLIST
1658 *
1659 * @param element Element to be inserted
1660 * @param separator Separator inserted between elements
1661 * @param search_position Position in string, where search for list should start
1662 * @param string String
1663 **/
insertElementOfList(const GLchar * element,const GLchar * separator,size_t & search_position,std::string & string)1664 void insertElementOfList(const GLchar *element, const GLchar *separator, size_t &search_position, std::string &string)
1665 {
1666 static const char *list = g_list;
1667 static const char *sep_list = "SEPARATORLIST";
1668
1669 /* Try to get "list" positions */
1670 const size_t list_position = string.find(list, search_position);
1671 const size_t sep_list_position = string.find(sep_list, search_position);
1672
1673 /* There is no list in string */
1674 if (std::string::npos == list_position)
1675 {
1676 return;
1677 }
1678
1679 if (9 /* strlen(SEPARATOR) */ == list_position - sep_list_position)
1680 {
1681 replaceToken("SEPARATOR", search_position, separator, string);
1682 }
1683
1684 /* Save search_position */
1685 const size_t start_position = search_position;
1686
1687 /* Prepare new element */
1688 replaceToken("LIST", search_position, "ELEMENTSEPARATORLIST", string);
1689
1690 /* Restore search_position */
1691 search_position = start_position;
1692
1693 /* Replace element and separator */
1694 replaceToken("ELEMENT", search_position, element, string);
1695 }
1696
1697 /** Close list in string.
1698 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>
1699 * LIST is replaced with ""
1700 *
1701 * @param separator Separator inserted between elements
1702 * @param search_position Position in string, where search for list should start
1703 * @param string String
1704 **/
endList(const glw::GLchar * separator,size_t & search_position,std::string & string)1705 void endList(const glw::GLchar *separator, size_t &search_position, std::string &string)
1706 {
1707 const size_t sep_position = string.find("SEPARATOR", search_position);
1708 if (std::string::npos != sep_position)
1709 {
1710 replaceToken("SEPARATOR", search_position, separator, string);
1711 }
1712
1713 replaceToken("LIST", search_position, "", string);
1714 }
1715
1716 /* Buffer constants */
1717 const GLuint Buffer::m_invalid_id = -1;
1718
1719 /** Constructor.
1720 *
1721 * @param context CTS context.
1722 **/
Buffer(deqp::Context & context)1723 Buffer::Buffer(deqp::Context &context) : m_id(m_invalid_id), m_buffer(Array), m_context(context)
1724 {
1725 }
1726
1727 /** Destructor
1728 *
1729 **/
~Buffer()1730 Buffer::~Buffer()
1731 {
1732 Release();
1733 }
1734
1735 /** Initialize buffer instance
1736 *
1737 * @param buffer Buffer type
1738 * @param usage Buffer usage enum
1739 * @param size <size> parameter
1740 * @param data <data> parameter
1741 **/
Init(BUFFERS buffer,USAGE usage,GLsizeiptr size,GLvoid * data)1742 void Buffer::Init(BUFFERS buffer, USAGE usage, GLsizeiptr size, GLvoid *data)
1743 {
1744 /* Delete previous buffer instance */
1745 Release();
1746
1747 m_buffer = buffer;
1748
1749 const Functions &gl = m_context.getRenderContext().getFunctions();
1750
1751 Generate(gl, m_id);
1752 Bind(gl, m_id, m_buffer);
1753 Data(gl, m_buffer, usage, size, data);
1754 }
1755
1756 /** Release buffer instance
1757 *
1758 **/
Release()1759 void Buffer::Release()
1760 {
1761 if (m_invalid_id != m_id)
1762 {
1763 const Functions &gl = m_context.getRenderContext().getFunctions();
1764
1765 gl.deleteBuffers(1, &m_id);
1766 m_id = m_invalid_id;
1767 }
1768 }
1769
1770 /** Binds buffer to its target
1771 *
1772 **/
Bind() const1773 void Buffer::Bind() const
1774 {
1775 const Functions &gl = m_context.getRenderContext().getFunctions();
1776
1777 Bind(gl, m_id, m_buffer);
1778 }
1779
1780 /** Binds indexed buffer
1781 *
1782 * @param index <index> parameter
1783 **/
BindBase(GLuint index) const1784 void Buffer::BindBase(GLuint index) const
1785 {
1786 const Functions &gl = m_context.getRenderContext().getFunctions();
1787
1788 BindBase(gl, m_id, m_buffer, index);
1789 }
1790
1791 /** Binds range of buffer
1792 *
1793 * @param index <index> parameter
1794 * @param offset <offset> parameter
1795 * @param size <size> parameter
1796 **/
BindRange(GLuint index,GLintptr offset,GLsizeiptr size) const1797 void Buffer::BindRange(GLuint index, GLintptr offset, GLsizeiptr size) const
1798 {
1799 const Functions &gl = m_context.getRenderContext().getFunctions();
1800
1801 BindRange(gl, m_id, m_buffer, index, offset, size);
1802 }
1803
1804 /** Allocate memory for buffer and sends initial content
1805 *
1806 * @param usage Buffer usage enum
1807 * @param size <size> parameter
1808 * @param data <data> parameter
1809 **/
Data(USAGE usage,glw::GLsizeiptr size,glw::GLvoid * data)1810 void Buffer::Data(USAGE usage, glw::GLsizeiptr size, glw::GLvoid *data)
1811 {
1812 const Functions &gl = m_context.getRenderContext().getFunctions();
1813
1814 Data(gl, m_buffer, usage, size, data);
1815 }
1816
1817 /** Maps contents of buffer into CPU space
1818 *
1819 * @param access Requested access
1820 *
1821 * @return Pointer to memory region available for CPU
1822 **/
Map(ACCESS access)1823 GLvoid *Buffer::Map(ACCESS access)
1824 {
1825 const Functions &gl = m_context.getRenderContext().getFunctions();
1826
1827 return Map(gl, m_buffer, access);
1828 }
1829
1830 /** Allocate memory for buffer and sends initial content
1831 *
1832 * @param offset Offset in buffer
1833 * @param size <size> parameter
1834 * @param data <data> parameter
1835 **/
SubData(glw::GLintptr offset,glw::GLsizeiptr size,glw::GLvoid * data)1836 void Buffer::SubData(glw::GLintptr offset, glw::GLsizeiptr size, glw::GLvoid *data)
1837 {
1838 const Functions &gl = m_context.getRenderContext().getFunctions();
1839
1840 SubData(gl, m_buffer, offset, size, data);
1841 }
1842
1843 /** Maps contents of buffer into CPU space
1844 **/
UnMap()1845 void Buffer::UnMap()
1846 {
1847 const Functions &gl = m_context.getRenderContext().getFunctions();
1848
1849 return UnMap(gl, m_buffer);
1850 }
1851
1852 /** Bind buffer to given target
1853 *
1854 * @param gl GL functions
1855 * @param id Id of buffer
1856 * @param buffer Buffer enum
1857 **/
Bind(const Functions & gl,GLuint id,BUFFERS buffer)1858 void Buffer::Bind(const Functions &gl, GLuint id, BUFFERS buffer)
1859 {
1860 GLenum target = GetBufferGLenum(buffer);
1861
1862 gl.bindBuffer(target, id);
1863 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
1864 }
1865
1866 /** Binds indexed buffer
1867 *
1868 * @param gl GL functions
1869 * @param id Id of buffer
1870 * @param buffer Buffer enum
1871 * @param index <index> parameter
1872 **/
BindBase(const Functions & gl,GLuint id,BUFFERS buffer,GLuint index)1873 void Buffer::BindBase(const Functions &gl, GLuint id, BUFFERS buffer, GLuint index)
1874 {
1875 GLenum target = GetBufferGLenum(buffer);
1876
1877 gl.bindBufferBase(target, index, id);
1878 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
1879 }
1880
1881 /** Binds buffer range
1882 *
1883 * @param gl GL functions
1884 * @param id Id of buffer
1885 * @param buffer Buffer enum
1886 * @param index <index> parameter
1887 * @param offset <offset> parameter
1888 * @param size <size> parameter
1889 **/
BindRange(const Functions & gl,GLuint id,BUFFERS buffer,GLuint index,GLintptr offset,GLsizeiptr size)1890 void Buffer::BindRange(const Functions &gl, GLuint id, BUFFERS buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1891 {
1892 GLenum target = GetBufferGLenum(buffer);
1893
1894 gl.bindBufferRange(target, index, id, offset, size);
1895 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
1896 }
1897
1898 /** Allocate memory for buffer and sends initial content
1899 *
1900 * @param gl GL functions
1901 * @param buffer Buffer enum
1902 * @param usage Buffer usage enum
1903 * @param size <size> parameter
1904 * @param data <data> parameter
1905 **/
Data(const glw::Functions & gl,BUFFERS buffer,USAGE usage,glw::GLsizeiptr size,glw::GLvoid * data)1906 void Buffer::Data(const glw::Functions &gl, BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid *data)
1907 {
1908 GLenum target = GetBufferGLenum(buffer);
1909 GLenum gl_usage = GetUsageGLenum(usage);
1910
1911 gl.bufferData(target, size, data, gl_usage);
1912 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
1913 }
1914
1915 /** Allocate memory for buffer and sends initial content
1916 *
1917 * @param gl GL functions
1918 * @param buffer Buffer enum
1919 * @param offset Offset in buffer
1920 * @param size <size> parameter
1921 * @param data <data> parameter
1922 **/
SubData(const glw::Functions & gl,BUFFERS buffer,glw::GLintptr offset,glw::GLsizeiptr size,glw::GLvoid * data)1923 void Buffer::SubData(const glw::Functions &gl, BUFFERS buffer, glw::GLintptr offset, glw::GLsizeiptr size,
1924 glw::GLvoid *data)
1925 {
1926 GLenum target = GetBufferGLenum(buffer);
1927
1928 gl.bufferSubData(target, offset, size, data);
1929 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData");
1930 }
1931
1932 /** Generate buffer
1933 *
1934 * @param gl GL functions
1935 * @param out_id Id of buffer
1936 **/
Generate(const Functions & gl,GLuint & out_id)1937 void Buffer::Generate(const Functions &gl, GLuint &out_id)
1938 {
1939 GLuint id = m_invalid_id;
1940
1941 gl.genBuffers(1, &id);
1942 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
1943
1944 if (m_invalid_id == id)
1945 {
1946 TCU_FAIL("Got invalid id");
1947 }
1948
1949 out_id = id;
1950 }
1951
1952 /** Maps buffer content
1953 *
1954 * @param gl GL functions
1955 * @param buffer Buffer enum
1956 * @param access Access rights for mapped region
1957 *
1958 * @return Mapped memory
1959 **/
Map(const Functions & gl,BUFFERS buffer,ACCESS access)1960 void *Buffer::Map(const Functions &gl, BUFFERS buffer, ACCESS access)
1961 {
1962 GLenum target = GetBufferGLenum(buffer);
1963 GLenum gl_access = GetAccessGLenum(access);
1964
1965 void *result = gl.mapBuffer(target, gl_access);
1966 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
1967
1968 return result;
1969 }
1970
1971 /** Unmaps buffer
1972 *
1973 **/
UnMap(const Functions & gl,BUFFERS buffer)1974 void Buffer::UnMap(const Functions &gl, BUFFERS buffer)
1975 {
1976 GLenum target = GetBufferGLenum(buffer);
1977
1978 gl.unmapBuffer(target);
1979 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
1980 }
1981
1982 /** Return GLenum representation of requested access
1983 *
1984 * @param access Requested access
1985 *
1986 * @return GLenum value
1987 **/
GetAccessGLenum(ACCESS access)1988 GLenum Buffer::GetAccessGLenum(ACCESS access)
1989 {
1990 GLenum result = 0;
1991
1992 switch (access)
1993 {
1994 case ReadOnly:
1995 result = GL_READ_ONLY;
1996 break;
1997 case WriteOnly:
1998 result = GL_WRITE_ONLY;
1999 break;
2000 case ReadWrite:
2001 result = GL_READ_WRITE;
2002 break;
2003 default:
2004 TCU_FAIL("Invalid enum");
2005 }
2006
2007 return result;
2008 }
2009
2010 /** Return GLenum representation of requested buffer type
2011 *
2012 * @param buffer Requested buffer type
2013 *
2014 * @return GLenum value
2015 **/
GetBufferGLenum(BUFFERS buffer)2016 GLenum Buffer::GetBufferGLenum(BUFFERS buffer)
2017 {
2018 GLenum result = 0;
2019
2020 switch (buffer)
2021 {
2022 case Array:
2023 result = GL_ARRAY_BUFFER;
2024 break;
2025 case Element:
2026 result = GL_ELEMENT_ARRAY_BUFFER;
2027 break;
2028 case Shader_Storage:
2029 result = GL_SHADER_STORAGE_BUFFER;
2030 break;
2031 case Texture:
2032 result = GL_TEXTURE_BUFFER;
2033 break;
2034 case Transform_feedback:
2035 result = GL_TRANSFORM_FEEDBACK_BUFFER;
2036 break;
2037 case Uniform:
2038 result = GL_UNIFORM_BUFFER;
2039 break;
2040 default:
2041 TCU_FAIL("Invalid enum");
2042 }
2043
2044 return result;
2045 }
2046
2047 /** Return GLenum representation of requested usage
2048 *
2049 * @param usage Requested usage
2050 *
2051 * @return GLenum value
2052 **/
GetUsageGLenum(USAGE usage)2053 GLenum Buffer::GetUsageGLenum(USAGE usage)
2054 {
2055 GLenum result = 0;
2056
2057 switch (usage)
2058 {
2059 case DynamicCopy:
2060 result = GL_DYNAMIC_COPY;
2061 break;
2062 case DynamicDraw:
2063 result = GL_DYNAMIC_DRAW;
2064 break;
2065 case DynamicRead:
2066 result = GL_DYNAMIC_READ;
2067 break;
2068 case StaticCopy:
2069 result = GL_STATIC_COPY;
2070 break;
2071 case StaticDraw:
2072 result = GL_STATIC_DRAW;
2073 break;
2074 case StaticRead:
2075 result = GL_STATIC_READ;
2076 break;
2077 case StreamCopy:
2078 result = GL_STREAM_COPY;
2079 break;
2080 case StreamDraw:
2081 result = GL_STREAM_DRAW;
2082 break;
2083 case StreamRead:
2084 result = GL_STREAM_READ;
2085 break;
2086 default:
2087 TCU_FAIL("Invalid enum");
2088 }
2089
2090 return result;
2091 }
2092
2093 /** Returns name of buffer target
2094 *
2095 * @param buffer Target enum
2096 *
2097 * @return Name of target
2098 **/
GetBufferName(BUFFERS buffer)2099 const GLchar *Buffer::GetBufferName(BUFFERS buffer)
2100 {
2101 const GLchar *name = 0;
2102
2103 switch (buffer)
2104 {
2105 case Array:
2106 name = "Array";
2107 break;
2108 case Element:
2109 name = "Element";
2110 break;
2111 case Shader_Storage:
2112 name = "Shader_Storage";
2113 break;
2114 case Texture:
2115 name = "Texture";
2116 break;
2117 case Transform_feedback:
2118 name = "Transform_feedback";
2119 break;
2120 case Uniform:
2121 name = "Uniform";
2122 break;
2123 default:
2124 TCU_FAIL("Invalid enum");
2125 }
2126
2127 return name;
2128 }
2129
2130 /* Framebuffer constants */
2131 const GLuint Framebuffer::m_invalid_id = -1;
2132
2133 /** Constructor
2134 *
2135 * @param context CTS context
2136 **/
Framebuffer(deqp::Context & context)2137 Framebuffer::Framebuffer(deqp::Context &context) : m_id(m_invalid_id), m_context(context)
2138 {
2139 /* Nothing to be done here */
2140 }
2141
2142 /** Destructor
2143 *
2144 **/
~Framebuffer()2145 Framebuffer::~Framebuffer()
2146 {
2147 Release();
2148 }
2149
2150 /** Initialize framebuffer instance
2151 *
2152 **/
Init()2153 void Framebuffer::Init()
2154 {
2155 /* Delete previous instance */
2156 Release();
2157
2158 const Functions &gl = m_context.getRenderContext().getFunctions();
2159
2160 Generate(gl, m_id);
2161 }
2162
2163 /** Release framebuffer instance
2164 *
2165 **/
Release()2166 void Framebuffer::Release()
2167 {
2168 if (m_invalid_id != m_id)
2169 {
2170 const Functions &gl = m_context.getRenderContext().getFunctions();
2171
2172 gl.deleteFramebuffers(1, &m_id);
2173 m_id = m_invalid_id;
2174 }
2175 }
2176
2177 /** Attach texture to specified attachment
2178 *
2179 * @param attachment Attachment
2180 * @param texture_id Texture id
2181 * @param width Texture width
2182 * @param height Texture height
2183 **/
AttachTexture(GLenum attachment,GLuint texture_id,GLuint width,GLuint height)2184 void Framebuffer::AttachTexture(GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2185 {
2186 const Functions &gl = m_context.getRenderContext().getFunctions();
2187
2188 AttachTexture(gl, attachment, texture_id, width, height);
2189 }
2190
2191 /** Binds framebuffer to DRAW_FRAMEBUFFER
2192 *
2193 **/
Bind()2194 void Framebuffer::Bind()
2195 {
2196 const Functions &gl = m_context.getRenderContext().getFunctions();
2197
2198 Bind(gl, m_id);
2199 }
2200
2201 /** Clear framebuffer
2202 *
2203 * @param mask <mask> parameter of glClear. Decides which shall be cleared
2204 **/
Clear(GLenum mask)2205 void Framebuffer::Clear(GLenum mask)
2206 {
2207 const Functions &gl = m_context.getRenderContext().getFunctions();
2208
2209 Clear(gl, mask);
2210 }
2211
2212 /** Specifies clear color
2213 *
2214 * @param red Red channel
2215 * @param green Green channel
2216 * @param blue Blue channel
2217 * @param alpha Alpha channel
2218 **/
ClearColor(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)2219 void Framebuffer::ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2220 {
2221 const Functions &gl = m_context.getRenderContext().getFunctions();
2222
2223 ClearColor(gl, red, green, blue, alpha);
2224 }
2225
2226 /** Attach texture to specified attachment
2227 *
2228 * @param gl GL functions
2229 * @param attachment Attachment
2230 * @param texture_id Texture id
2231 * @param width Texture width
2232 * @param height Texture height
2233 **/
AttachTexture(const Functions & gl,GLenum attachment,GLuint texture_id,GLuint width,GLuint height)2234 void Framebuffer::AttachTexture(const Functions &gl, GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2235 {
2236 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
2237 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
2238
2239 gl.viewport(0 /* x */, 0 /* y */, width, height);
2240 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2241 }
2242
2243 /** Binds framebuffer to DRAW_FRAMEBUFFER
2244 *
2245 * @param gl GL functions
2246 * @param id ID of framebuffer
2247 **/
Bind(const Functions & gl,GLuint id)2248 void Framebuffer::Bind(const Functions &gl, GLuint id)
2249 {
2250 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
2251 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2252 }
2253
2254 /** Clear framebuffer
2255 *
2256 * @param gl GL functions
2257 * @param mask <mask> parameter of glClear. Decides which shall be cleared
2258 **/
Clear(const Functions & gl,GLenum mask)2259 void Framebuffer::Clear(const Functions &gl, GLenum mask)
2260 {
2261 gl.clear(mask);
2262 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2263 }
2264
2265 /** Specifies clear color
2266 *
2267 * @param gl GL functions
2268 * @param red Red channel
2269 * @param green Green channel
2270 * @param blue Blue channel
2271 * @param alpha Alpha channel
2272 **/
ClearColor(const Functions & gl,GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)2273 void Framebuffer::ClearColor(const Functions &gl, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2274 {
2275 gl.clearColor(red, green, blue, alpha);
2276 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
2277 }
2278
2279 /** Generate framebuffer
2280 *
2281 **/
Generate(const Functions & gl,GLuint & out_id)2282 void Framebuffer::Generate(const Functions &gl, GLuint &out_id)
2283 {
2284 GLuint id = m_invalid_id;
2285
2286 gl.genFramebuffers(1, &id);
2287 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
2288
2289 if (m_invalid_id == id)
2290 {
2291 TCU_FAIL("Invalid id");
2292 }
2293
2294 out_id = id;
2295 }
2296
2297 /* Shader's constants */
2298 const GLuint Shader::m_invalid_id = 0;
2299
2300 /** Constructor.
2301 *
2302 * @param context CTS context.
2303 **/
Shader(deqp::Context & context)2304 Shader::Shader(deqp::Context &context) : m_id(m_invalid_id), m_context(context)
2305 {
2306 /* Nothing to be done here */
2307 }
2308
2309 /** Destructor
2310 *
2311 **/
~Shader()2312 Shader::~Shader()
2313 {
2314 Release();
2315 }
2316
2317 /** Initialize shader instance
2318 *
2319 * @param stage Shader stage
2320 * @param source Source code
2321 **/
Init(STAGES stage,const std::string & source)2322 void Shader::Init(STAGES stage, const std::string &source)
2323 {
2324 if (true == source.empty())
2325 {
2326 /* No source == no shader */
2327 return;
2328 }
2329
2330 /* Delete any previous shader */
2331 Release();
2332
2333 /* Create, set source and compile */
2334 const Functions &gl = m_context.getRenderContext().getFunctions();
2335
2336 Create(gl, stage, m_id);
2337 Source(gl, m_id, source);
2338
2339 try
2340 {
2341 Compile(gl, m_id);
2342 }
2343 catch (const CompilationException &exc)
2344 {
2345 throw InvalidSourceException(exc.what(), source, stage);
2346 }
2347 }
2348
2349 /** Release shader instance
2350 *
2351 **/
Release()2352 void Shader::Release()
2353 {
2354 if (m_invalid_id != m_id)
2355 {
2356 const Functions &gl = m_context.getRenderContext().getFunctions();
2357
2358 gl.deleteShader(m_id);
2359 m_id = m_invalid_id;
2360 }
2361 }
2362
2363 /** Compile shader
2364 *
2365 * @param gl GL functions
2366 * @param id Shader id
2367 **/
Compile(const Functions & gl,GLuint id)2368 void Shader::Compile(const Functions &gl, GLuint id)
2369 {
2370 GLint status = GL_FALSE;
2371
2372 /* Compile */
2373 gl.compileShader(id);
2374 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2375
2376 /* Get compilation status */
2377 gl.getShaderiv(id, GL_COMPILE_STATUS, &status);
2378 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2379
2380 /* Log compilation error */
2381 if (GL_TRUE != status)
2382 {
2383 glw::GLint length = 0;
2384 std::string message;
2385
2386 /* Error log length */
2387 gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length);
2388 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2389
2390 /* Prepare storage */
2391 message.resize(length, 0);
2392
2393 /* Get error log */
2394 gl.getShaderInfoLog(id, length, 0, &message[0]);
2395 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2396
2397 throw CompilationException(message.c_str());
2398 }
2399 }
2400
2401 /** Create shader
2402 *
2403 * @param gl GL functions
2404 * @param stage Shader stage
2405 * @param out_id Shader id
2406 **/
Create(const Functions & gl,STAGES stage,GLuint & out_id)2407 void Shader::Create(const Functions &gl, STAGES stage, GLuint &out_id)
2408 {
2409 const GLenum shaderType = GetShaderStageGLenum(stage);
2410 const GLuint id = gl.createShader(shaderType);
2411 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2412
2413 if (m_invalid_id == id)
2414 {
2415 TCU_FAIL("Failed to create shader");
2416 }
2417
2418 out_id = id;
2419 }
2420
2421 /** Set shader's source code
2422 *
2423 * @param gl GL functions
2424 * @param id Shader id
2425 * @param source Shader source code
2426 **/
Source(const Functions & gl,GLuint id,const std::string & source)2427 void Shader::Source(const Functions &gl, GLuint id, const std::string &source)
2428 {
2429 const GLchar *code = source.c_str();
2430
2431 gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */);
2432 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2433 }
2434
2435 /** Get GLenum repesenting shader stage
2436 *
2437 * @param stage Shader stage
2438 *
2439 * @return GLenum
2440 **/
GetShaderStageGLenum(STAGES stage)2441 GLenum Shader::GetShaderStageGLenum(STAGES stage)
2442 {
2443 GLenum result = 0;
2444
2445 switch (stage)
2446 {
2447 case COMPUTE:
2448 result = GL_COMPUTE_SHADER;
2449 break;
2450 case FRAGMENT:
2451 result = GL_FRAGMENT_SHADER;
2452 break;
2453 case GEOMETRY:
2454 result = GL_GEOMETRY_SHADER;
2455 break;
2456 case TESS_CTRL:
2457 result = GL_TESS_CONTROL_SHADER;
2458 break;
2459 case TESS_EVAL:
2460 result = GL_TESS_EVALUATION_SHADER;
2461 break;
2462 case VERTEX:
2463 result = GL_VERTEX_SHADER;
2464 break;
2465 default:
2466 TCU_FAIL("Invalid enum");
2467 }
2468
2469 return result;
2470 }
2471
2472 /** Get string representing name of shader stage
2473 *
2474 * @param stage Shader stage
2475 *
2476 * @return String with name of shader stage
2477 **/
GetStageName(STAGES stage)2478 const glw::GLchar *Shader::GetStageName(STAGES stage)
2479 {
2480 const GLchar *result = 0;
2481
2482 switch (stage)
2483 {
2484 case COMPUTE:
2485 result = "compute";
2486 break;
2487 case VERTEX:
2488 result = "vertex";
2489 break;
2490 case TESS_CTRL:
2491 result = "tessellation control";
2492 break;
2493 case TESS_EVAL:
2494 result = "tessellation evaluation";
2495 break;
2496 case GEOMETRY:
2497 result = "geometry";
2498 break;
2499 case FRAGMENT:
2500 result = "fragment";
2501 break;
2502 default:
2503 TCU_FAIL("Invalid enum");
2504 }
2505
2506 return result;
2507 }
2508
2509 /** Logs shader source
2510 *
2511 * @param context CTS context
2512 * @param source Source of shader
2513 * @param stage Shader stage
2514 **/
LogSource(deqp::Context & context,const std::string & source,STAGES stage)2515 void Shader::LogSource(deqp::Context &context, const std::string &source, STAGES stage)
2516 {
2517 /* Skip empty shaders */
2518 if (true == source.empty())
2519 {
2520 return;
2521 }
2522
2523 context.getTestContext().getLog() << tcu::TestLog::Message
2524 << "Shader source. Stage: " << Shader::GetStageName(stage)
2525 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(source);
2526 }
2527
2528 /** Constructor
2529 *
2530 * @param message Compilation error message
2531 **/
CompilationException(const GLchar * message)2532 Shader::CompilationException::CompilationException(const GLchar *message)
2533 {
2534 m_message = message;
2535 }
2536
2537 /** Returns error messages
2538 *
2539 * @return Compilation error message
2540 **/
what() const2541 const char *Shader::CompilationException::what() const throw()
2542 {
2543 return m_message.c_str();
2544 }
2545
2546 /** Constructor
2547 *
2548 * @param message Compilation error message
2549 **/
InvalidSourceException(const GLchar * error_message,const std::string & source,STAGES stage)2550 Shader::InvalidSourceException::InvalidSourceException(const GLchar *error_message, const std::string &source,
2551 STAGES stage)
2552 : m_message(error_message)
2553 , m_source(source)
2554 , m_stage(stage)
2555 {
2556 }
2557
2558 /** Returns error messages
2559 *
2560 * @return Compilation error message
2561 **/
what() const2562 const char *Shader::InvalidSourceException::what() const throw()
2563 {
2564 return "Compilation error";
2565 }
2566
2567 /** Logs error message and shader sources **/
log(deqp::Context & context) const2568 void Shader::InvalidSourceException::log(deqp::Context &context) const
2569 {
2570 context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader: " << m_message.c_str()
2571 << tcu::TestLog::EndMessage;
2572
2573 LogSource(context, m_source, m_stage);
2574 }
2575
2576 /* Program constants */
2577 const GLuint Pipeline::m_invalid_id = 0;
2578
2579 /** Constructor.
2580 *
2581 * @param context CTS context.
2582 **/
Pipeline(deqp::Context & context)2583 Pipeline::Pipeline(deqp::Context &context) : m_id(m_invalid_id), m_context(context)
2584 {
2585 /* Nothing to be done here */
2586 }
2587
2588 /** Destructor
2589 *
2590 **/
~Pipeline()2591 Pipeline::~Pipeline()
2592 {
2593 Release();
2594 }
2595
2596 /** Initialize pipline object
2597 *
2598 **/
Init()2599 void Pipeline::Init()
2600 {
2601 Release();
2602
2603 const Functions &gl = m_context.getRenderContext().getFunctions();
2604
2605 /* Generate */
2606 gl.genProgramPipelines(1, &m_id);
2607 GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines");
2608 }
2609
2610 /** Release pipeline object
2611 *
2612 **/
Release()2613 void Pipeline::Release()
2614 {
2615 if (m_invalid_id != m_id)
2616 {
2617 const Functions &gl = m_context.getRenderContext().getFunctions();
2618
2619 /* Generate */
2620 gl.deleteProgramPipelines(1, &m_id);
2621 GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteProgramPipelines");
2622
2623 m_id = m_invalid_id;
2624 }
2625 }
2626
2627 /** Bind pipeline
2628 *
2629 **/
Bind()2630 void Pipeline::Bind()
2631 {
2632 const Functions &gl = m_context.getRenderContext().getFunctions();
2633
2634 Bind(gl, m_id);
2635 }
2636
2637 /** Set which stages should be active
2638 *
2639 * @param program_id Id of program
2640 * @param stages Logical combination of enums representing stages
2641 **/
UseProgramStages(GLuint program_id,GLenum stages)2642 void Pipeline::UseProgramStages(GLuint program_id, GLenum stages)
2643 {
2644 const Functions &gl = m_context.getRenderContext().getFunctions();
2645
2646 UseProgramStages(gl, m_id, program_id, stages);
2647 }
2648
2649 /** Bind pipeline
2650 *
2651 * @param gl Functiions
2652 * @param id Pipeline id
2653 **/
Bind(const Functions & gl,GLuint id)2654 void Pipeline::Bind(const Functions &gl, GLuint id)
2655 {
2656 gl.bindProgramPipeline(id);
2657 GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline");
2658 }
2659
2660 /** Set which stages should be active
2661 *
2662 * @param gl Functiions
2663 * @param id Pipeline id
2664 * @param program_id Id of program
2665 * @param stages Logical combination of enums representing stages
2666 **/
UseProgramStages(const Functions & gl,GLuint id,GLuint program_id,GLenum stages)2667 void Pipeline::UseProgramStages(const Functions &gl, GLuint id, GLuint program_id, GLenum stages)
2668 {
2669 gl.useProgramStages(id, stages, program_id);
2670 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
2671 }
2672
2673 /* Program constants */
2674 const GLuint Program::m_invalid_id = 0;
2675
2676 /** Constructor.
2677 *
2678 * @param context CTS context.
2679 **/
Program(deqp::Context & context)2680 Program::Program(deqp::Context &context)
2681 : m_id(m_invalid_id)
2682 , m_compute(context)
2683 , m_fragment(context)
2684 , m_geometry(context)
2685 , m_tess_ctrl(context)
2686 , m_tess_eval(context)
2687 , m_vertex(context)
2688 , m_context(context)
2689 {
2690 /* Nothing to be done here */
2691 }
2692
2693 /** Destructor
2694 *
2695 **/
~Program()2696 Program::~Program()
2697 {
2698 Release();
2699 }
2700
2701 /** Initialize program instance
2702 *
2703 * @param compute_shader Compute shader source code
2704 * @param fragment_shader Fragment shader source code
2705 * @param geometry_shader Geometry shader source code
2706 * @param tessellation_control_shader Tessellation control shader source code
2707 * @param tessellation_evaluation_shader Tessellation evaluation shader source code
2708 * @param vertex_shader Vertex shader source code
2709 * @param captured_varyings Vector of variables to be captured with transfrom feedback
2710 * @param capture_interleaved Select mode of transform feedback (separate or interleaved)
2711 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false
2712 **/
Init(const std::string & compute_shader,const std::string & fragment_shader,const std::string & geometry_shader,const std::string & tessellation_control_shader,const std::string & tessellation_evaluation_shader,const std::string & vertex_shader,const NameVector & captured_varyings,bool capture_interleaved,bool is_separable)2713 void Program::Init(const std::string &compute_shader, const std::string &fragment_shader,
2714 const std::string &geometry_shader, const std::string &tessellation_control_shader,
2715 const std::string &tessellation_evaluation_shader, const std::string &vertex_shader,
2716 const NameVector &captured_varyings, bool capture_interleaved, bool is_separable)
2717 {
2718 /* Delete previous program */
2719 Release();
2720
2721 /* GL entry points */
2722 const Functions &gl = m_context.getRenderContext().getFunctions();
2723
2724 /* Initialize shaders */
2725 m_compute.Init(Shader::COMPUTE, compute_shader);
2726 m_fragment.Init(Shader::FRAGMENT, fragment_shader);
2727 m_geometry.Init(Shader::GEOMETRY, geometry_shader);
2728 m_tess_ctrl.Init(Shader::TESS_CTRL, tessellation_control_shader);
2729 m_tess_eval.Init(Shader::TESS_EVAL, tessellation_evaluation_shader);
2730 m_vertex.Init(Shader::VERTEX, vertex_shader);
2731
2732 /* Create program, set up transform feedback and attach shaders */
2733 Create(gl, m_id);
2734 Capture(gl, m_id, captured_varyings, capture_interleaved);
2735 Attach(gl, m_id, m_compute.m_id);
2736 Attach(gl, m_id, m_fragment.m_id);
2737 Attach(gl, m_id, m_geometry.m_id);
2738 Attach(gl, m_id, m_tess_ctrl.m_id);
2739 Attach(gl, m_id, m_tess_eval.m_id);
2740 Attach(gl, m_id, m_vertex.m_id);
2741
2742 /* Set separable parameter */
2743 if (true == is_separable)
2744 {
2745 gl.programParameteri(m_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2746 GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri");
2747 }
2748
2749 try
2750 {
2751 /* Link program */
2752 Link(gl, m_id);
2753 }
2754 catch (const LinkageException &exc)
2755 {
2756 throw BuildException(exc.what(), compute_shader, fragment_shader, geometry_shader, tessellation_control_shader,
2757 tessellation_evaluation_shader, vertex_shader);
2758 }
2759 }
2760
2761 /** Initialize program instance
2762 *
2763 * @param compute_shader Compute shader source code
2764 * @param fragment_shader Fragment shader source code
2765 * @param geometry_shader Geometry shader source code
2766 * @param tessellation_control_shader Tessellation control shader source code
2767 * @param tessellation_evaluation_shader Tessellation evaluation shader source code
2768 * @param vertex_shader Vertex shader source code
2769 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false
2770 **/
Init(const std::string & compute_shader,const std::string & fragment_shader,const std::string & geometry_shader,const std::string & tessellation_control_shader,const std::string & tessellation_evaluation_shader,const std::string & vertex_shader,bool is_separable)2771 void Program::Init(const std::string &compute_shader, const std::string &fragment_shader,
2772 const std::string &geometry_shader, const std::string &tessellation_control_shader,
2773 const std::string &tessellation_evaluation_shader, const std::string &vertex_shader,
2774 bool is_separable)
2775 {
2776 NameVector captured_varying;
2777
2778 Init(compute_shader, fragment_shader, geometry_shader, tessellation_control_shader, tessellation_evaluation_shader,
2779 vertex_shader, captured_varying, true, is_separable);
2780 }
2781
2782 /** Release program instance
2783 *
2784 **/
Release()2785 void Program::Release()
2786 {
2787 const Functions &gl = m_context.getRenderContext().getFunctions();
2788
2789 if (m_invalid_id != m_id)
2790 {
2791 Use(gl, m_invalid_id);
2792
2793 gl.deleteProgram(m_id);
2794 m_id = m_invalid_id;
2795 }
2796
2797 m_compute.Release();
2798 m_fragment.Release();
2799 m_geometry.Release();
2800 m_tess_ctrl.Release();
2801 m_tess_eval.Release();
2802 m_vertex.Release();
2803 }
2804
2805 /** Get <pname> for a set of active uniforms
2806 *
2807 * @param count Number of indices
2808 * @param indices Indices of uniforms
2809 * @param pname Queired pname
2810 * @param params Array that will be filled with values of parameters
2811 **/
GetActiveUniformsiv(GLsizei count,const GLuint * indices,GLenum pname,GLint * params) const2812 void Program::GetActiveUniformsiv(GLsizei count, const GLuint *indices, GLenum pname, GLint *params) const
2813 {
2814 const Functions &gl = m_context.getRenderContext().getFunctions();
2815
2816 GetActiveUniformsiv(gl, m_id, count, indices, pname, params);
2817 }
2818
2819 /** Get location of attribute
2820 *
2821 * @param name Name of attribute
2822 *
2823 * @return Result of query
2824 **/
GetAttribLocation(const std::string & name) const2825 glw::GLint Program::GetAttribLocation(const std::string &name) const
2826 {
2827 const Functions &gl = m_context.getRenderContext().getFunctions();
2828
2829 return GetAttribLocation(gl, m_id, name);
2830 }
2831
2832 /** Query resource
2833 *
2834 * @param interface Interface to be queried
2835 * @param index Index of resource
2836 * @param property Property to be queried
2837 * @param buf_size Size of <params> buffer
2838 * @param params Results of query
2839 **/
GetResource(GLenum interface,GLuint index,GLenum property,GLsizei buf_size,GLint * params) const2840 void Program::GetResource(GLenum interface, GLuint index, GLenum property, GLsizei buf_size, GLint *params) const
2841 {
2842 const Functions &gl = m_context.getRenderContext().getFunctions();
2843
2844 GetResource(gl, m_id, interface, index, property, buf_size, params);
2845 }
2846
2847 /** Query for index of resource
2848 *
2849 * @param name Name of resource
2850 * @param interface Interface to be queried
2851 *
2852 * @return Result of query
2853 **/
GetResourceIndex(const std::string & name,GLenum interface) const2854 glw::GLuint Program::GetResourceIndex(const std::string &name, GLenum interface) const
2855 {
2856 const Functions &gl = m_context.getRenderContext().getFunctions();
2857
2858 return GetResourceIndex(gl, m_id, name, interface);
2859 }
2860
2861 /** Get indices for a set of uniforms
2862 *
2863 * @param count Count number of uniforms
2864 * @param names Names of uniforms
2865 * @param indices Buffer that will be filled with indices
2866 **/
GetUniformIndices(GLsizei count,const GLchar ** names,GLuint * indices) const2867 void Program::GetUniformIndices(GLsizei count, const GLchar **names, GLuint *indices) const
2868 {
2869 const Functions &gl = m_context.getRenderContext().getFunctions();
2870
2871 GetUniformIndices(gl, m_id, count, names, indices);
2872 }
2873
2874 /** Get uniform location
2875 *
2876 * @param name Name of uniform
2877 *
2878 * @return Results of query
2879 **/
GetUniformLocation(const std::string & name) const2880 glw::GLint Program::GetUniformLocation(const std::string &name) const
2881 {
2882 const Functions &gl = m_context.getRenderContext().getFunctions();
2883
2884 return GetUniformLocation(gl, m_id, name);
2885 }
2886
2887 /** Set program as active
2888 *
2889 **/
Use() const2890 void Program::Use() const
2891 {
2892 const Functions &gl = m_context.getRenderContext().getFunctions();
2893
2894 Use(gl, m_id);
2895 }
2896
2897 /** Attach shader to program
2898 *
2899 * @param gl GL functions
2900 * @param program_id Id of program
2901 * @param shader_id Id of shader
2902 **/
Attach(const Functions & gl,GLuint program_id,GLuint shader_id)2903 void Program::Attach(const Functions &gl, GLuint program_id, GLuint shader_id)
2904 {
2905 /* Quick checks */
2906 if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id))
2907 {
2908 return;
2909 }
2910
2911 gl.attachShader(program_id, shader_id);
2912 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2913 }
2914
2915 /** Set up captured varyings
2916 *
2917 * @param gl GL functions
2918 * @param id Id of program
2919 * @param captured_varyings Vector of varyings
2920 * @param capture_interleaved Selects if interleaved or separate mode should be used
2921 **/
Capture(const Functions & gl,GLuint id,const NameVector & captured_varyings,bool capture_interleaved)2922 void Program::Capture(const Functions &gl, GLuint id, const NameVector &captured_varyings, bool capture_interleaved)
2923 {
2924 const size_t n_varyings = captured_varyings.size();
2925
2926 if (0 == n_varyings)
2927 {
2928 /* empty list, skip */
2929 return;
2930 }
2931
2932 std::vector<const GLchar *> varying_names;
2933 varying_names.resize(n_varyings);
2934
2935 for (size_t i = 0; i < n_varyings; ++i)
2936 {
2937 varying_names[i] = captured_varyings[i].c_str();
2938 }
2939
2940 GLenum mode = 0;
2941 if (true == capture_interleaved)
2942 {
2943 mode = GL_INTERLEAVED_ATTRIBS;
2944 }
2945 else
2946 {
2947 mode = GL_SEPARATE_ATTRIBS;
2948 }
2949
2950 gl.transformFeedbackVaryings(id, static_cast<GLsizei>(n_varyings), &varying_names[0], mode);
2951 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
2952 }
2953
2954 /** Create program instance
2955 *
2956 * @param gl GL functions
2957 * @param out_id Id of program
2958 **/
Create(const Functions & gl,GLuint & out_id)2959 void Program::Create(const Functions &gl, GLuint &out_id)
2960 {
2961 const GLuint id = gl.createProgram();
2962 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2963
2964 if (m_invalid_id == id)
2965 {
2966 TCU_FAIL("Failed to create program");
2967 }
2968
2969 out_id = id;
2970 }
2971
2972 /** Get <pname> for a set of active uniforms
2973 *
2974 * @param gl Functions
2975 * @param program_id Id of program
2976 * @param count Number of indices
2977 * @param indices Indices of uniforms
2978 * @param pname Queired pname
2979 * @param params Array that will be filled with values of parameters
2980 **/
GetActiveUniformsiv(const Functions & gl,GLuint program_id,GLsizei count,const GLuint * indices,GLenum pname,GLint * params)2981 void Program::GetActiveUniformsiv(const Functions &gl, GLuint program_id, GLsizei count, const GLuint *indices,
2982 GLenum pname, GLint *params)
2983 {
2984 gl.getActiveUniformsiv(program_id, count, indices, pname, params);
2985 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
2986 }
2987
2988 /** Get indices for a set of uniforms
2989 *
2990 * @param gl Functions
2991 * @param program_id Id of program
2992 * @param count Count number of uniforms
2993 * @param names Names of uniforms
2994 * @param indices Buffer that will be filled with indices
2995 **/
GetUniformIndices(const Functions & gl,GLuint program_id,GLsizei count,const GLchar ** names,GLuint * indices)2996 void Program::GetUniformIndices(const Functions &gl, GLuint program_id, GLsizei count, const GLchar **names,
2997 GLuint *indices)
2998 {
2999 gl.getUniformIndices(program_id, count, names, indices);
3000 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
3001 }
3002
3003 /** Link program
3004 *
3005 * @param gl GL functions
3006 * @param id Id of program
3007 **/
Link(const Functions & gl,GLuint id)3008 void Program::Link(const Functions &gl, GLuint id)
3009 {
3010 GLint status = GL_FALSE;
3011
3012 gl.linkProgram(id);
3013 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
3014
3015 /* Get link status */
3016 gl.getProgramiv(id, GL_LINK_STATUS, &status);
3017 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
3018
3019 /* Log link error */
3020 if (GL_TRUE != status)
3021 {
3022 glw::GLint length = 0;
3023 std::string message;
3024
3025 /* Get error log length */
3026 gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length);
3027 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
3028
3029 message.resize(length, 0);
3030
3031 /* Get error log */
3032 gl.getProgramInfoLog(id, length, 0, &message[0]);
3033 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
3034
3035 throw LinkageException(message.c_str());
3036 }
3037 }
3038
3039 /** Set generic uniform
3040 *
3041 * @param gl Functions
3042 * @param type Type of uniform
3043 * @param count Length of array
3044 * @param location Location of uniform
3045 * @param data Data that will be used
3046 **/
Uniform(const Functions & gl,const Type & type,GLsizei count,GLint location,const GLvoid * data)3047 void Program::Uniform(const Functions &gl, const Type &type, GLsizei count, GLint location, const GLvoid *data)
3048 {
3049 if (-1 == location)
3050 {
3051 TCU_FAIL("Uniform is inactive");
3052 }
3053
3054 switch (type.m_basic_type)
3055 {
3056 case Type::Double:
3057 if (1 == type.m_n_columns)
3058 {
3059 getUniformNdv(gl, type.m_n_rows)(location, count, (const GLdouble *)data);
3060 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNdv");
3061 }
3062 else
3063 {
3064 getUniformMatrixNdv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLdouble *)data);
3065 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNdv");
3066 }
3067 break;
3068 case Type::Float:
3069 if (1 == type.m_n_columns)
3070 {
3071 getUniformNfv(gl, type.m_n_rows)(location, count, (const GLfloat *)data);
3072 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNfv");
3073 }
3074 else
3075 {
3076 getUniformMatrixNfv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLfloat *)data);
3077 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNfv");
3078 }
3079 break;
3080 case Type::Int:
3081 getUniformNiv(gl, type.m_n_rows)(location, count, (const GLint *)data);
3082 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNiv");
3083 break;
3084 case Type::Uint:
3085 getUniformNuiv(gl, type.m_n_rows)(location, count, (const GLuint *)data);
3086 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNuiv");
3087 break;
3088 default:
3089 TCU_FAIL("Invalid enum");
3090 }
3091 }
3092
3093 /** Use program
3094 *
3095 * @param gl GL functions
3096 * @param id Id of program
3097 **/
Use(const Functions & gl,GLuint id)3098 void Program::Use(const Functions &gl, GLuint id)
3099 {
3100 gl.useProgram(id);
3101 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3102 }
3103
3104 /** Get location of attribute
3105 *
3106 * @param gl GL functions
3107 * @param id Id of program
3108 * @param name Name of attribute
3109 *
3110 * @return Location of attribute
3111 **/
GetAttribLocation(const Functions & gl,GLuint id,const std::string & name)3112 GLint Program::GetAttribLocation(const Functions &gl, GLuint id, const std::string &name)
3113 {
3114 GLint location = gl.getAttribLocation(id, name.c_str());
3115 GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation");
3116
3117 return location;
3118 }
3119
3120 /** Query resource
3121 *
3122 * @param gl GL functions
3123 * @param id Id of program
3124 * @param interface Interface to be queried
3125 * @param index Index of resource
3126 * @param property Property to be queried
3127 * @param buf_size Size of <params> buffer
3128 * @param params Results of query
3129 **/
GetResource(const Functions & gl,GLuint id,GLenum interface,GLuint index,GLenum property,GLsizei buf_size,GLint * params)3130 void Program::GetResource(const Functions &gl, GLuint id, GLenum interface, GLuint index, GLenum property,
3131 GLsizei buf_size, GLint *params)
3132 {
3133 gl.getProgramResourceiv(id, interface, index, 1 /* propCount */, &property, buf_size /* bufSize */, 0 /* length */,
3134 params);
3135 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv");
3136 }
3137
3138 /** Get index of resource
3139 *
3140 * @param gl GL functions
3141 * @param id Id of program
3142 * @param name Name of resource
3143 * @param interface Program interface to queried
3144 *
3145 * @return Location of attribute
3146 **/
GetResourceIndex(const Functions & gl,GLuint id,const std::string & name,GLenum interface)3147 GLuint Program::GetResourceIndex(const Functions &gl, GLuint id, const std::string &name, GLenum interface)
3148 {
3149 GLuint index = gl.getProgramResourceIndex(id, interface, name.c_str());
3150 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex");
3151
3152 return index;
3153 }
3154
3155 /** Get location of attribute
3156 *
3157 * @param gl GL functions
3158 * @param id Id of program
3159 * @param name Name of attribute
3160 *
3161 * @return Location of uniform
3162 **/
GetUniformLocation(const Functions & gl,GLuint id,const std::string & name)3163 GLint Program::GetUniformLocation(const Functions &gl, GLuint id, const std::string &name)
3164 {
3165 GLint location = gl.getUniformLocation(id, name.c_str());
3166 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3167
3168 return location;
3169 }
3170
3171 /** Constructor
3172 *
3173 * @param error_message Error message
3174 * @param compute_shader Source code for compute stage
3175 * @param fragment_shader Source code for fragment stage
3176 * @param geometry_shader Source code for geometry stage
3177 * @param tess_ctrl_shader Source code for tessellation control stage
3178 * @param tess_eval_shader Source code for tessellation evaluation stage
3179 * @param vertex_shader Source code for vertex stage
3180 **/
BuildException(const glw::GLchar * error_message,const std::string compute_shader,const std::string fragment_shader,const std::string geometry_shader,const std::string tess_ctrl_shader,const std::string tess_eval_shader,const std::string vertex_shader)3181 Program::BuildException::BuildException(const glw::GLchar *error_message, const std::string compute_shader,
3182 const std::string fragment_shader, const std::string geometry_shader,
3183 const std::string tess_ctrl_shader, const std::string tess_eval_shader,
3184 const std::string vertex_shader)
3185 : m_error_message(error_message)
3186 , m_compute_shader(compute_shader)
3187 , m_fragment_shader(fragment_shader)
3188 , m_geometry_shader(geometry_shader)
3189 , m_tess_ctrl_shader(tess_ctrl_shader)
3190 , m_tess_eval_shader(tess_eval_shader)
3191 , m_vertex_shader(vertex_shader)
3192 {
3193 }
3194
3195 /** Overwrites std::exception::what method
3196 *
3197 * @return Message compossed from error message and shader sources
3198 **/
what() const3199 const char *Program::BuildException::what() const throw()
3200 {
3201 return "Failed to link program";
3202 }
3203
3204 /** Logs error message and shader sources **/
log(deqp::Context & context) const3205 void Program::BuildException::log(deqp::Context &context) const
3206 {
3207 context.getTestContext().getLog() << tcu::TestLog::Message << "Link failure: " << m_error_message
3208 << tcu::TestLog::EndMessage;
3209
3210 Shader::LogSource(context, m_vertex_shader, Shader::VERTEX);
3211 Shader::LogSource(context, m_tess_ctrl_shader, Shader::TESS_CTRL);
3212 Shader::LogSource(context, m_tess_eval_shader, Shader::TESS_EVAL);
3213 Shader::LogSource(context, m_geometry_shader, Shader::GEOMETRY);
3214 Shader::LogSource(context, m_fragment_shader, Shader::FRAGMENT);
3215 Shader::LogSource(context, m_compute_shader, Shader::COMPUTE);
3216 }
3217
3218 /** Constructor
3219 *
3220 * @param message Linking error message
3221 **/
LinkageException(const glw::GLchar * message)3222 Program::LinkageException::LinkageException(const glw::GLchar *message) : m_error_message(message)
3223 {
3224 /* Nothing to be done */
3225 }
3226
3227 /** Returns error messages
3228 *
3229 * @return Linking error message
3230 **/
what() const3231 const char *Program::LinkageException::what() const throw()
3232 {
3233 return m_error_message.c_str();
3234 }
3235
3236 /* Texture constants */
3237 const GLuint Texture::m_invalid_id = -1;
3238
3239 /** Constructor.
3240 *
3241 * @param context CTS context.
3242 **/
Texture(deqp::Context & context)3243 Texture::Texture(deqp::Context &context) : m_id(m_invalid_id), m_context(context), m_type(TEX_2D)
3244 {
3245 /* Nothing to done here */
3246 }
3247
3248 /** Destructor
3249 *
3250 **/
~Texture()3251 Texture::~Texture()
3252 {
3253 Release();
3254 }
3255
3256 /** Initialize texture instance
3257 *
3258 * @param tex_type Type of texture
3259 * @param width Width of texture
3260 * @param height Height of texture
3261 * @param depth Depth of texture
3262 * @param internal_format Internal format of texture
3263 * @param format Format of texture data
3264 * @param type Type of texture data
3265 * @param data Texture data
3266 **/
Init(TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum internal_format,GLenum format,GLenum type,GLvoid * data)3267 void Texture::Init(TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum internal_format, GLenum format,
3268 GLenum type, GLvoid *data)
3269 {
3270 const Functions &gl = m_context.getRenderContext().getFunctions();
3271
3272 /* Delete previous texture */
3273 Release();
3274
3275 m_type = tex_type;
3276
3277 /* Generate, bind, allocate storage and upload data */
3278 Generate(gl, m_id);
3279 Bind(gl, m_id, tex_type);
3280 Storage(gl, tex_type, width, height, depth, internal_format);
3281 Update(gl, tex_type, width, height, depth, format, type, data);
3282 }
3283
3284 /** Initialize buffer texture
3285 *
3286 * @param internal_format Internal format of texture
3287 * @param buffer_id Id of buffer that will be used as data source
3288 **/
Init(GLenum internal_format,GLuint buffer_id)3289 void Texture::Init(GLenum internal_format, GLuint buffer_id)
3290 {
3291 const Functions &gl = m_context.getRenderContext().getFunctions();
3292
3293 /* Delete previous texture */
3294 Release();
3295
3296 m_type = TEX_BUFFER;
3297
3298 /* Generate, bind and attach buffer */
3299 Generate(gl, m_id);
3300 Bind(gl, m_id, TEX_BUFFER);
3301 TexBuffer(gl, buffer_id, internal_format);
3302 }
3303
3304 /** Release texture instance
3305 *
3306 **/
Release()3307 void Texture::Release()
3308 {
3309 if (m_invalid_id != m_id)
3310 {
3311 const Functions &gl = m_context.getRenderContext().getFunctions();
3312
3313 gl.deleteTextures(1, &m_id);
3314 m_id = m_invalid_id;
3315 }
3316 }
3317
3318 /** Bind texture to its target
3319 *
3320 **/
Bind() const3321 void Texture::Bind() const
3322 {
3323 const Functions &gl = m_context.getRenderContext().getFunctions();
3324
3325 Bind(gl, m_id, m_type);
3326 }
3327
3328 /** Get texture data
3329 *
3330 * @param format Format of data
3331 * @param type Type of data
3332 * @param out_data Buffer for data
3333 **/
Get(GLenum format,GLenum type,GLvoid * out_data) const3334 void Texture::Get(GLenum format, GLenum type, GLvoid *out_data) const
3335 {
3336 const Functions &gl = m_context.getRenderContext().getFunctions();
3337
3338 Bind(gl, m_id, m_type);
3339 Get(gl, m_type, format, type, out_data);
3340 }
3341
3342 /** Bind texture to target
3343 *
3344 * @param gl GL functions
3345 * @param id Id of texture
3346 * @param tex_type Type of texture
3347 **/
Bind(const Functions & gl,GLuint id,TYPES tex_type)3348 void Texture::Bind(const Functions &gl, GLuint id, TYPES tex_type)
3349 {
3350 GLenum target = GetTargetGLenum(tex_type);
3351
3352 gl.bindTexture(target, id);
3353 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3354 }
3355
3356 /** Generate texture instance
3357 *
3358 * @param gl GL functions
3359 * @param out_id Id of texture
3360 **/
Generate(const Functions & gl,GLuint & out_id)3361 void Texture::Generate(const Functions &gl, GLuint &out_id)
3362 {
3363 GLuint id = m_invalid_id;
3364
3365 gl.genTextures(1, &id);
3366 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3367
3368 if (m_invalid_id == id)
3369 {
3370 TCU_FAIL("Invalid id");
3371 }
3372
3373 out_id = id;
3374 }
3375
3376 /** Get texture data
3377 *
3378 * @param gl GL functions
3379 * @param format Format of data
3380 * @param type Type of data
3381 * @param out_data Buffer for data
3382 **/
Get(const Functions & gl,TYPES tex_type,GLenum format,GLenum type,GLvoid * out_data)3383 void Texture::Get(const Functions &gl, TYPES tex_type, GLenum format, GLenum type, GLvoid *out_data)
3384 {
3385 GLenum target = GetTargetGLenum(tex_type);
3386
3387 if (TEX_CUBE != tex_type)
3388 {
3389 gl.getTexImage(target, 0 /* level */, format, type, out_data);
3390 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3391 }
3392 else
3393 {
3394 GLint width;
3395 GLint height;
3396
3397 if ((GL_RGBA != format) && (GL_UNSIGNED_BYTE != type))
3398 {
3399 TCU_FAIL("Not implemented");
3400 }
3401
3402 GLuint texel_size = 4;
3403
3404 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_WIDTH, &width);
3405 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3406
3407 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_HEIGHT, &height);
3408 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3409
3410 const GLuint image_size = width * height * texel_size;
3411
3412 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, format, type,
3413 (GLvoid *)((GLchar *)out_data + (image_size * 0)));
3414 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0 /* level */, format, type,
3415 (GLvoid *)((GLchar *)out_data + (image_size * 1)));
3416 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0 /* level */, format, type,
3417 (GLvoid *)((GLchar *)out_data + (image_size * 2)));
3418 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0 /* level */, format, type,
3419 (GLvoid *)((GLchar *)out_data + (image_size * 3)));
3420 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0 /* level */, format, type,
3421 (GLvoid *)((GLchar *)out_data + (image_size * 4)));
3422 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0 /* level */, format, type,
3423 (GLvoid *)((GLchar *)out_data + (image_size * 5)));
3424 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3425 }
3426 }
3427
3428 /** Allocate storage for texture
3429 *
3430 * @param gl GL functions
3431 * @param tex_type Type of texture
3432 * @param width Width of texture
3433 * @param height Height of texture
3434 * @param depth Depth of texture
3435 * @param internal_format Internal format of texture
3436 **/
Storage(const Functions & gl,TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum internal_format)3437 void Texture::Storage(const Functions &gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth,
3438 GLenum internal_format)
3439 {
3440 static const GLuint levels = 1;
3441
3442 GLenum target = GetTargetGLenum(tex_type);
3443
3444 switch (tex_type)
3445 {
3446 case TEX_1D:
3447 gl.texStorage1D(target, levels, internal_format, width);
3448 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3449 break;
3450 case TEX_2D:
3451 case TEX_1D_ARRAY:
3452 case TEX_2D_RECT:
3453 case TEX_CUBE:
3454 gl.texStorage2D(target, levels, internal_format, width, height);
3455 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3456 break;
3457 case TEX_3D:
3458 case TEX_2D_ARRAY:
3459 gl.texStorage3D(target, levels, internal_format, width, height, depth);
3460 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3461 break;
3462 default:
3463 TCU_FAIL("Invalid enum");
3464 }
3465 }
3466
3467 /** Attach buffer as source of texture buffer data
3468 *
3469 * @param gl GL functions
3470 * @param internal_format Internal format of texture
3471 * @param buffer_id Id of buffer that will be used as data source
3472 **/
TexBuffer(const Functions & gl,GLenum internal_format,GLuint & buffer_id)3473 void Texture::TexBuffer(const Functions &gl, GLenum internal_format, GLuint &buffer_id)
3474 {
3475 gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id);
3476 GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer");
3477 }
3478
3479 /** Update contents of texture
3480 *
3481 * @param gl GL functions
3482 * @param tex_type Type of texture
3483 * @param width Width of texture
3484 * @param height Height of texture
3485 * @param format Format of data
3486 * @param type Type of data
3487 * @param data Buffer with image data
3488 **/
Update(const Functions & gl,TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum format,GLenum type,GLvoid * data)3489 void Texture::Update(const Functions &gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum format,
3490 GLenum type, GLvoid *data)
3491 {
3492 static const GLuint level = 0;
3493
3494 GLenum target = GetTargetGLenum(tex_type);
3495
3496 switch (tex_type)
3497 {
3498 case TEX_1D:
3499 gl.texSubImage1D(target, level, 0 /* x */, width, format, type, data);
3500 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3501 break;
3502 case TEX_2D:
3503 case TEX_1D_ARRAY:
3504 case TEX_2D_RECT:
3505 gl.texSubImage2D(target, level, 0 /* x */, 0 /* y */, width, height, format, type, data);
3506 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3507 break;
3508 case TEX_CUBE:
3509 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3510 data);
3511 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3512 data);
3513 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3514 data);
3515 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3516 data);
3517 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3518 data);
3519 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3520 data);
3521 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3522 break;
3523 case TEX_3D:
3524 case TEX_2D_ARRAY:
3525 gl.texSubImage3D(target, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format, type, data);
3526 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3527 break;
3528 default:
3529 TCU_FAIL("Invalid enum");
3530 }
3531 }
3532
3533 /** Get target for given texture type
3534 *
3535 * @param type Type of texture
3536 *
3537 * @return Target
3538 **/
GetTargetGLenum(TYPES type)3539 GLenum Texture::GetTargetGLenum(TYPES type)
3540 {
3541 GLenum result = 0;
3542
3543 switch (type)
3544 {
3545 case TEX_BUFFER:
3546 result = GL_TEXTURE_BUFFER;
3547 break;
3548 case TEX_2D:
3549 result = GL_TEXTURE_2D;
3550 break;
3551 case TEX_2D_RECT:
3552 result = GL_TEXTURE_RECTANGLE;
3553 break;
3554 case TEX_2D_ARRAY:
3555 result = GL_TEXTURE_2D_ARRAY;
3556 break;
3557 case TEX_3D:
3558 result = GL_TEXTURE_3D;
3559 break;
3560 case TEX_CUBE:
3561 result = GL_TEXTURE_CUBE_MAP;
3562 break;
3563 case TEX_1D:
3564 result = GL_TEXTURE_1D;
3565 break;
3566 case TEX_1D_ARRAY:
3567 result = GL_TEXTURE_1D_ARRAY;
3568 break;
3569 }
3570
3571 return result;
3572 }
3573
3574 /* VertexArray constants */
3575 const GLuint VertexArray::m_invalid_id = -1;
3576
3577 /** Constructor.
3578 *
3579 * @param context CTS context.
3580 **/
VertexArray(deqp::Context & context)3581 VertexArray::VertexArray(deqp::Context &context) : m_id(m_invalid_id), m_context(context)
3582 {
3583 }
3584
3585 /** Destructor
3586 *
3587 **/
~VertexArray()3588 VertexArray::~VertexArray()
3589 {
3590 Release();
3591 }
3592
3593 /** Initialize vertex array instance
3594 *
3595 **/
Init()3596 void VertexArray::Init()
3597 {
3598 /* Delete previous instance */
3599 Release();
3600
3601 const Functions &gl = m_context.getRenderContext().getFunctions();
3602
3603 Generate(gl, m_id);
3604 }
3605
3606 /** Release vertex array object instance
3607 *
3608 **/
Release()3609 void VertexArray::Release()
3610 {
3611 if (m_invalid_id != m_id)
3612 {
3613 const Functions &gl = m_context.getRenderContext().getFunctions();
3614
3615 gl.deleteVertexArrays(1, &m_id);
3616
3617 m_id = m_invalid_id;
3618 }
3619 }
3620
3621 /** Set attribute in VAO
3622 *
3623 * @param index Index of attribute
3624 * @param type Type of attribute
3625 * @param n_array_elements Arary length
3626 * @param normalized Selects if values should be normalized
3627 * @param stride Stride
3628 * @param pointer Pointer to data, or offset in buffer
3629 **/
Attribute(GLuint index,const Type & type,GLuint n_array_elements,GLboolean normalized,GLsizei stride,const GLvoid * pointer)3630 void VertexArray::Attribute(GLuint index, const Type &type, GLuint n_array_elements, GLboolean normalized,
3631 GLsizei stride, const GLvoid *pointer)
3632 {
3633 const Functions &gl = m_context.getRenderContext().getFunctions();
3634
3635 AttribPointer(gl, index, type, n_array_elements, normalized, stride, pointer);
3636 Enable(gl, index, type, n_array_elements);
3637 }
3638
3639 /** Binds Vertex array object
3640 *
3641 **/
Bind()3642 void VertexArray::Bind()
3643 {
3644 const Functions &gl = m_context.getRenderContext().getFunctions();
3645
3646 Bind(gl, m_id);
3647 }
3648
3649 /** Set attribute in VAO
3650 *
3651 * @param gl Functions
3652 * @param index Index of attribute
3653 * @param type Type of attribute
3654 * @param n_array_elements Arary length
3655 * @param normalized Selects if values should be normalized
3656 * @param stride Stride
3657 * @param pointer Pointer to data, or offset in buffer
3658 **/
AttribPointer(const Functions & gl,GLuint index,const Type & type,GLuint n_array_elements,GLboolean normalized,GLsizei stride,const GLvoid * pointer)3659 void VertexArray::AttribPointer(const Functions &gl, GLuint index, const Type &type, GLuint n_array_elements,
3660 GLboolean normalized, GLsizei stride, const GLvoid *pointer)
3661 {
3662 const GLuint basic_type_size = Type::GetTypeSize(type.m_basic_type);
3663 const GLint size = (GLint)type.m_n_rows;
3664 const GLuint column_size = (GLuint)size * basic_type_size;
3665 const GLenum gl_type = Type::GetTypeGLenum(type.m_basic_type);
3666
3667 GLuint offset = 0;
3668
3669 /* If attribute is not an array */
3670 if (0 == n_array_elements)
3671 {
3672 n_array_elements = 1;
3673 }
3674
3675 /* For each element in array */
3676 for (GLuint element = 0; element < n_array_elements; ++element)
3677 {
3678 /* For each column in matrix */
3679 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3680 {
3681 /* Calculate offset */
3682 const GLvoid *ptr = (GLubyte *)pointer + offset;
3683
3684 /* Set up attribute */
3685 switch (type.m_basic_type)
3686 {
3687 case Type::Float:
3688 gl.vertexAttribPointer(index, size, gl_type, normalized, stride, ptr);
3689 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribPointer");
3690 break;
3691 case Type::Int:
3692 case Type::Uint:
3693 gl.vertexAttribIPointer(index, size, gl_type, stride, ptr);
3694 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribIPointer");
3695 break;
3696 case Type::Double:
3697 gl.vertexAttribLPointer(index, size, gl_type, stride, ptr);
3698 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribLPointer");
3699 break;
3700 default:
3701 TCU_FAIL("Invalid enum");
3702 }
3703
3704 /* Next location */
3705 offset += column_size;
3706 index += 1;
3707 }
3708 }
3709 }
3710
3711 /** Binds Vertex array object
3712 *
3713 * @param gl GL functions
3714 * @param id ID of vertex array object
3715 **/
Bind(const glw::Functions & gl,glw::GLuint id)3716 void VertexArray::Bind(const glw::Functions &gl, glw::GLuint id)
3717 {
3718 gl.bindVertexArray(id);
3719 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
3720 }
3721
3722 /** Disable attribute in VAO
3723 *
3724 * @param gl Functions
3725 * @param index Index of attribute
3726 * @param type Type of attribute
3727 * @param n_array_elements Arary length
3728 **/
Disable(const Functions & gl,GLuint index,const Type & type,GLuint n_array_elements)3729 void VertexArray::Disable(const Functions &gl, GLuint index, const Type &type, GLuint n_array_elements)
3730 {
3731 /* If attribute is not an array */
3732 if (0 == n_array_elements)
3733 {
3734 n_array_elements = 1;
3735 }
3736
3737 /* For each element in array */
3738 for (GLuint element = 0; element < n_array_elements; ++element)
3739 {
3740 /* For each column in matrix */
3741 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3742 {
3743 /* Enable attribute array */
3744 gl.disableVertexAttribArray(index);
3745 GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray");
3746
3747 /* Next location */
3748 index += 1;
3749 }
3750 }
3751 }
3752
3753 /** Set divisor for attribute
3754 *
3755 * @param gl Functions
3756 * @param index Index of attribute
3757 * @param divisor New divisor value
3758 **/
Divisor(const Functions & gl,GLuint index,GLuint divisor)3759 void VertexArray::Divisor(const Functions &gl, GLuint index, GLuint divisor)
3760 {
3761 gl.vertexAttribDivisor(index, divisor);
3762 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribDivisor");
3763 }
3764
3765 /** Enables attribute in VAO
3766 *
3767 * @param gl Functions
3768 * @param index Index of attribute
3769 * @param type Type of attribute
3770 * @param n_array_elements Arary length
3771 **/
Enable(const Functions & gl,GLuint index,const Type & type,GLuint n_array_elements)3772 void VertexArray::Enable(const Functions &gl, GLuint index, const Type &type, GLuint n_array_elements)
3773 {
3774 /* If attribute is not an array */
3775 if (0 == n_array_elements)
3776 {
3777 n_array_elements = 1;
3778 }
3779
3780 /* For each element in array */
3781 for (GLuint element = 0; element < n_array_elements; ++element)
3782 {
3783 /* For each column in matrix */
3784 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3785 {
3786 /* Enable attribute array */
3787 gl.enableVertexAttribArray(index);
3788 GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray");
3789
3790 /* Next location */
3791 index += 1;
3792 }
3793 }
3794 }
3795
3796 /** Generates Vertex array object
3797 *
3798 * @param gl GL functions
3799 * @param out_id ID of vertex array object
3800 **/
Generate(const glw::Functions & gl,glw::GLuint & out_id)3801 void VertexArray::Generate(const glw::Functions &gl, glw::GLuint &out_id)
3802 {
3803 GLuint id = m_invalid_id;
3804
3805 gl.genVertexArrays(1, &id);
3806 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
3807
3808 if (m_invalid_id == id)
3809 {
3810 TCU_FAIL("Invalid id");
3811 }
3812
3813 out_id = id;
3814 }
3815
3816 /* Constatns used by Variable */
3817 const GLint Variable::m_automatic_location = -1;
3818
3819 /** Copy constructor
3820 *
3821 **/
Variable(const Variable & var)3822 Variable::Variable(const Variable &var)
3823 : m_data(var.m_data)
3824 , m_data_size(var.m_data_size)
3825 , m_descriptor(var.m_descriptor.m_name.c_str(), var.m_descriptor.m_qualifiers.c_str(),
3826 var.m_descriptor.m_expected_component, var.m_descriptor.m_expected_location,
3827 var.m_descriptor.m_builtin, var.m_descriptor.m_normalized, var.m_descriptor.m_n_array_elements,
3828 var.m_descriptor.m_expected_stride_of_element, var.m_descriptor.m_offset)
3829 , m_storage(var.m_storage)
3830 {
3831 m_descriptor.m_type = var.m_descriptor.m_type;
3832
3833 if (BUILTIN != var.m_descriptor.m_type)
3834 {
3835 m_descriptor.m_interface = var.m_descriptor.m_interface;
3836 }
3837 }
3838
3839 /** Get code that defines variable
3840 *
3841 * @param flavour Provides info if variable is array or not
3842 *
3843 * @return String with code
3844 **/
GetDefinition(FLAVOUR flavour) const3845 std::string Variable::GetDefinition(FLAVOUR flavour) const
3846 {
3847 return m_descriptor.GetDefinition(flavour, m_storage);
3848 }
3849
3850 /** Calcualtes stride of variable
3851 *
3852 * @return Calculated value
3853 **/
GetStride() const3854 GLuint Variable::GetStride() const
3855 {
3856 GLint variable_stride = 0;
3857
3858 if (0 == m_descriptor.m_n_array_elements)
3859 {
3860 variable_stride = m_descriptor.m_expected_stride_of_element;
3861 }
3862 else
3863 {
3864 variable_stride = m_descriptor.m_expected_stride_of_element * m_descriptor.m_n_array_elements;
3865 }
3866
3867 return variable_stride;
3868 }
3869
3870 /** Check if variable is block
3871 *
3872 * @return true if variable type is block, false otherwise
3873 **/
IsBlock() const3874 bool Variable::IsBlock() const
3875 {
3876 if (BUILTIN == m_descriptor.m_type)
3877 {
3878 return false;
3879 }
3880
3881 const Interface *interface = m_descriptor.m_interface;
3882 if (0 == interface)
3883 {
3884 TCU_FAIL("Nullptr");
3885 }
3886
3887 return (Interface::BLOCK == interface->m_type);
3888 }
3889
3890 /** Check if variable is struct
3891 *
3892 * @return true if variable type is struct, false otherwise
3893 **/
IsStruct() const3894 bool Variable::IsStruct() const
3895 {
3896 if (BUILTIN == m_descriptor.m_type)
3897 {
3898 return false;
3899 }
3900
3901 const Interface *interface = m_descriptor.m_interface;
3902 if (0 == interface)
3903 {
3904 TCU_FAIL("Nullptr");
3905 }
3906
3907 return (Interface::STRUCT == interface->m_type);
3908 }
3909 /** Get code that reference variable
3910 *
3911 * @param parent_name Name of parent
3912 * @param variable Descriptor of variable
3913 * @param flavour Provides info about how variable should be referenced
3914 * @param array_index Index of array, ignored when variable is not array
3915 *
3916 * @return String with code
3917 **/
GetReference(const std::string & parent_name,const Descriptor & variable,FLAVOUR flavour,GLuint array_index)3918 std::string Variable::GetReference(const std::string &parent_name, const Descriptor &variable, FLAVOUR flavour,
3919 GLuint array_index)
3920 {
3921 std::string name;
3922
3923 /* Prepare name */
3924 if (false == parent_name.empty())
3925 {
3926 name = parent_name;
3927 name.append(".");
3928 name.append(variable.m_name);
3929 }
3930 else
3931 {
3932 name = variable.m_name;
3933 }
3934
3935 /* */
3936 switch (flavour)
3937 {
3938 case Utils::Variable::BASIC:
3939 break;
3940
3941 case Utils::Variable::ARRAY:
3942 name.append("[0]");
3943 break;
3944
3945 case Utils::Variable::INDEXED_BY_INVOCATION_ID:
3946 name.append("[gl_InvocationID]");
3947 break;
3948 }
3949
3950 /* Assumption that both variables have same lengths */
3951 if (0 != variable.m_n_array_elements)
3952 {
3953 GLchar buffer[16];
3954 sprintf(buffer, "%d", array_index);
3955 name.append("[");
3956 name.append(buffer);
3957 name.append("]");
3958 }
3959
3960 return name;
3961 }
3962
3963 /** Get "flavour" of varying
3964 *
3965 * @param stage Stage of shader
3966 * @param direction Selects if varying is in or out
3967 *
3968 * @return Flavour
3969 **/
GetFlavour(Shader::STAGES stage,VARYING_DIRECTION direction)3970 Variable::FLAVOUR Variable::GetFlavour(Shader::STAGES stage, VARYING_DIRECTION direction)
3971 {
3972 FLAVOUR result = BASIC;
3973
3974 switch (stage)
3975 {
3976 case Shader::GEOMETRY:
3977 case Shader::TESS_EVAL:
3978 if (INPUT == direction)
3979 {
3980 result = ARRAY;
3981 }
3982 break;
3983 case Shader::TESS_CTRL:
3984 result = INDEXED_BY_INVOCATION_ID;
3985 break;
3986 default:
3987 break;
3988 }
3989
3990 return result;
3991 }
3992
3993 /** Constructor, for built-in types
3994 *
3995 * @param name Name
3996 * @param qualifiers Qualifiers
3997 * @param expected_component Expected component of variable
3998 * @param expected_location Expected location
3999 * @param type Type
4000 * @param normalized Selects if data should be normalized
4001 * @param n_array_elements Length of array
4002 * @param expected_stride_of_element Expected stride of element
4003 * @param offset Offset
4004 **/
Descriptor(const GLchar * name,const GLchar * qualifiers,GLint expected_component,GLint expected_location,const Type & type,GLboolean normalized,GLuint n_array_elements,GLint expected_stride_of_element,GLuint offset)4005 Variable::Descriptor::Descriptor(const GLchar *name, const GLchar *qualifiers, GLint expected_component,
4006 GLint expected_location, const Type &type, GLboolean normalized,
4007 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4008 : m_expected_component(expected_component)
4009 , m_expected_location(expected_location)
4010 , m_expected_stride_of_element(expected_stride_of_element)
4011 , m_n_array_elements(n_array_elements)
4012 , m_name(name)
4013 , m_normalized(normalized)
4014 , m_offset(offset)
4015 , m_qualifiers(qualifiers)
4016 , m_type(BUILTIN)
4017 , m_builtin(type)
4018 {
4019 }
4020
4021 /** Constructor, for interface types
4022 *
4023 * @param name Name
4024 * @param qualifiers Qualifiers
4025 * @param expected_component Expected component of variable
4026 * @param expected_location Expected location
4027 * @param interface Interface of variable
4028 * @param n_array_elements Length of array
4029 * @param expected_stride_of_element Expected stride of element
4030 * @param offset Offset
4031 **/
Descriptor(const GLchar * name,const GLchar * qualifiers,GLint expected_componenet,GLint expected_location,Interface * interface,GLuint n_array_elements,GLint expected_stride_of_element,GLuint offset)4032 Variable::Descriptor::Descriptor(const GLchar *name, const GLchar *qualifiers, GLint expected_componenet,
4033 GLint expected_location, Interface *interface, GLuint n_array_elements,
4034 GLint expected_stride_of_element, GLuint offset)
4035 : m_expected_component(expected_componenet)
4036 , m_expected_location(expected_location)
4037 , m_expected_stride_of_element(expected_stride_of_element)
4038 , m_n_array_elements(n_array_elements)
4039 , m_name(name)
4040 , m_normalized(GL_FALSE)
4041 , m_offset(offset)
4042 , m_qualifiers(qualifiers)
4043 , m_type(INTERFACE)
4044 , m_interface(interface)
4045 {
4046 }
4047
4048 /** Get definition of variable
4049 *
4050 * @param flavour Flavour of variable
4051 * @param storage Storage used for variable
4052 *
4053 * @return code with defintion
4054 **/
GetDefinition(FLAVOUR flavour,STORAGE storage) const4055 std::string Variable::Descriptor::GetDefinition(FLAVOUR flavour, STORAGE storage) const
4056 {
4057 static const GLchar *basic_template = "QUALIFIERS STORAGETYPE NAMEARRAY;";
4058 static const GLchar *array_template = "QUALIFIERS STORAGETYPE NAME[]ARRAY;";
4059 const GLchar *storage_str = 0;
4060
4061 std::string definition;
4062 size_t position = 0;
4063
4064 /* Select definition template */
4065 switch (flavour)
4066 {
4067 case BASIC:
4068 definition = basic_template;
4069 break;
4070 case ARRAY:
4071 case INDEXED_BY_INVOCATION_ID:
4072 definition = array_template;
4073 break;
4074 default:
4075 TCU_FAIL("Invalid enum");
4076 }
4077
4078 if (BUILTIN != m_type)
4079 {
4080 if (0 == m_interface)
4081 {
4082 TCU_FAIL("Nullptr");
4083 }
4084 }
4085
4086 /* Qualifiers */
4087 if (true == m_qualifiers.empty())
4088 {
4089 replaceToken("QUALIFIERS ", position, "", definition);
4090 }
4091 else
4092 {
4093 replaceToken("QUALIFIERS", position, m_qualifiers.c_str(), definition);
4094 }
4095
4096 // According to spec: int, uint, and double type must always be declared with flat qualifier
4097 bool flat_qualifier = false;
4098 if (m_type != BUILTIN && m_interface != NULL)
4099 {
4100 if (m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Int ||
4101 m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Uint ||
4102 m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Double)
4103 {
4104 flat_qualifier = true;
4105 }
4106 }
4107 /* Storage */
4108 switch (storage)
4109 {
4110 case VARYING_INPUT:
4111 storage_str = flat_qualifier ? "flat in " : "in ";
4112 break;
4113 case VARYING_OUTPUT:
4114 storage_str = "out ";
4115 break;
4116 case UNIFORM:
4117 storage_str = "uniform ";
4118 break;
4119 case SSB:
4120 storage_str = "buffer ";
4121 break;
4122 case MEMBER:
4123 storage_str = "";
4124 break;
4125 default:
4126 TCU_FAIL("Invalid enum");
4127 }
4128
4129 replaceToken("STORAGE", position, storage_str, definition);
4130
4131 /* Type */
4132 if (BUILTIN == m_type)
4133 {
4134 replaceToken("TYPE", position, m_builtin.GetGLSLTypeName(), definition);
4135 }
4136 else
4137 {
4138 if (Interface::STRUCT == m_interface->m_type)
4139 {
4140 replaceToken("TYPE", position, m_interface->m_name.c_str(), definition);
4141 }
4142 else
4143 {
4144 const std::string &block_definition = m_interface->GetDefinition();
4145
4146 replaceToken("TYPE", position, block_definition.c_str(), definition);
4147 }
4148 }
4149
4150 /* Name */
4151 replaceToken("NAME", position, m_name.c_str(), definition);
4152
4153 /* Array size */
4154 if (0 == m_n_array_elements)
4155 {
4156 replaceToken("ARRAY", position, "", definition);
4157 }
4158 else
4159 {
4160 char buffer[16];
4161 sprintf(buffer, "[%d]", m_n_array_elements);
4162
4163 replaceToken("ARRAY", position, buffer, definition);
4164 }
4165
4166 /* Done */
4167 return definition;
4168 }
4169
4170 /** Get definitions for variables collected in vector
4171 *
4172 * @param vector Collection of variables
4173 * @param flavour Flavour of variables
4174 *
4175 * @return Code with definitions
4176 **/
GetDefinitions(const Variable::PtrVector & vector,Variable::FLAVOUR flavour)4177 std::string GetDefinitions(const Variable::PtrVector &vector, Variable::FLAVOUR flavour)
4178 {
4179 std::string list = Utils::g_list;
4180 size_t position = 0;
4181
4182 for (GLuint i = 0; i < vector.size(); ++i)
4183 {
4184 Utils::insertElementOfList(vector[i]->GetDefinition(flavour).c_str(), "\n", position, list);
4185 }
4186
4187 Utils::endList("", position, list);
4188
4189 return list;
4190 }
4191
4192 /** Get definitions for interfaces collected in vector
4193 *
4194 * @param vector Collection of interfaces
4195 *
4196 * @return Code with definitions
4197 **/
GetDefinitions(const Interface::PtrVector & vector)4198 std::string GetDefinitions(const Interface::PtrVector &vector)
4199 {
4200 std::string list = Utils::g_list;
4201 size_t position = 0;
4202
4203 for (GLuint i = 0; i < vector.size(); ++i)
4204 {
4205 Utils::insertElementOfList(vector[i]->GetDefinition().c_str(), "\n", position, list);
4206 }
4207
4208 Utils::endList("", position, list);
4209
4210 return list;
4211 }
4212
4213 /** Constructor
4214 *
4215 * @param name Name
4216 * @param type Type of interface
4217 **/
Interface(const GLchar * name,Interface::TYPE type)4218 Interface::Interface(const GLchar *name, Interface::TYPE type) : m_name(name), m_type(type)
4219 {
4220 }
4221
4222 /** Adds member to interface
4223 *
4224 * @param member Descriptor of new member
4225 *
4226 * @return Pointer to just created member
4227 **/
AddMember(const Variable::Descriptor & member)4228 Variable::Descriptor *Interface::AddMember(const Variable::Descriptor &member)
4229 {
4230 m_members.push_back(member);
4231
4232 return &m_members.back();
4233 }
4234
4235 /** Get definition of interface
4236 *
4237 * @param Code with definition
4238 **/
GetDefinition() const4239 std::string Interface::GetDefinition() const
4240 {
4241 std::string definition;
4242 size_t position = 0;
4243
4244 const GLchar *member_list = " MEMBER_DEFINITION\nMEMBER_LIST";
4245
4246 if (STRUCT == m_type)
4247 {
4248 definition = "struct NAME {\nMEMBER_LIST};";
4249 }
4250 else
4251 {
4252 definition = "NAME {\nMEMBER_LIST}";
4253 }
4254
4255 /* Name */
4256 replaceToken("NAME", position, m_name.c_str(), definition);
4257
4258 /* Member list */
4259 for (GLuint i = 0; i < m_members.size(); ++i)
4260 {
4261 const size_t start_position = position;
4262 const std::string &member_definition = m_members[i].GetDefinition(Variable::BASIC, Variable::MEMBER);
4263
4264 /* Member list */
4265 replaceToken("MEMBER_LIST", position, member_list, definition);
4266
4267 /* Move back position */
4268 position = start_position;
4269
4270 /* Member definition */
4271 replaceToken("MEMBER_DEFINITION", position, member_definition.c_str(), definition);
4272 }
4273
4274 /* Remove last member list */
4275 replaceToken("MEMBER_LIST", position, "", definition);
4276
4277 /* Done */
4278 return definition;
4279 }
4280
4281 /** Adds member of built-in type to interface
4282 *
4283 * @param name Name
4284 * @param qualifiers Qualifiers
4285 * @param expected_component Expected component of variable
4286 * @param expected_location Expected location
4287 * @param type Type
4288 * @param normalized Selects if data should be normalized
4289 * @param n_array_elements Length of array
4290 * @param expected_stride_of_element Expected stride of element
4291 * @param offset Offset
4292 *
4293 * @return Pointer to just created member
4294 **/
Member(const GLchar * name,const GLchar * qualifiers,GLint expected_component,GLint expected_location,const Type & type,GLboolean normalized,GLuint n_array_elements,GLint expected_stride_of_element,GLuint offset)4295 Variable::Descriptor *Interface::Member(const GLchar *name, const GLchar *qualifiers, GLint expected_component,
4296 GLint expected_location, const Type &type, GLboolean normalized,
4297 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4298 {
4299 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, type, normalized,
4300 n_array_elements, expected_stride_of_element, offset));
4301 }
4302
4303 /** Adds member of interface type to interface
4304 *
4305 * @param name Name
4306 * @param qualifiers Qualifiers
4307 * @param expected_component Expected component of variable
4308 * @param expected_location Expected location
4309 * @param type Type
4310 * @param normalized Selects if data should be normalized
4311 * @param n_array_elements Length of array
4312 * @param expected_stride_of_element Expected stride of element
4313 * @param offset Offset
4314 *
4315 * @return Pointer to just created member
4316 **/
Member(const GLchar * name,const GLchar * qualifiers,GLint expected_component,GLint expected_location,Interface * nterface,GLuint n_array_elements,GLint expected_stride_of_element,GLuint offset)4317 Variable::Descriptor *Interface::Member(const GLchar *name, const GLchar *qualifiers, GLint expected_component,
4318 GLint expected_location, Interface *nterface, GLuint n_array_elements,
4319 GLint expected_stride_of_element, GLuint offset)
4320 {
4321 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, nterface,
4322 n_array_elements, expected_stride_of_element, offset));
4323 }
4324
4325 /** Clears contents of vector of pointers
4326 *
4327 * @tparam T Type of elements
4328 *
4329 * @param vector Collection to be cleared
4330 **/
4331 template <typename T>
clearPtrVector(std::vector<T * > & vector)4332 void clearPtrVector(std::vector<T *> &vector)
4333 {
4334 for (size_t i = 0; i < vector.size(); ++i)
4335 {
4336 T *t = vector[i];
4337
4338 vector[i] = 0;
4339
4340 if (0 != t)
4341 {
4342 delete t;
4343 }
4344 }
4345
4346 vector.clear();
4347 }
4348
4349 /** Constructor
4350 *
4351 * @param stage Stage described by that interface
4352 **/
ShaderInterface(Shader::STAGES stage)4353 ShaderInterface::ShaderInterface(Shader::STAGES stage) : m_stage(stage)
4354 {
4355 /* Nothing to be done */
4356 }
4357
4358 /** Get definitions of globals
4359 *
4360 * @return Code with definitions
4361 **/
GetDefinitionsGlobals() const4362 std::string ShaderInterface::GetDefinitionsGlobals() const
4363 {
4364 return m_globals;
4365 }
4366
4367 /** Get definitions of inputs
4368 *
4369 * @return Code with definitions
4370 **/
GetDefinitionsInputs() const4371 std::string ShaderInterface::GetDefinitionsInputs() const
4372 {
4373 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::INPUT);
4374
4375 return GetDefinitions(m_inputs, flavour);
4376 }
4377
4378 /** Get definitions of outputs
4379 *
4380 * @return Code with definitions
4381 **/
GetDefinitionsOutputs() const4382 std::string ShaderInterface::GetDefinitionsOutputs() const
4383 {
4384 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::OUTPUT);
4385
4386 return GetDefinitions(m_outputs, flavour);
4387 }
4388
4389 /** Get definitions of buffers
4390 *
4391 * @return Code with definitions
4392 **/
GetDefinitionsSSBs() const4393 std::string ShaderInterface::GetDefinitionsSSBs() const
4394 {
4395 return GetDefinitions(m_ssb_blocks, Variable::BASIC);
4396 }
4397
4398 /** Get definitions of uniforms
4399 *
4400 * @return Code with definitions
4401 **/
GetDefinitionsUniforms() const4402 std::string ShaderInterface::GetDefinitionsUniforms() const
4403 {
4404 return GetDefinitions(m_uniforms, Variable::BASIC);
4405 }
4406
4407 /** Constructor
4408 *
4409 * @param in Input variable
4410 * @param out Output variable
4411 **/
VaryingConnection(Variable * in,Variable * out)4412 VaryingConnection::VaryingConnection(Variable *in, Variable *out) : m_in(in), m_out(out)
4413 {
4414 /* NBothing to be done here */
4415 }
4416
4417 /** Adds new varying connection to given stage
4418 *
4419 * @param stage Shader stage
4420 * @param in In varying
4421 * @param out Out varying
4422 **/
Add(Shader::STAGES stage,Variable * in,Variable * out)4423 void VaryingPassthrough::Add(Shader::STAGES stage, Variable *in, Variable *out)
4424 {
4425 VaryingConnection::Vector &vector = Get(stage);
4426
4427 vector.push_back(VaryingConnection(in, out));
4428 }
4429
4430 /** Get all passthrough connections for given stage
4431 *
4432 * @param stage Shader stage
4433 *
4434 * @return Vector of connections
4435 **/
Get(Shader::STAGES stage)4436 VaryingConnection::Vector &VaryingPassthrough::Get(Shader::STAGES stage)
4437 {
4438 VaryingConnection::Vector *result = 0;
4439
4440 switch (stage)
4441 {
4442 case Shader::FRAGMENT:
4443 result = &m_fragment;
4444 break;
4445 case Shader::GEOMETRY:
4446 result = &m_geometry;
4447 break;
4448 case Shader::TESS_CTRL:
4449 result = &m_tess_ctrl;
4450 break;
4451 case Shader::TESS_EVAL:
4452 result = &m_tess_eval;
4453 break;
4454 case Shader::VERTEX:
4455 result = &m_vertex;
4456 break;
4457 default:
4458 TCU_FAIL("Invalid enum");
4459 }
4460
4461 return *result;
4462 }
4463
4464 /** Constructor
4465 *
4466 **/
ProgramInterface()4467 ProgramInterface::ProgramInterface()
4468 : m_compute(Shader::COMPUTE)
4469 , m_vertex(Shader::VERTEX)
4470 , m_tess_ctrl(Shader::TESS_CTRL)
4471 , m_tess_eval(Shader::TESS_EVAL)
4472 , m_geometry(Shader::GEOMETRY)
4473 , m_fragment(Shader::FRAGMENT)
4474 {
4475 }
4476
4477 /** Destructor
4478 *
4479 **/
~ProgramInterface()4480 ProgramInterface::~ProgramInterface()
4481 {
4482 clearPtrVector(m_blocks);
4483 clearPtrVector(m_structures);
4484 }
4485
4486 /** Adds new interface
4487 *
4488 * @param name
4489 * @param type
4490 *
4491 * @return Pointer to created interface
4492 **/
AddInterface(const GLchar * name,Interface::TYPE type)4493 Interface *ProgramInterface::AddInterface(const GLchar *name, Interface::TYPE type)
4494 {
4495 Interface *interface = 0;
4496
4497 if (Interface::STRUCT == type)
4498 {
4499 interface = new Interface(name, type);
4500
4501 m_structures.push_back(interface);
4502 }
4503 else
4504 {
4505 interface = new Interface(name, type);
4506
4507 m_blocks.push_back(interface);
4508 }
4509
4510 return interface;
4511 }
4512
4513 /** Adds new block interface
4514 *
4515 * @param name
4516 *
4517 * @return Pointer to created interface
4518 **/
Block(const GLchar * name)4519 Interface *ProgramInterface::Block(const GLchar *name)
4520 {
4521 return AddInterface(name, Interface::BLOCK);
4522 }
4523
4524 /** Get interface of given shader stage
4525 *
4526 * @param stage Shader stage
4527 *
4528 * @return Reference to stage interface
4529 **/
GetShaderInterface(Shader::STAGES stage)4530 ShaderInterface &ProgramInterface::GetShaderInterface(Shader::STAGES stage)
4531 {
4532 ShaderInterface *interface = 0;
4533
4534 switch (stage)
4535 {
4536 case Shader::COMPUTE:
4537 interface = &m_compute;
4538 break;
4539 case Shader::FRAGMENT:
4540 interface = &m_fragment;
4541 break;
4542 case Shader::GEOMETRY:
4543 interface = &m_geometry;
4544 break;
4545 case Shader::TESS_CTRL:
4546 interface = &m_tess_ctrl;
4547 break;
4548 case Shader::TESS_EVAL:
4549 interface = &m_tess_eval;
4550 break;
4551 case Shader::VERTEX:
4552 interface = &m_vertex;
4553 break;
4554 default:
4555 TCU_FAIL("Invalid enum");
4556 }
4557
4558 return *interface;
4559 }
4560
4561 /** Get interface of given shader stage
4562 *
4563 * @param stage Shader stage
4564 *
4565 * @return Reference to stage interface
4566 **/
GetShaderInterface(Shader::STAGES stage) const4567 const ShaderInterface &ProgramInterface::GetShaderInterface(Shader::STAGES stage) const
4568 {
4569 const ShaderInterface *interface = 0;
4570
4571 switch (stage)
4572 {
4573 case Shader::COMPUTE:
4574 interface = &m_compute;
4575 break;
4576 case Shader::FRAGMENT:
4577 interface = &m_fragment;
4578 break;
4579 case Shader::GEOMETRY:
4580 interface = &m_geometry;
4581 break;
4582 case Shader::TESS_CTRL:
4583 interface = &m_tess_ctrl;
4584 break;
4585 case Shader::TESS_EVAL:
4586 interface = &m_tess_eval;
4587 break;
4588 case Shader::VERTEX:
4589 interface = &m_vertex;
4590 break;
4591 default:
4592 TCU_FAIL("Invalid enum");
4593 }
4594
4595 return *interface;
4596 }
4597
4598 /** Clone interface of Vertex shader stage to other stages
4599 * It creates matching inputs, outputs, uniforms and buffers in other stages.
4600 * There are no additional outputs for FRAGMENT shader generated.
4601 *
4602 * @param varying_passthrough Collection of varyings connections
4603 **/
CloneVertexInterface(VaryingPassthrough & varying_passthrough)4604 void ProgramInterface::CloneVertexInterface(VaryingPassthrough &varying_passthrough)
4605 {
4606 /* VS outputs >> TCS inputs >> TCS outputs >> .. >> FS inputs */
4607 for (size_t i = 0; i < m_vertex.m_outputs.size(); ++i)
4608 {
4609 const Variable &vs_var = *m_vertex.m_outputs[i];
4610 const GLchar *prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4611
4612 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4613 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4614 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4615 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4616 }
4617
4618 /* Copy uniforms from VS to other stages */
4619 for (size_t i = 0; i < m_vertex.m_uniforms.size(); ++i)
4620 {
4621 Variable &vs_var = *m_vertex.m_uniforms[i];
4622 const GLchar *prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4623
4624 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4625 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4626 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4627 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4628 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4629
4630 /* Uniform blocks needs unique binding */
4631 if (true == vs_var.IsBlock())
4632 {
4633 replaceBinding(vs_var, Shader::VERTEX);
4634 }
4635 }
4636
4637 /* Copy SSBs from VS to other stages */
4638 for (size_t i = 0; i < m_vertex.m_ssb_blocks.size(); ++i)
4639 {
4640 Variable &vs_var = *m_vertex.m_ssb_blocks[i];
4641 const GLchar *prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4642
4643 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4644 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4645 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4646 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4647 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4648
4649 /* SSBs blocks needs unique binding */
4650 if (true == vs_var.IsBlock())
4651 {
4652 replaceBinding(vs_var, Shader::VERTEX);
4653 }
4654 }
4655
4656 m_compute.m_globals = m_vertex.m_globals;
4657 m_fragment.m_globals = m_vertex.m_globals;
4658 m_geometry.m_globals = m_vertex.m_globals;
4659 m_tess_ctrl.m_globals = m_vertex.m_globals;
4660 m_tess_eval.m_globals = m_vertex.m_globals;
4661 }
4662
4663 /** Clone variable for specific stage
4664 *
4665 * @param variable Variable
4666 * @param stage Requested stage
4667 * @param prefix Prefix used in variable name that is specific for original stage
4668 * @param varying_passthrough Collection of varyings connections
4669 **/
cloneVariableForStage(const Variable & variable,Shader::STAGES stage,const GLchar * prefix,VaryingPassthrough & varying_passthrough)4670 void ProgramInterface::cloneVariableForStage(const Variable &variable, Shader::STAGES stage, const GLchar *prefix,
4671 VaryingPassthrough &varying_passthrough)
4672 {
4673 switch (variable.m_storage)
4674 {
4675 case Variable::VARYING_OUTPUT:
4676 {
4677 Variable *in = cloneVariableForStage(variable, stage, Variable::VARYING_INPUT, prefix);
4678
4679 if (Shader::FRAGMENT != stage)
4680 {
4681 Variable *out = cloneVariableForStage(variable, stage, Variable::VARYING_OUTPUT, prefix);
4682 varying_passthrough.Add(stage, in, out);
4683 }
4684 }
4685 break;
4686 case Variable::UNIFORM:
4687 case Variable::SSB:
4688 cloneVariableForStage(variable, stage, variable.m_storage, prefix);
4689 break;
4690 default:
4691 TCU_FAIL("Invalid enum");
4692 }
4693 }
4694
4695 /** Clone variable for specific stage
4696 *
4697 * @param variable Variable
4698 * @param stage Requested stage
4699 * @param storage Storage used by variable
4700 * @param prefix Prefix used in variable name that is specific for original stage
4701 *
4702 * @return New variable
4703 **/
cloneVariableForStage(const Variable & variable,Shader::STAGES stage,Variable::STORAGE storage,const GLchar * prefix)4704 Variable *ProgramInterface::cloneVariableForStage(const Variable &variable, Shader::STAGES stage,
4705 Variable::STORAGE storage, const GLchar *prefix)
4706 {
4707 /* Initialize with original variable */
4708 Variable *var = new Variable(variable);
4709 if (0 == var)
4710 {
4711 TCU_FAIL("Memory allocation");
4712 }
4713
4714 /* Set up storage */
4715 var->m_storage = storage;
4716
4717 /* Get name */
4718 std::string name = variable.m_descriptor.m_name;
4719
4720 /* Prefix name with stage ID, empty means default block */
4721 if (false == name.empty())
4722 {
4723 size_t position = 0;
4724 const GLchar *stage_prefix = GetStagePrefix(stage, storage);
4725 Utils::replaceToken(prefix, position, stage_prefix, name);
4726 }
4727 var->m_descriptor.m_name = name;
4728
4729 /* Clone block */
4730 const bool is_block = variable.IsBlock();
4731 if (true == is_block)
4732 {
4733 const Interface *interface = variable.m_descriptor.m_interface;
4734
4735 Interface *block = CloneBlockForStage(*interface, stage, storage, prefix);
4736
4737 var->m_descriptor.m_interface = block;
4738 }
4739
4740 /* Store variable */
4741 ShaderInterface &si = GetShaderInterface(stage);
4742 Variable *result = 0;
4743
4744 switch (storage)
4745 {
4746 case Variable::VARYING_INPUT:
4747 si.m_inputs.push_back(var);
4748 result = si.m_inputs.back();
4749 break;
4750 case Variable::VARYING_OUTPUT:
4751 si.m_outputs.push_back(var);
4752 result = si.m_outputs.back();
4753 break;
4754 case Variable::UNIFORM:
4755 /* Uniform blocks needs unique binding */
4756 if (true == is_block)
4757 {
4758 replaceBinding(*var, stage);
4759 }
4760
4761 si.m_uniforms.push_back(var);
4762 result = si.m_uniforms.back();
4763 break;
4764 case Variable::SSB:
4765 /* SSBs needs unique binding */
4766 if (true == is_block)
4767 {
4768 replaceBinding(*var, stage);
4769 }
4770
4771 si.m_ssb_blocks.push_back(var);
4772 result = si.m_ssb_blocks.back();
4773 break;
4774 default:
4775 TCU_FAIL("Invalid enum");
4776 }
4777
4778 return result;
4779 }
4780
4781 /** clone block to specific stage
4782 *
4783 * @param block Block to be copied
4784 * @param stage Specific stage
4785 * @param storage Storage used by block
4786 * @param prefix Prefix used in block name
4787 *
4788 * @return New interface
4789 **/
CloneBlockForStage(const Interface & block,Shader::STAGES stage,Variable::STORAGE storage,const GLchar * prefix)4790 Interface *ProgramInterface::CloneBlockForStage(const Interface &block, Shader::STAGES stage, Variable::STORAGE storage,
4791 const GLchar *prefix)
4792 {
4793 /* Get name */
4794 std::string name = block.m_name;
4795
4796 /* Prefix name with stage ID */
4797 size_t position = 0;
4798 const GLchar *stage_prefix = GetStagePrefix(stage, storage);
4799 Utils::replaceToken(prefix, position, stage_prefix, name);
4800
4801 Interface *ptr = GetBlock(name.c_str());
4802
4803 if (0 == ptr)
4804 {
4805 ptr = AddInterface(name.c_str(), Interface::BLOCK);
4806 }
4807
4808 ptr->m_members = block.m_members;
4809
4810 return ptr;
4811 }
4812
4813 /** Get stage specific prefix used in names
4814 *
4815 * @param stage Stage
4816 * @param storage Storage class
4817 *
4818 * @return String
4819 **/
GetStagePrefix(Shader::STAGES stage,Variable::STORAGE storage)4820 const GLchar *ProgramInterface::GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage)
4821 {
4822 static const GLchar *lut[Shader::STAGE_MAX][Variable::STORAGE_MAX] = {
4823 /* IN OUT UNIFORM SSB MEMBER */
4824 /* CS */ {0, 0, "cs_uni_", "cs_buf_", ""},
4825 /* VS */ {"in_vs_", "vs_tcs_", "vs_uni_", "vs_buf_", ""},
4826 /* TCS */ {"vs_tcs_", "tcs_tes_", "tcs_uni_", "tcs_buf_", ""},
4827 /* TES */ {"tcs_tes_", "tes_gs_", "tes_uni_", "tes_buf_", ""},
4828 /* GS */ {"tes_gs_", "gs_fs_", "gs_uni_", "gs_buf_", ""},
4829 /* FS */ {"gs_fs_", "fs_out_", "fs_uni_", "fs_buf_", ""},
4830 };
4831
4832 const GLchar *result = 0;
4833
4834 result = lut[stage][storage];
4835
4836 return result;
4837 }
4838
4839 /** Get definitions of all structures used in program interface
4840 *
4841 * @return String with code
4842 **/
GetDefinitionsStructures() const4843 std::string ProgramInterface::GetDefinitionsStructures() const
4844 {
4845 return GetDefinitions(m_structures);
4846 }
4847
4848 /** Get interface code for stage
4849 *
4850 * @param stage Specific stage
4851 *
4852 * @return String with code
4853 **/
GetInterfaceForStage(Shader::STAGES stage) const4854 std::string ProgramInterface::GetInterfaceForStage(Shader::STAGES stage) const
4855 {
4856 size_t position = 0;
4857 std::string interface = "/* Globals */\n"
4858 "GLOBALS\n"
4859 "\n"
4860 "/* Structures */\n"
4861 "STRUCTURES\n"
4862 "\n"
4863 "/* Uniforms */\n"
4864 "UNIFORMS\n"
4865 "\n"
4866 "/* Inputs */\n"
4867 "INPUTS\n"
4868 "\n"
4869 "/* Outputs */\n"
4870 "OUTPUTS\n"
4871 "\n"
4872 "/* Storage */\n"
4873 "STORAGE\n";
4874
4875 const ShaderInterface &si = GetShaderInterface(stage);
4876
4877 const std::string &structures = GetDefinitionsStructures();
4878
4879 const std::string &globals = si.GetDefinitionsGlobals();
4880 const std::string &inputs = si.GetDefinitionsInputs();
4881 const std::string &outputs = si.GetDefinitionsOutputs();
4882 const std::string &uniforms = si.GetDefinitionsUniforms();
4883 const std::string &ssbs = si.GetDefinitionsSSBs();
4884
4885 replaceToken("GLOBALS", position, globals.c_str(), interface);
4886 replaceToken("STRUCTURES", position, structures.c_str(), interface);
4887 replaceToken("UNIFORMS", position, uniforms.c_str(), interface);
4888 replaceToken("INPUTS", position, inputs.c_str(), interface);
4889 replaceToken("OUTPUTS", position, outputs.c_str(), interface);
4890 replaceToken("STORAGE", position, ssbs.c_str(), interface);
4891
4892 return interface;
4893 }
4894
4895 /** Functional object used in find_if algorithm, in search for interface of given name
4896 *
4897 **/
4898 struct matchInterfaceName
4899 {
matchInterfaceNamegl4cts::EnhancedLayouts::Utils::matchInterfaceName4900 matchInterfaceName(const GLchar *name) : m_name(name)
4901 {
4902 }
4903
operator ()gl4cts::EnhancedLayouts::Utils::matchInterfaceName4904 bool operator()(const Interface *interface)
4905 {
4906 return 0 == interface->m_name.compare(m_name);
4907 }
4908
4909 const GLchar *m_name;
4910 };
4911
4912 /** Finds interface of given name in given vector of interfaces
4913 *
4914 * @param vector Collection of interfaces
4915 * @param name Requested name
4916 *
4917 * @return Pointer to interface if available, 0 otherwise
4918 **/
findInterfaceByName(Interface::PtrVector & vector,const GLchar * name)4919 static Interface *findInterfaceByName(Interface::PtrVector &vector, const GLchar *name)
4920 {
4921 Interface::PtrVector::iterator it = std::find_if(vector.begin(), vector.end(), matchInterfaceName(name));
4922
4923 if (vector.end() != it)
4924 {
4925 return *it;
4926 }
4927 else
4928 {
4929 return 0;
4930 }
4931 }
4932
4933 /** Search for block of given name
4934 *
4935 * @param name Name of block
4936 *
4937 * @return Pointer to block or 0
4938 **/
GetBlock(const GLchar * name)4939 Interface *ProgramInterface::GetBlock(const GLchar *name)
4940 {
4941 return findInterfaceByName(m_blocks, name);
4942 }
4943
4944 /** Search for structure of given name
4945 *
4946 * @param name Name of structure
4947 *
4948 * @return Pointer to structure or 0
4949 **/
GetStructure(const GLchar * name)4950 Interface *ProgramInterface::GetStructure(const GLchar *name)
4951 {
4952 return findInterfaceByName(m_structures, name);
4953 }
4954
4955 /** Adds new sturcture to interface
4956 *
4957 * @param name Name of structure
4958 *
4959 * @return Created structure
4960 **/
Structure(const GLchar * name)4961 Interface *ProgramInterface::Structure(const GLchar *name)
4962 {
4963 return AddInterface(name, Interface::STRUCT);
4964 }
4965
4966 /** Replace "BINDING" token in qualifiers string to value specific for given stage
4967 *
4968 * @param variable Variable to modify
4969 * @param stage Requested stage
4970 **/
replaceBinding(Variable & variable,Shader::STAGES stage)4971 void ProgramInterface::replaceBinding(Variable &variable, Shader::STAGES stage)
4972 {
4973 GLchar binding[16];
4974 sprintf(binding, "%d", stage);
4975 replaceAllTokens("BINDING", binding, variable.m_descriptor.m_qualifiers);
4976 }
4977 } // namespace Utils
4978
4979 /** Debuging procedure. Logs parameters.
4980 *
4981 * @param source As specified in GL spec.
4982 * @param type As specified in GL spec.
4983 * @param id As specified in GL spec.
4984 * @param severity As specified in GL spec.
4985 * @param ignored
4986 * @param message As specified in GL spec.
4987 * @param info Pointer to instance of Context used by test.
4988 */
debug_proc(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei,const GLchar * message,void * info)4989 void GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */,
4990 const GLchar *message, void *info)
4991 {
4992 deqp::Context *ctx = (deqp::Context *)info;
4993
4994 const GLchar *source_str = "Unknown";
4995 const GLchar *type_str = "Unknown";
4996 const GLchar *severity_str = "Unknown";
4997
4998 switch (source)
4999 {
5000 case GL_DEBUG_SOURCE_API:
5001 source_str = "API";
5002 break;
5003 case GL_DEBUG_SOURCE_APPLICATION:
5004 source_str = "APP";
5005 break;
5006 case GL_DEBUG_SOURCE_OTHER:
5007 source_str = "OTR";
5008 break;
5009 case GL_DEBUG_SOURCE_SHADER_COMPILER:
5010 source_str = "COM";
5011 break;
5012 case GL_DEBUG_SOURCE_THIRD_PARTY:
5013 source_str = "3RD";
5014 break;
5015 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
5016 source_str = "WS";
5017 break;
5018 default:
5019 break;
5020 }
5021
5022 switch (type)
5023 {
5024 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
5025 type_str = "DEPRECATED_BEHAVIOR";
5026 break;
5027 case GL_DEBUG_TYPE_ERROR:
5028 type_str = "ERROR";
5029 break;
5030 case GL_DEBUG_TYPE_MARKER:
5031 type_str = "MARKER";
5032 break;
5033 case GL_DEBUG_TYPE_OTHER:
5034 type_str = "OTHER";
5035 break;
5036 case GL_DEBUG_TYPE_PERFORMANCE:
5037 type_str = "PERFORMANCE";
5038 break;
5039 case GL_DEBUG_TYPE_POP_GROUP:
5040 type_str = "POP_GROUP";
5041 break;
5042 case GL_DEBUG_TYPE_PORTABILITY:
5043 type_str = "PORTABILITY";
5044 break;
5045 case GL_DEBUG_TYPE_PUSH_GROUP:
5046 type_str = "PUSH_GROUP";
5047 break;
5048 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
5049 type_str = "UNDEFINED_BEHAVIOR";
5050 break;
5051 default:
5052 break;
5053 }
5054
5055 switch (severity)
5056 {
5057 case GL_DEBUG_SEVERITY_HIGH:
5058 severity_str = "H";
5059 break;
5060 case GL_DEBUG_SEVERITY_LOW:
5061 severity_str = "L";
5062 break;
5063 case GL_DEBUG_SEVERITY_MEDIUM:
5064 severity_str = "M";
5065 break;
5066 case GL_DEBUG_SEVERITY_NOTIFICATION:
5067 severity_str = "N";
5068 break;
5069 default:
5070 break;
5071 }
5072
5073 ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
5074 << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
5075 << ": " << message << tcu::TestLog::EndMessage;
5076 }
5077
5078 /** Constructor
5079 *
5080 * @param context Test context
5081 * @param test_name Test name
5082 * @param test_description Test description
5083 **/
TestBase(deqp::Context & context,const GLchar * test_name,const GLchar * test_description)5084 TestBase::TestBase(deqp::Context &context, const GLchar *test_name, const GLchar *test_description)
5085 : TestCase(context, test_name, test_description)
5086 {
5087 /* Nothing to be done here */
5088 }
5089
5090 /** Execute test
5091 *
5092 * @return tcu::TestNode::STOP otherwise
5093 **/
iterate()5094 tcu::TestNode::IterateResult TestBase::iterate()
5095 {
5096 bool test_result;
5097
5098 #if DEBUG_ENBALE_MESSAGE_CALLBACK
5099 const Functions &gl = m_context.getRenderContext().getFunctions();
5100
5101 gl.debugMessageCallback(debug_proc, &m_context);
5102 GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
5103 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
5104
5105 try
5106 {
5107 /* Execute test */
5108 test_result = test();
5109 }
5110 catch (std::exception &exc)
5111 {
5112 TCU_FAIL(exc.what());
5113 }
5114
5115 /* Set result */
5116 if (true == test_result)
5117 {
5118 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
5119 }
5120 else
5121 {
5122 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5123 }
5124
5125 /* Done */
5126 return tcu::TestNode::STOP;
5127 }
5128
5129 /** Get last input location available for given type at specific stage
5130 *
5131 * @param stage Shader stage
5132 * @param type Input type
5133 * @param array_length Length of input array
5134 *
5135 * @return Last location index
5136 **/
getLastInputLocation(Utils::Shader::STAGES stage,const Utils::Type & type,GLuint array_length,bool ignore_prev_stage)5137 GLint TestBase::getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type &type, GLuint array_length,
5138 bool ignore_prev_stage)
5139 {
5140 GLint divide = 4; /* 4 components per location */
5141 GLint param = 0;
5142 GLenum pname = 0;
5143 GLint paramPrev = 0;
5144 GLenum pnamePrev = 0;
5145
5146 /* Select pnmae */
5147 switch (stage)
5148 {
5149 case Utils::Shader::FRAGMENT:
5150 pname = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5151 pnamePrev = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5152 break;
5153 case Utils::Shader::GEOMETRY:
5154 pname = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5155 pnamePrev = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5156 break;
5157 case Utils::Shader::TESS_CTRL:
5158 pname = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5159 pnamePrev = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5160 break;
5161 case Utils::Shader::TESS_EVAL:
5162 pname = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5163 pnamePrev = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5164 break;
5165 case Utils::Shader::VERTEX:
5166 pname = GL_MAX_VERTEX_ATTRIBS;
5167 divide = 1;
5168 break;
5169 default:
5170 TCU_FAIL("Invalid enum");
5171 }
5172
5173 /* Zero means no array, but 1 slot is required */
5174 if (0 == array_length)
5175 {
5176 array_length += 1;
5177 }
5178
5179 /* Get MAX */
5180 const Functions &gl = m_context.getRenderContext().getFunctions();
5181
5182 gl.getIntegerv(pname, ¶m);
5183 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5184
5185 if (pnamePrev && !ignore_prev_stage)
5186 {
5187 gl.getIntegerv(pnamePrev, ¶mPrev);
5188 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5189
5190 /* Don't read from a location that doesn't exist in the previous stage */
5191 param = de::min(param, paramPrev);
5192 }
5193
5194 /* Calculate */
5195 #if WRKARD_VARYINGLOCATIONSTEST
5196
5197 const GLint n_avl_locations = 16;
5198
5199 #else
5200
5201 const GLint n_avl_locations = param / divide;
5202
5203 #endif
5204
5205 const GLuint n_req_location = type.GetLocations(stage == Utils::Shader::VERTEX) * array_length;
5206
5207 return n_avl_locations - n_req_location; /* last is max - 1 */
5208 }
5209
5210 /** Get last output location available for given type at specific stage
5211 *
5212 * @param stage Shader stage
5213 * @param type Input type
5214 * @param array_length Length of input array
5215 *
5216 * @return Last location index
5217 **/
getLastOutputLocation(Utils::Shader::STAGES stage,const Utils::Type & type,GLuint array_length,bool ignore_next_stage)5218 GLint TestBase::getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type &type, GLuint array_length,
5219 bool ignore_next_stage)
5220 {
5221 GLint param = 0;
5222 GLenum pname = 0;
5223 GLint paramNext = 0;
5224 GLenum pnameNext = 0;
5225
5226 /* Select pname */
5227 switch (stage)
5228 {
5229 case Utils::Shader::GEOMETRY:
5230 pname = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5231 pnameNext = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5232 break;
5233 case Utils::Shader::TESS_CTRL:
5234 pname = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5235 pnameNext = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5236 break;
5237 case Utils::Shader::TESS_EVAL:
5238 pname = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5239 pnameNext = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5240 break;
5241 case Utils::Shader::VERTEX:
5242 pname = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5243 pnameNext = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5244 break;
5245 default:
5246 TCU_FAIL("Invalid enum");
5247 }
5248
5249 /* Zero means no array, but 1 slot is required */
5250 if (0 == array_length)
5251 {
5252 array_length += 1;
5253 }
5254
5255 /* Get MAX */
5256 const Functions &gl = m_context.getRenderContext().getFunctions();
5257
5258 gl.getIntegerv(pname, ¶m);
5259 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5260
5261 /* Calculate */
5262 #if WRKARD_VARYINGLOCATIONSTEST
5263
5264 const GLint n_avl_locations = 16;
5265
5266 #else
5267
5268 /* Don't write to a location that doesn't exist in the next stage */
5269 if (!ignore_next_stage)
5270 {
5271 gl.getIntegerv(pnameNext, ¶mNext);
5272 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5273
5274 param = de::min(param, paramNext);
5275 }
5276
5277 const GLint n_avl_locations = param / 4; /* 4 components per location */
5278
5279 #endif
5280
5281 const GLuint n_req_location = type.GetLocations() * array_length;
5282
5283 return n_avl_locations - n_req_location; /* last is max - 1 */
5284 }
5285
5286 /** Basic implementation
5287 *
5288 * @param ignored
5289 *
5290 * @return Empty string
5291 **/
getTestCaseName(GLuint)5292 std::string TestBase::getTestCaseName(GLuint /* test_case_index */)
5293 {
5294 std::string result;
5295
5296 return result;
5297 }
5298
5299 /** Basic implementation
5300 *
5301 * @return 1
5302 **/
getTestCaseNumber()5303 GLuint TestBase::getTestCaseNumber()
5304 {
5305 return 1;
5306 }
5307
5308 /** Check if flat qualifier is required for given type, stage and storage
5309 *
5310 * @param stage Shader stage
5311 * @param type Input type
5312 * @param storage Storage of variable
5313 *
5314 * @return Last location index
5315 **/
isFlatRequired(Utils::Shader::STAGES stage,const Utils::Type & type,Utils::Variable::STORAGE storage,const bool coherent) const5316 bool TestBase::isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type &type, Utils::Variable::STORAGE storage,
5317 const bool coherent) const
5318 {
5319 /* Float types do not need flat at all */
5320 if (Utils::Type::Float == type.m_basic_type)
5321 {
5322 return false;
5323 }
5324
5325 /* Inputs to fragment shader */
5326 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_INPUT == storage))
5327 {
5328 return true;
5329 }
5330
5331 /* Outputs from geometry shader
5332 *
5333 * This is not strictly needed since fragment shader input
5334 * interpolation qualifiers will override whatever comes from the
5335 * previous stage. However, if we want to have a coherent
5336 * interface, let's better do it.
5337 */
5338 if ((Utils::Shader::GEOMETRY == stage) && (Utils::Variable::VARYING_OUTPUT == storage) && coherent)
5339 {
5340 return true;
5341 }
5342
5343 return false;
5344 }
5345
5346 /** Basic implementation of testInit method
5347 *
5348 **/
testInit()5349 void TestBase::testInit()
5350 {
5351 }
5352
5353 /** Calculate stride for interface
5354 *
5355 * @param interface Interface
5356 *
5357 * @return Calculated value
5358 **/
calculateStride(const Utils::Interface & interface) const5359 GLuint TestBase::calculateStride(const Utils::Interface &interface) const
5360 {
5361 const size_t n_members = interface.m_members.size();
5362
5363 GLuint stride = 0;
5364
5365 for (size_t i = 0; i < n_members; ++i)
5366 {
5367 const Utils::Variable::Descriptor &member = interface.m_members[i];
5368 const GLuint member_offset = member.m_offset;
5369 const GLuint member_stride = member.m_expected_stride_of_element;
5370 const GLuint member_ends_at = member_offset + member_stride;
5371
5372 stride = std::max(stride, member_ends_at);
5373 }
5374
5375 return stride;
5376 }
5377
5378 /** Generate data for interface. This routine is recursive
5379 *
5380 * @param interface Interface
5381 * @param offset Offset in out_data
5382 * @param out_data Buffer to be filled
5383 **/
generateData(const Utils::Interface & interface,GLuint offset,std::vector<GLubyte> & out_data) const5384 void TestBase::generateData(const Utils::Interface &interface, GLuint offset, std::vector<GLubyte> &out_data) const
5385 {
5386 const size_t n_members = interface.m_members.size();
5387 GLubyte *ptr = &out_data[offset];
5388
5389 for (size_t i = 0; i < n_members; ++i)
5390 {
5391 const Utils::Variable::Descriptor &member = interface.m_members[i];
5392 const GLuint member_offset = member.m_offset;
5393 const GLuint n_elements = (0 == member.m_n_array_elements) ? 1 : member.m_n_array_elements;
5394
5395 for (GLuint element = 0; element < n_elements; ++element)
5396 {
5397 const GLuint element_offset = element * member.m_expected_stride_of_element;
5398 const GLuint data_offfset = member_offset + element_offset;
5399
5400 if (Utils::Variable::BUILTIN == member.m_type)
5401 {
5402 const std::vector<GLubyte> &data = member.m_builtin.GenerateData();
5403
5404 memcpy(ptr + data_offfset, &data[0], data.size());
5405 }
5406 else
5407 {
5408 generateData(*member.m_interface, offset + data_offfset, out_data);
5409 }
5410 }
5411 }
5412 }
5413
5414 /** Get type at index
5415 *
5416 * @param index Index of requested type
5417 *
5418 * @return Type
5419 **/
getType(GLuint index) const5420 Utils::Type TestBase::getType(GLuint index) const
5421 {
5422 Utils::Type type;
5423
5424 switch (index)
5425 {
5426 case 0:
5427 type = Utils::Type::_double;
5428 break;
5429 case 1:
5430 type = Utils::Type::dmat2;
5431 break;
5432 case 2:
5433 type = Utils::Type::dmat2x3;
5434 break;
5435 case 3:
5436 type = Utils::Type::dmat2x4;
5437 break;
5438 case 4:
5439 type = Utils::Type::dmat3;
5440 break;
5441 case 5:
5442 type = Utils::Type::dmat3x2;
5443 break;
5444 case 6:
5445 type = Utils::Type::dmat3x4;
5446 break;
5447 case 7:
5448 type = Utils::Type::dmat4;
5449 break;
5450 case 8:
5451 type = Utils::Type::dmat4x2;
5452 break;
5453 case 9:
5454 type = Utils::Type::dmat4x3;
5455 break;
5456 case 10:
5457 type = Utils::Type::dvec2;
5458 break;
5459 case 11:
5460 type = Utils::Type::dvec3;
5461 break;
5462 case 12:
5463 type = Utils::Type::dvec4;
5464 break;
5465 case 13:
5466 type = Utils::Type::_float;
5467 break;
5468 case 14:
5469 type = Utils::Type::mat2;
5470 break;
5471 case 15:
5472 type = Utils::Type::mat2x3;
5473 break;
5474 case 16:
5475 type = Utils::Type::mat2x4;
5476 break;
5477 case 17:
5478 type = Utils::Type::mat3;
5479 break;
5480 case 18:
5481 type = Utils::Type::mat3x2;
5482 break;
5483 case 19:
5484 type = Utils::Type::mat3x4;
5485 break;
5486 case 20:
5487 type = Utils::Type::mat4;
5488 break;
5489 case 21:
5490 type = Utils::Type::mat4x2;
5491 break;
5492 case 22:
5493 type = Utils::Type::mat4x3;
5494 break;
5495 case 23:
5496 type = Utils::Type::vec2;
5497 break;
5498 case 24:
5499 type = Utils::Type::vec3;
5500 break;
5501 case 25:
5502 type = Utils::Type::vec4;
5503 break;
5504 case 26:
5505 type = Utils::Type::_int;
5506 break;
5507 case 27:
5508 type = Utils::Type::ivec2;
5509 break;
5510 case 28:
5511 type = Utils::Type::ivec3;
5512 break;
5513 case 29:
5514 type = Utils::Type::ivec4;
5515 break;
5516 case 30:
5517 type = Utils::Type::uint;
5518 break;
5519 case 31:
5520 type = Utils::Type::uvec2;
5521 break;
5522 case 32:
5523 type = Utils::Type::uvec3;
5524 break;
5525 case 33:
5526 type = Utils::Type::uvec4;
5527 break;
5528 default:
5529 TCU_FAIL("invalid enum");
5530 }
5531
5532 return type;
5533 }
5534
5535 /** Get name of type at index
5536 *
5537 * @param index Index of type
5538 *
5539 * @return Name
5540 **/
getTypeName(GLuint index) const5541 std::string TestBase::getTypeName(GLuint index) const
5542 {
5543 std::string name = getType(index).GetGLSLTypeName();
5544
5545 return name;
5546 }
5547
5548 /** Get number of types
5549 *
5550 * @return 34
5551 **/
getTypesNumber() const5552 glw::GLuint TestBase::getTypesNumber() const
5553 {
5554 return 34;
5555 }
5556
5557 /** Execute test
5558 *
5559 * @return true if test pass, false otherwise
5560 **/
test()5561 bool TestBase::test()
5562 {
5563 bool result = true;
5564 GLuint n_test_cases = 0;
5565
5566 /* Prepare test */
5567 testInit();
5568
5569 /* GL entry points */
5570 const Functions &gl = m_context.getRenderContext().getFunctions();
5571
5572 /* Tessellation patch set up */
5573 gl.patchParameteri(GL_PATCH_VERTICES, 1);
5574 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
5575
5576 /* Get number of test cases */
5577 n_test_cases = getTestCaseNumber();
5578
5579 #if DEBUG_REPEAT_TEST_CASE
5580
5581 while (1)
5582 {
5583 GLuint test_case = DEBUG_REPEATED_TEST_CASE;
5584
5585 #else /* DEBUG_REPEAT_TEST_CASE */
5586
5587 for (GLuint test_case = 0; test_case < n_test_cases; ++test_case)
5588 {
5589 #endif /* DEBUG_REPEAT_TEST_CASE */
5590
5591 /* Execute case */
5592 if (!testCase(test_case))
5593 {
5594 const std::string &test_case_name = getTestCaseName(test_case);
5595
5596 if (false == test_case_name.empty())
5597 {
5598 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case_name
5599 << ") failed." << tcu::TestLog::EndMessage;
5600 }
5601 else
5602 {
5603 m_context.getTestContext().getLog()
5604 << tcu::TestLog::Message << "Test case (" << test_case << ") failed." << tcu::TestLog::EndMessage;
5605 }
5606
5607 result = false;
5608 }
5609 }
5610
5611 /* Done */
5612 return result;
5613 }
5614
5615 /* Constants used by BufferTestBase */
5616 const GLuint BufferTestBase::bufferDescriptor::m_non_indexed = -1;
5617
5618 /** Constructor
5619 *
5620 * @param context Test context
5621 * @param test_name Name of test
5622 * @param test_description Description of test
5623 **/
5624 BufferTestBase::BufferTestBase(deqp::Context &context, const GLchar *test_name, const GLchar *test_description)
5625 : TestBase(context, test_name, test_description)
5626 {
5627 }
5628
5629 /** Execute drawArrays for single vertex
5630 *
5631 * @param ignored
5632 *
5633 * @return true
5634 **/
5635 bool BufferTestBase::executeDrawCall(bool tesEnabled, GLuint /* test_case_index */)
5636 {
5637 const Functions &gl = m_context.getRenderContext().getFunctions();
5638
5639 gl.disable(GL_RASTERIZER_DISCARD);
5640 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
5641
5642 gl.beginTransformFeedback(GL_POINTS);
5643 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
5644
5645 // Only TES is existed, glDrawArray can use the parameter GL_PATCHES
5646 if (tesEnabled == false)
5647 {
5648 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
5649 }
5650 else
5651 {
5652 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
5653 }
5654
5655 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
5656
5657 gl.endTransformFeedback();
5658 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
5659
5660 return true;
5661 }
5662
5663 /** Get descriptors of buffers necessary for test
5664 *
5665 * @param ignored
5666 * @param ignored
5667 **/
5668 void BufferTestBase::getBufferDescriptors(glw::GLuint /* test_case_index */,
5669 bufferDescriptor::Vector & /* out_descriptors */)
5670 {
5671 /* Nothhing to be done */
5672 }
5673
5674 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
5675 *
5676 * @param ignored
5677 * @param ignored
5678 **/
5679 void BufferTestBase::getCapturedVaryings(glw::GLuint /* test_case_index */,
5680 Utils::Program::NameVector & /* captured_varyings */,
5681 GLint * /* xfb_components */)
5682 {
5683 /* Nothing to be done */
5684 }
5685
5686 /** Get body of main function for given shader stage
5687 *
5688 * @param ignored
5689 * @param ignored
5690 * @param out_assignments Set to empty
5691 * @param out_calculations Set to empty
5692 **/
5693 void BufferTestBase::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5694 std::string &out_assignments, std::string &out_calculations)
5695 {
5696 out_assignments = "";
5697 out_calculations = "";
5698 }
5699
5700 /** Get interface of shader
5701 *
5702 * @param ignored
5703 * @param ignored
5704 * @param out_interface Set to ""
5705 **/
5706 void BufferTestBase::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5707 std::string &out_interface)
5708 {
5709 out_interface = "";
5710 }
5711
5712 /** Get source code of shader
5713 *
5714 * @param test_case_index Index of test case
5715 * @param stage Shader stage
5716 *
5717 * @return Source
5718 **/
5719 std::string BufferTestBase::getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage)
5720 {
5721 std::string assignments;
5722 std::string calculations;
5723 std::string interface;
5724
5725 /* */
5726 getShaderBody(test_case_index, stage, assignments, calculations);
5727 getShaderInterface(test_case_index, stage, interface);
5728
5729 /* */
5730 std::string source = getShaderTemplate(stage);
5731
5732 /* */
5733 size_t position = 0;
5734 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
5735 Utils::replaceToken("CALCULATIONS", position, calculations.c_str(), source);
5736 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
5737
5738 /* */
5739 return source;
5740 }
5741
5742 /** Inspects program to check if all resources are as expected
5743 *
5744 * @param ignored
5745 * @param ignored
5746 * @param ignored
5747 *
5748 * @return true
5749 **/
5750 bool BufferTestBase::inspectProgram(GLuint /* test_case_index */, Utils::Program & /* program */,
5751 std::stringstream & /* out_stream */)
5752 {
5753 return true;
5754 }
5755
5756 /** Runs test case
5757 *
5758 * @param test_case_index Id of test case
5759 *
5760 * @return true if test case pass, false otherwise
5761 **/
5762 bool BufferTestBase::testCase(GLuint test_case_index)
5763 {
5764 try
5765 {
5766 bufferCollection buffers;
5767 Utils::Program::NameVector captured_varyings;
5768 bufferDescriptor::Vector descriptors;
5769 Utils::Program program(m_context);
5770 Utils::VertexArray vao(m_context);
5771
5772 /* Get captured varyings */
5773 GLint xfb_components;
5774 getCapturedVaryings(test_case_index, captured_varyings, &xfb_components);
5775
5776 /* Don't generate shaders that try to capture more XFB components than the implementation's limit */
5777 if (captured_varyings.size() > 0)
5778 {
5779 const Functions &gl = m_context.getRenderContext().getFunctions();
5780
5781 GLint max_xfb_components;
5782 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_components);
5783 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5784
5785 if (xfb_components > max_xfb_components)
5786 return true;
5787 }
5788
5789 /* Get shader sources */
5790 const std::string &fragment_shader = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
5791 const std::string &geometry_shader = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
5792 const std::string &tess_ctrl_shader = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
5793 const std::string &tess_eval_shader = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
5794 const std::string &vertex_shader = getShaderSource(test_case_index, Utils::Shader::VERTEX);
5795
5796 /* Set up program */
5797 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
5798 vertex_shader, captured_varyings, true, false /* is_separable */);
5799
5800 /* Inspection */
5801 {
5802 std::stringstream stream;
5803 if (false == inspectProgram(test_case_index, program, stream))
5804 {
5805 m_context.getTestContext().getLog()
5806 << tcu::TestLog::Message
5807 << "Program inspection failed. Test case: " << getTestCaseName(test_case_index)
5808 << ". Reason: " << stream.str() << tcu::TestLog::EndMessage
5809 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5810 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5811 << tcu::TestLog::KernelSource(fragment_shader);
5812
5813 return false;
5814 }
5815 }
5816
5817 program.Use();
5818
5819 /* Set up buffers */
5820 getBufferDescriptors(test_case_index, descriptors);
5821 cleanBuffers();
5822 prepareBuffers(descriptors, buffers);
5823
5824 /* Set up vao */
5825 vao.Init();
5826 vao.Bind();
5827
5828 /* Draw */
5829 bool result = executeDrawCall((program.m_tess_eval.m_id != 0), test_case_index);
5830
5831 #if USE_NSIGHT
5832 m_context.getRenderContext().postIterate();
5833 #endif
5834
5835 if (false == result)
5836 {
5837 m_context.getTestContext().getLog()
5838 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5839 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5840 << tcu::TestLog::KernelSource(fragment_shader);
5841
5842 return false;
5843 }
5844
5845 /* Verify result */
5846 if (false == verifyBuffers(buffers))
5847 {
5848 m_context.getTestContext().getLog()
5849 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5850 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5851 << tcu::TestLog::KernelSource(fragment_shader);
5852
5853 return false;
5854 }
5855 }
5856 catch (Utils::Shader::InvalidSourceException &exc)
5857 {
5858 exc.log(m_context);
5859 TCU_FAIL(exc.what());
5860 }
5861 catch (Utils::Program::BuildException &exc)
5862 {
5863 exc.log(m_context);
5864 TCU_FAIL(exc.what());
5865 }
5866
5867 /* Done */
5868 return true;
5869 }
5870
5871 /** Verify contents of buffers
5872 *
5873 * @param buffers Collection of buffers to be verified
5874 *
5875 * @return true if everything is as expected, false otherwise
5876 **/
5877 bool BufferTestBase::verifyBuffers(bufferCollection &buffers)
5878 {
5879 bool result = true;
5880
5881 for (bufferCollection::Vector::iterator it = buffers.m_vector.begin(), end = buffers.m_vector.end(); end != it;
5882 ++it)
5883 {
5884 bufferCollection::pair &pair = *it;
5885 Utils::Buffer *buffer = pair.m_buffer;
5886 bufferDescriptor *descriptor = pair.m_descriptor;
5887 size_t size = descriptor->m_expected_data.size();
5888
5889 /* Skip buffers that have no expected data */
5890 if (0 == size)
5891 {
5892 continue;
5893 }
5894
5895 /* Get pointer to contents of buffer */
5896 buffer->Bind();
5897 GLvoid *buffer_data = buffer->Map(Utils::Buffer::ReadOnly);
5898
5899 /* Get pointer to expected data */
5900 GLvoid *expected_data = &descriptor->m_expected_data[0];
5901
5902 /* Compare */
5903 int res = memcmp(buffer_data, expected_data, size);
5904
5905 if (0 != res)
5906 {
5907 m_context.getTestContext().getLog()
5908 << tcu::TestLog::Message
5909 << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
5910 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
5911
5912 result = false;
5913 }
5914
5915 /* Release buffer mapping */
5916 buffer->UnMap();
5917 }
5918
5919 return result;
5920 }
5921
5922 /** Unbinds all uniforms and xfb
5923 *
5924 **/
5925 void BufferTestBase::cleanBuffers()
5926 {
5927 const Functions &gl = m_context.getRenderContext().getFunctions();
5928
5929 GLint max_uni = 0;
5930 GLint max_xfb = 0;
5931
5932 gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uni);
5933 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
5934 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5935
5936 for (GLint i = 0; i < max_uni; ++i)
5937 {
5938 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Uniform, i);
5939 }
5940
5941 for (GLint i = 0; i < max_xfb; ++i)
5942 {
5943 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Transform_feedback, i);
5944 }
5945 }
5946
5947 /** Get template of shader for given stage
5948 *
5949 * @param stage Stage
5950 *
5951 * @return Template of shader source
5952 **/
5953 std::string BufferTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
5954 {
5955 static const GLchar *compute_shader_template = "#version 430 core\n"
5956 "#extension GL_ARB_enhanced_layouts : require\n"
5957 "\n"
5958 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
5959 "\n"
5960 "writeonly uniform uimage2D uni_image;\n"
5961 "\n"
5962 "INTERFACE"
5963 "\n"
5964 "void main()\n"
5965 "{\n"
5966 "CALCULATIONS"
5967 "\n"
5968 "ASSIGNMENTS"
5969 "}\n"
5970 "\n";
5971
5972 static const GLchar *fragment_shader_template = "#version 430 core\n"
5973 "#extension GL_ARB_enhanced_layouts : require\n"
5974 "\n"
5975 "INTERFACE"
5976 "\n"
5977 "void main()\n"
5978 "{\n"
5979 "CALCULATIONS"
5980 "\n"
5981 "ASSIGNMENTS"
5982 "}\n"
5983 "\n";
5984
5985 // max_vertices is set to 3 for the test case "xfb_vertex_streams" declares 3 streams in geometry shader,
5986 // according to spec, max_vertices should be no less than 3 if there are 3 streams in GS.
5987 static const GLchar *geometry_shader_template = "#version 430 core\n"
5988 "#extension GL_ARB_enhanced_layouts : require\n"
5989 "\n"
5990 "layout(points) in;\n"
5991 "layout(points, max_vertices = 3) out;\n"
5992 "\n"
5993 "INTERFACE"
5994 "\n"
5995 "void main()\n"
5996 "{\n"
5997 "CALCULATIONS"
5998 "\n"
5999 "\n"
6000 "ASSIGNMENTS"
6001 " gl_Position = vec4(0, 0, 0, 1);\n"
6002 " EmitVertex();\n"
6003 "}\n"
6004 "\n";
6005
6006 static const GLchar *tess_ctrl_shader_template = "#version 430 core\n"
6007 "#extension GL_ARB_enhanced_layouts : require\n"
6008 "\n"
6009 "layout(vertices = 1) out;\n"
6010 "\n"
6011 "INTERFACE"
6012 "\n"
6013 "void main()\n"
6014 "{\n"
6015 "CALCULATIONS"
6016 "\n"
6017 "ASSIGNMENTS"
6018 "\n"
6019 " gl_TessLevelOuter[0] = 1.0;\n"
6020 " gl_TessLevelOuter[1] = 1.0;\n"
6021 " gl_TessLevelOuter[2] = 1.0;\n"
6022 " gl_TessLevelOuter[3] = 1.0;\n"
6023 " gl_TessLevelInner[0] = 1.0;\n"
6024 " gl_TessLevelInner[1] = 1.0;\n"
6025 "}\n"
6026 "\n";
6027
6028 static const GLchar *tess_eval_shader_template = "#version 430 core\n"
6029 "#extension GL_ARB_enhanced_layouts : require\n"
6030 "\n"
6031 "layout(isolines, point_mode) in;\n"
6032 "\n"
6033 "INTERFACE"
6034 "\n"
6035 "void main()\n"
6036 "{\n"
6037 "CALCULATIONS"
6038 "\n"
6039 "ASSIGNMENTS"
6040 "}\n"
6041 "\n";
6042
6043 static const GLchar *vertex_shader_template = "#version 430 core\n"
6044 "#extension GL_ARB_enhanced_layouts : require\n"
6045 "\n"
6046 "INTERFACE"
6047 "\n"
6048 "void main()\n"
6049 "{\n"
6050 "CALCULATIONS"
6051 "\n"
6052 "ASSIGNMENTS"
6053 "}\n"
6054 "\n";
6055
6056 const GLchar *result = 0;
6057
6058 switch (stage)
6059 {
6060 case Utils::Shader::COMPUTE:
6061 result = compute_shader_template;
6062 break;
6063 case Utils::Shader::FRAGMENT:
6064 result = fragment_shader_template;
6065 break;
6066 case Utils::Shader::GEOMETRY:
6067 result = geometry_shader_template;
6068 break;
6069 case Utils::Shader::TESS_CTRL:
6070 result = tess_ctrl_shader_template;
6071 break;
6072 case Utils::Shader::TESS_EVAL:
6073 result = tess_eval_shader_template;
6074 break;
6075 case Utils::Shader::VERTEX:
6076 result = vertex_shader_template;
6077 break;
6078 default:
6079 TCU_FAIL("Invalid enum");
6080 }
6081
6082 return result;
6083 }
6084
6085 /** Prepare buffer according to descriptor
6086 *
6087 * @param buffer Buffer to prepare
6088 * @param desc Descriptor
6089 **/
6090 void BufferTestBase::prepareBuffer(Utils::Buffer &buffer, bufferDescriptor &desc)
6091 {
6092 GLsizeiptr size = 0;
6093 GLvoid *data = 0;
6094
6095 if (false == desc.m_initial_data.empty())
6096 {
6097 size = desc.m_initial_data.size();
6098 data = &desc.m_initial_data[0];
6099 }
6100 else if (false == desc.m_expected_data.empty())
6101 {
6102 size = desc.m_expected_data.size();
6103 }
6104
6105 buffer.Init(desc.m_target, Utils::Buffer::StaticDraw, size, data);
6106
6107 if (bufferDescriptor::m_non_indexed != desc.m_index)
6108 {
6109 buffer.BindBase(desc.m_index);
6110 }
6111 else
6112 {
6113 buffer.Bind();
6114 }
6115 }
6116
6117 /** Prepare collection of buffer
6118 *
6119 * @param descriptors Collection of descriptors
6120 * @param out_buffers Collection of buffers
6121 **/
6122 void BufferTestBase::prepareBuffers(bufferDescriptor::Vector &descriptors, bufferCollection &out_buffers)
6123 {
6124 for (bufferDescriptor::Vector::iterator it = descriptors.begin(), end = descriptors.end(); end != it; ++it)
6125 {
6126 bufferCollection::pair pair;
6127
6128 pair.m_buffer = new Utils::Buffer(m_context);
6129 if (0 == pair.m_buffer)
6130 {
6131 TCU_FAIL("Memory allocation failed");
6132 }
6133
6134 pair.m_descriptor = &(*it);
6135
6136 prepareBuffer(*pair.m_buffer, *pair.m_descriptor);
6137
6138 out_buffers.m_vector.push_back(pair);
6139 }
6140 }
6141
6142 /** Destructor
6143 *
6144 **/
6145 BufferTestBase::bufferCollection::~bufferCollection()
6146 {
6147 for (Vector::iterator it = m_vector.begin(), end = m_vector.end(); end != it; ++it)
6148 {
6149 if (0 != it->m_buffer)
6150 {
6151 delete it->m_buffer;
6152 it->m_buffer = 0;
6153 }
6154 }
6155 }
6156
6157 /** Constructor
6158 *
6159 * @param context Test context
6160 * @param test_name Name of test
6161 * @param test_description Description of test
6162 **/
6163 NegativeTestBase::NegativeTestBase(deqp::Context &context, const GLchar *test_name, const GLchar *test_description)
6164 : TestBase(context, test_name, test_description)
6165 {
6166 }
6167
6168 /** Selects if "compute" stage is relevant for test
6169 *
6170 * @param ignored
6171 *
6172 * @return true
6173 **/
6174 bool NegativeTestBase::isComputeRelevant(GLuint /* test_case_index */)
6175 {
6176 return true;
6177 }
6178
6179 /** Selects if compilation failure is expected result
6180 *
6181 * @param ignored
6182 *
6183 * @return true
6184 **/
6185 bool NegativeTestBase::isFailureExpected(GLuint /* test_case_index */)
6186 {
6187 return true;
6188 }
6189
6190 /** Selects if the test case should use a separable program
6191 *
6192 * @param ignored
6193 *
6194 * @return false
6195 **/
6196 bool NegativeTestBase::isSeparable(const GLuint /* test_case_index */)
6197 {
6198 return false;
6199 }
6200
6201 /** Runs test case
6202 *
6203 * @param test_case_index Id of test case
6204 *
6205 * @return true if test case pass, false otherwise
6206 **/
6207 bool NegativeTestBase::testCase(GLuint test_case_index)
6208 {
6209 bool test_case_result = true;
6210
6211 /* Compute */
6212 if (true == isComputeRelevant(test_case_index))
6213 {
6214 const std::string &cs_source = getShaderSource(test_case_index, Utils::Shader::COMPUTE);
6215 bool is_build_error = false;
6216 const bool is_failure_expected = isFailureExpected(test_case_index);
6217 Utils::Program program(m_context);
6218
6219 try
6220 {
6221 program.Init(cs_source, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */,
6222 false /* separable */);
6223 }
6224 catch (Utils::Shader::InvalidSourceException &exc)
6225 {
6226 if (false == is_failure_expected)
6227 {
6228 m_context.getTestContext().getLog()
6229 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6230 exc.log(m_context);
6231 }
6232
6233 #if DEBUG_NEG_LOG_ERROR
6234
6235 else
6236 {
6237 m_context.getTestContext().getLog()
6238 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6239 << tcu::TestLog::EndMessage;
6240 exc.log(m_context);
6241 }
6242
6243 #endif /* DEBUG_NEG_LOG_ERROR */
6244
6245 is_build_error = true;
6246 }
6247 catch (Utils::Program::BuildException &exc)
6248 {
6249 if (false == is_failure_expected)
6250 {
6251 m_context.getTestContext().getLog()
6252 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6253 exc.log(m_context);
6254 }
6255
6256 #if DEBUG_NEG_LOG_ERROR
6257
6258 else
6259 {
6260 m_context.getTestContext().getLog()
6261 << tcu::TestLog::Message
6262 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6263 exc.log(m_context);
6264 }
6265
6266 #endif /* DEBUG_NEG_LOG_ERROR */
6267
6268 is_build_error = true;
6269 }
6270
6271 if (is_build_error != is_failure_expected)
6272 {
6273 if (!is_build_error)
6274 {
6275 m_context.getTestContext().getLog()
6276 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6277 Utils::Shader::LogSource(m_context, cs_source, Utils::Shader::COMPUTE);
6278 }
6279 test_case_result = false;
6280 }
6281 }
6282 else /* Draw */
6283 {
6284 const std::string &fs_source = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
6285 const std::string &gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
6286 bool is_build_error = false;
6287 const bool is_failure_expected = isFailureExpected(test_case_index);
6288 Utils::Program program(m_context);
6289 const std::string &tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
6290 const std::string &tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
6291 const std::string &vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
6292
6293 try
6294 {
6295 if (isSeparable(test_case_index))
6296 {
6297 program.Init("" /*cs*/, fs_source, "" /*gs_source*/, "" /*tcs_source*/, "" /*tes_source*/,
6298 "" /*vs_source*/, true /* separable */);
6299 program.Init("" /*cs*/, "" /*fs_source*/, gs_source, "" /*tcs_source*/, "" /*tes_source*/,
6300 "" /*vs_source*/, true /* separable */);
6301 program.Init("" /*cs*/, "" /*fs_source*/, "" /*gs_source*/, tcs_source, "" /*tes_source*/,
6302 "" /*vs_source*/, true /* separable */);
6303 program.Init("" /*cs*/, "" /*fs_source*/, "" /*gs_source*/, "" /*tcs_source*/, tes_source,
6304 "" /*vs_source*/, true /* separable */);
6305 program.Init("" /*cs*/, "" /*fs_source*/, "" /*gs_source*/, "" /*tcs_source*/, "" /*tes_source*/,
6306 vs_source, true /* separable */);
6307 }
6308 else
6309 {
6310 program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source,
6311 false /* separable */);
6312 }
6313 }
6314 catch (Utils::Shader::InvalidSourceException &exc)
6315 {
6316 if (false == is_failure_expected)
6317 {
6318 m_context.getTestContext().getLog()
6319 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6320 exc.log(m_context);
6321 }
6322
6323 #if DEBUG_NEG_LOG_ERROR
6324
6325 else
6326 {
6327 m_context.getTestContext().getLog()
6328 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6329 << tcu::TestLog::EndMessage;
6330 exc.log(m_context);
6331 }
6332
6333 #endif /* DEBUG_NEG_LOG_ERROR */
6334
6335 is_build_error = true;
6336 }
6337 catch (Utils::Program::BuildException &exc)
6338 {
6339 if (false == is_failure_expected)
6340 {
6341 m_context.getTestContext().getLog()
6342 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6343 exc.log(m_context);
6344 }
6345
6346 #if DEBUG_NEG_LOG_ERROR
6347
6348 else
6349 {
6350 m_context.getTestContext().getLog()
6351 << tcu::TestLog::Message
6352 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6353 exc.log(m_context);
6354 }
6355
6356 #endif /* DEBUG_NEG_LOG_ERROR */
6357
6358 is_build_error = true;
6359 }
6360
6361 if (is_build_error != is_failure_expected)
6362 {
6363 if (!is_build_error)
6364 {
6365 m_context.getTestContext().getLog()
6366 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6367 Utils::Shader::LogSource(m_context, vs_source, Utils::Shader::VERTEX);
6368 Utils::Shader::LogSource(m_context, tcs_source, Utils::Shader::TESS_CTRL);
6369 Utils::Shader::LogSource(m_context, tes_source, Utils::Shader::TESS_EVAL);
6370 Utils::Shader::LogSource(m_context, gs_source, Utils::Shader::GEOMETRY);
6371 Utils::Shader::LogSource(m_context, fs_source, Utils::Shader::FRAGMENT);
6372 }
6373 test_case_result = false;
6374 }
6375 }
6376
6377 return test_case_result;
6378 }
6379
6380 /* Constants used by TextureTestBase */
6381 const glw::GLuint TextureTestBase::m_width = 16;
6382 const glw::GLuint TextureTestBase::m_height = 16;
6383
6384 /** Constructor
6385 *
6386 * @param context Test context
6387 * @param test_name Name of test
6388 * @param test_description Description of test
6389 **/
6390 TextureTestBase::TextureTestBase(deqp::Context &context, const GLchar *test_name, const GLchar *test_description)
6391 : TestBase(context, test_name, test_description)
6392 {
6393 }
6394
6395 /** Get locations for all inputs with automatic_location
6396 *
6397 * @param program Program object
6398 * @param program_interface Interface of program
6399 **/
6400 void TextureTestBase::prepareAttribLocation(Utils::Program &program, Utils::ProgramInterface &program_interface)
6401 {
6402 Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6403
6404 Utils::Variable::PtrVector &inputs = si.m_inputs;
6405
6406 for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it)
6407 {
6408 /* Test does not specify location, query value and set */
6409 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6410 {
6411 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT);
6412 GLint location = 0;
6413
6414 program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location);
6415
6416 (*it)->m_descriptor.m_expected_location = location;
6417 }
6418 }
6419 }
6420
6421 /** Verifies contents of drawn image
6422 *
6423 * @param ignored
6424 * @param color_0 Verified image
6425 *
6426 * @return true if image is filled with 1, false otherwise
6427 **/
6428 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture &color_0)
6429 {
6430 static const GLuint size = m_width * m_height;
6431 static const GLuint expected_color = 1;
6432
6433 std::vector<GLuint> data;
6434 data.resize(size);
6435
6436 color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]);
6437
6438 for (GLuint i = 0; i < size; ++i)
6439 {
6440 const GLuint color = data[i];
6441
6442 if (expected_color != color)
6443 {
6444 m_context.getTestContext().getLog()
6445 << tcu::TestLog::Message << "R32UI[" << i << "]:" << color << tcu::TestLog::EndMessage;
6446 return false;
6447 }
6448 }
6449
6450 return true;
6451 }
6452
6453 /** Execute dispatch compute for 16x16x1
6454 *
6455 * @param ignored
6456 **/
6457 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */)
6458 {
6459 const Functions &gl = m_context.getRenderContext().getFunctions();
6460
6461 gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */);
6462 GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
6463 }
6464
6465 /** Execute drawArrays for single vertex
6466 *
6467 * @param ignored
6468 **/
6469 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */)
6470 {
6471 const Functions &gl = m_context.getRenderContext().getFunctions();
6472
6473 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
6474 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
6475 }
6476
6477 /** Prepare code snippet that will pass in variables to out variables
6478 *
6479 * @param ignored
6480 * @param varying_passthrough Collection of connections between in and out variables
6481 * @param stage Shader stage
6482 *
6483 * @return Code that pass in variables to next stage
6484 **/
6485 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */,
6486 Utils::VaryingPassthrough &varying_passthrough, Utils::Shader::STAGES stage)
6487 {
6488 static const GLchar *separator = "\n ";
6489
6490 /* Skip for compute shader */
6491 if (Utils::Shader::COMPUTE == stage)
6492 {
6493 return "";
6494 }
6495
6496 Utils::VaryingConnection::Vector &vector = varying_passthrough.Get(stage);
6497
6498 std::string result = Utils::g_list;
6499 size_t position = 0;
6500
6501 for (GLuint i = 0; i < vector.size(); ++i)
6502 {
6503
6504 Utils::VaryingConnection &connection = vector[i];
6505
6506 Utils::Variable *in = connection.m_in;
6507 Utils::Variable *out = connection.m_out;
6508
6509 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6510 Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT);
6511
6512 const std::string passthrough =
6513 getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour);
6514
6515 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6516 }
6517
6518 Utils::endList("", position, result);
6519
6520 return result;
6521 }
6522
6523 /** Basic implementation of method getProgramInterface
6524 *
6525 * @param ignored
6526 * @param ignored
6527 * @param ignored
6528 **/
6529 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */,
6530 Utils::ProgramInterface & /* program_interface */,
6531 Utils::VaryingPassthrough & /* varying_passthrough */)
6532 {
6533 }
6534
6535 /** Prepare code snippet that will verify in and uniform variables
6536 *
6537 * @param ignored
6538 * @param program_interface Interface of program
6539 * @param stage Shader stage
6540 *
6541 * @return Code that verify variables
6542 **/
6543 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */,
6544 Utils::ProgramInterface &program_interface,
6545 Utils::Shader::STAGES stage)
6546 {
6547 static const GLchar *separator = " ||\n ";
6548
6549 std::string verification = "if (LIST)\n"
6550 " {\n"
6551 " result = 0u;\n"
6552 " }\n";
6553
6554 /* Get flavour of in and out variables */
6555 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6556
6557 /* Get interface for shader stage */
6558 Utils::ShaderInterface &si = program_interface.GetShaderInterface(stage);
6559
6560 /* There are no varialbes to verify */
6561 if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size()))
6562 {
6563 return "";
6564 }
6565
6566 /* For each in variable insert verification code */
6567 size_t position = 0;
6568
6569 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6570 {
6571 const Utils::Variable &var = *si.m_inputs[i];
6572 const std::string &var_verification = getVariableVerification("", var.m_data, var.m_descriptor, in_flavour);
6573
6574 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6575 }
6576
6577 /* For each unifrom variable insert verification code */
6578 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6579 {
6580 const Utils::Variable &var = *si.m_uniforms[i];
6581 const std::string &var_verification =
6582 getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6583
6584 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6585 }
6586
6587 /* For each ssb variable insert verification code */
6588 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6589 {
6590 const Utils::Variable &var = *si.m_ssb_blocks[i];
6591 const std::string &var_verification =
6592 getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6593
6594 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6595 }
6596
6597 Utils::endList("", position, verification);
6598
6599 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE
6600
6601 {
6602 GLchar buffer[16];
6603 sprintf(buffer, "%d", stage + 10);
6604 Utils::replaceToken("0u", position, buffer, verification);
6605 }
6606
6607 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE
6608
6609 if (Utils::Shader::VERTEX == stage)
6610 {
6611 Utils::replaceToken("0u", position, "in_vs_first.x", verification);
6612 }
6613 else
6614 {
6615 Utils::replaceToken("0u", position, "31u", verification);
6616 }
6617
6618 #endif
6619
6620 /* Done */
6621 return verification;
6622 }
6623
6624 /** Selects if "compute" stage is relevant for test
6625 *
6626 * @param ignored
6627 *
6628 * @return true
6629 **/
6630 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */)
6631 {
6632 return true;
6633 }
6634
6635 /** Selects if "draw" stages are relevant for test
6636 *
6637 * @param ignored
6638 *
6639 * @return true
6640 **/
6641 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */)
6642 {
6643 return true;
6644 }
6645
6646 /** Prepare code that will do assignment of single in to single out
6647 *
6648 * @param in_parent_name Name of parent in variable
6649 * @param in_variable Descriptor of in variable
6650 * @param in_flavour Flavoud of in variable
6651 * @param out_parent_name Name of parent out variable
6652 * @param out_variable Descriptor of out variable
6653 * @param out_flavour Flavoud of out variable
6654 *
6655 * @return Code that does OUT = IN
6656 **/
6657 std::string TextureTestBase::getVariablePassthrough(const std::string &in_parent_name,
6658 const Utils::Variable::Descriptor &in_variable,
6659 Utils::Variable::FLAVOUR in_flavour,
6660 const std::string &out_parent_name,
6661 const Utils::Variable::Descriptor &out_variable,
6662 Utils::Variable::FLAVOUR out_flavour)
6663 {
6664 bool done = false;
6665 GLuint index = 0;
6666 GLuint member_index = 0;
6667 size_t position = 0;
6668 std::string result = Utils::g_list;
6669 static const GLchar *separator = ";\n ";
6670
6671 /* For each member of each array element */
6672 do
6673 {
6674 const std::string in_name = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index);
6675 const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index);
6676 std::string passthrough;
6677
6678 /* Prepare verification */
6679 if (Utils::Variable::BUILTIN == in_variable.m_type)
6680 {
6681 size_t pass_position = 0;
6682
6683 passthrough = "OUT = IN;";
6684
6685 Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough);
6686 Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough);
6687
6688 /* Increment index */
6689 ++index;
6690 }
6691 else
6692 {
6693 const Utils::Interface *in_interface = in_variable.m_interface;
6694 const Utils::Interface *out_interface = out_variable.m_interface;
6695
6696 if ((0 == in_interface) || (0 == out_interface))
6697 {
6698 TCU_FAIL("Nullptr");
6699 }
6700
6701 const Utils::Variable::Descriptor &in_member = in_interface->m_members[member_index];
6702 const Utils::Variable::Descriptor &out_member = out_interface->m_members[member_index];
6703
6704 passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member,
6705 Utils::Variable::BASIC);
6706
6707 /* Increment member_index */
6708 ++member_index;
6709
6710 /* Increment index and reset member_index if all members were processed */
6711 if (in_interface->m_members.size() == member_index)
6712 {
6713 ++index;
6714 member_index = 0;
6715 }
6716 }
6717
6718 /* Check if loop should end */
6719 if ((index >= in_variable.m_n_array_elements) && (0 == member_index))
6720 {
6721 done = true;
6722 }
6723
6724 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6725
6726 } while (true != done);
6727
6728 Utils::endList("", position, result);
6729
6730 /* Done */
6731 return result;
6732 }
6733
6734 /** Get verification of single variable
6735 *
6736 * @param parent_name Name of parent variable
6737 * @param data Data that should be used as EXPECTED
6738 * @param variable Descriptor of variable
6739 * @param flavour Flavour of variable
6740 *
6741 * @return Code that does (EXPECTED != VALUE) ||
6742 **/
6743 std::string TextureTestBase::getVariableVerification(const std::string &parent_name, const GLvoid *data,
6744 const Utils::Variable::Descriptor &variable,
6745 Utils::Variable::FLAVOUR flavour)
6746 {
6747 static const GLchar *logic_op = " ||\n ";
6748 const GLuint n_elements = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements;
6749 size_t position = 0;
6750 std::string result = Utils::g_list;
6751 GLint stride = variable.m_expected_stride_of_element;
6752
6753 /* For each each array element */
6754 for (GLuint element = 0; element < n_elements; ++element)
6755 {
6756 const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element);
6757
6758 /* Calculate data pointer */
6759 GLvoid *data_ptr = (GLvoid *)((GLubyte *)data + element * stride);
6760
6761 /* Prepare verification */
6762 if (Utils::Variable::BUILTIN == variable.m_type)
6763 {
6764 const std::string &expected = variable.m_builtin.GetGLSLConstructor(data_ptr);
6765 std::string verification;
6766 size_t verification_position = 0;
6767
6768 verification = "(EXPECTED != NAME)";
6769
6770 Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification);
6771 Utils::replaceToken("NAME", verification_position, name.c_str(), verification);
6772
6773 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6774 }
6775 else
6776 {
6777 const Utils::Interface *interface = variable.m_interface;
6778
6779 if (0 == interface)
6780 {
6781 TCU_FAIL("Nullptr");
6782 }
6783
6784 const GLuint n_members = static_cast<GLuint>(interface->m_members.size());
6785
6786 /* for each member */
6787 for (GLuint member_index = 0; member_index < n_members; ++member_index)
6788 {
6789 const Utils::Variable::Descriptor &member = interface->m_members[member_index];
6790
6791 /* Get verification of member */
6792 const std::string &verification = getVariableVerification(name, (GLubyte *)data_ptr + member.m_offset,
6793 member, Utils::Variable::BASIC);
6794
6795 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6796 }
6797 }
6798 }
6799
6800 Utils::endList("", position, result);
6801
6802 return result;
6803 }
6804
6805 /** Prepare attributes, vertex array object and array buffer
6806 *
6807 * @param test_case_index Index of test case
6808 * @param program_interface Interface of program
6809 * @param buffer Array buffer
6810 * @param vao Vertex array object
6811 **/
6812 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface &program_interface,
6813 Utils::Buffer &buffer, Utils::VertexArray &vao)
6814 {
6815 const bool use_component_qualifier = useComponentQualifier(test_case_index);
6816
6817 /* Get shader interface */
6818 const Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6819
6820 /* Bind vao and buffer */
6821 vao.Bind();
6822 buffer.Bind();
6823
6824 /* Skip if there are no input variables in vertex shader */
6825 if (0 == si.m_inputs.size())
6826 {
6827 return;
6828 }
6829
6830 const Functions &gl = m_context.getRenderContext().getFunctions();
6831
6832 /* Calculate vertex stride and check */
6833 GLint max_inputs;
6834 gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_inputs);
6835 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
6836
6837 /* dvec3/4 vertex inputs use a single location but require 2x16B slots */
6838 const GLuint max_slots = max_inputs * 2;
6839
6840 /* Compute used slots */
6841 std::vector<GLuint> slot_sizes(max_slots, 0);
6842 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6843 {
6844 const Utils::Variable &variable = *si.m_inputs[i];
6845
6846 const GLuint variable_size = static_cast<GLuint>(variable.m_data_size);
6847
6848 const GLuint base_slot = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
6849 const GLuint ends_at = variable.m_descriptor.m_offset % 16 + variable_size;
6850
6851 const GLuint array_length = std::max(1u, variable.m_descriptor.m_n_array_elements);
6852 for (GLuint loc = 0; loc < array_length; loc++)
6853 {
6854 const GLuint slot = base_slot + loc;
6855 slot_sizes[slot] = std::max(slot_sizes[slot], ends_at);
6856 }
6857 }
6858
6859 /* Compute the offsets where we need to put vertex buffer data for each slot */
6860 std::vector<GLint> slot_offsets(max_slots, -1);
6861 GLuint buffer_size = 0;
6862 for (GLuint i = 0; i < max_slots; i++)
6863 {
6864 if (slot_sizes[i] == 0)
6865 continue;
6866 slot_offsets[i] = buffer_size;
6867 buffer_size += slot_sizes[i];
6868 }
6869
6870 /* Prepare buffer data and set up vao */
6871 std::vector<GLubyte> buffer_data(buffer_size);
6872
6873 GLubyte *ptr = &buffer_data[0];
6874
6875 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6876 {
6877 const Utils::Variable &variable = *si.m_inputs[i];
6878
6879 const GLuint base_slot = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
6880 const GLuint variable_offset = variable.m_descriptor.m_offset % 16;
6881 const GLuint array_length = std::max(1u, variable.m_descriptor.m_n_array_elements);
6882 for (GLuint loc = 0; loc < array_length; loc++)
6883 {
6884 const GLuint slot = base_slot + loc;
6885 memcpy(ptr + slot_offsets[slot] + variable_offset, variable.m_data, variable.m_data_size);
6886 }
6887
6888 if (!use_component_qualifier)
6889 {
6890 vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin,
6891 variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized,
6892 variable.GetStride(), (GLvoid *)(intptr_t)(slot_offsets[base_slot] + variable_offset));
6893 }
6894 else if (0 == variable.m_descriptor.m_expected_component)
6895 {
6896 /* Components can only be applied to types not surpassing
6897 * the bounds of a single slot. Therefore, we calculate
6898 * the amount of used components in the varying based on
6899 * the calculated slot sizes.
6900 */
6901 const GLuint n_component_size = Utils::Type::Double == variable.m_descriptor.m_builtin.m_basic_type ? 8 : 4;
6902 const GLuint n_rows = slot_sizes[base_slot] / n_component_size;
6903
6904 const Utils::Type &type = Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type,
6905 1 /* n_columns */, n_rows /* n_rows */);
6906
6907 vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements,
6908 variable.m_descriptor.m_normalized, variable.GetStride(),
6909 (GLvoid *)(intptr_t)(slot_offsets[base_slot] + variable_offset));
6910 }
6911 }
6912
6913 /* Update buffer */
6914 buffer.Data(Utils::Buffer::StaticDraw, buffer_size, ptr);
6915 }
6916
6917 /** Get locations for all outputs with automatic_location
6918 *
6919 * @param program Program object
6920 * @param program_interface Interface of program
6921 **/
6922 void TextureTestBase::prepareFragmentDataLoc(Utils::Program &program, Utils::ProgramInterface &program_interface)
6923 {
6924 Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6925 Utils::Variable::PtrVector &outputs = si.m_outputs;
6926
6927 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
6928 {
6929 /* Test does not specify location, query value and set */
6930 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6931 {
6932 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT);
6933 GLint location = 0;
6934
6935 program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location);
6936
6937 (*it)->m_descriptor.m_expected_location = location;
6938 }
6939 }
6940 }
6941
6942 /** Prepare framebuffer with single texture as color attachment
6943 *
6944 * @param framebuffer Framebuffer
6945 * @param color_0_texture Texture that will used as color attachment
6946 **/
6947 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer &framebuffer, Utils::Texture &color_0_texture)
6948 {
6949 /* Prepare data */
6950 std::vector<GLuint> texture_data;
6951 texture_data.resize(m_width * m_height);
6952
6953 for (GLuint i = 0; i < texture_data.size(); ++i)
6954 {
6955 texture_data[i] = 0x20406080;
6956 }
6957
6958 /* Prepare texture */
6959 color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6960 &texture_data[0]);
6961
6962 /* Prepare framebuffer */
6963 framebuffer.Init();
6964 framebuffer.Bind();
6965 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height);
6966
6967 framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6968 framebuffer.Clear(GL_COLOR_BUFFER_BIT);
6969 }
6970
6971 /** Prepare iamge unit for compute shader
6972 *
6973 * @param location Uniform location
6974 * @param image_texture Texture that will used as color attachment
6975 **/
6976 void TextureTestBase::prepareImage(GLint location, Utils::Texture &image_texture) const
6977 {
6978 static const GLuint image_unit = 0;
6979
6980 std::vector<GLuint> texture_data;
6981 texture_data.resize(m_width * m_height);
6982
6983 for (GLuint i = 0; i < texture_data.size(); ++i)
6984 {
6985 texture_data[i] = 0x20406080;
6986 }
6987
6988 image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6989 &texture_data[0]);
6990
6991 const Functions &gl = m_context.getRenderContext().getFunctions();
6992
6993 gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */,
6994 GL_WRITE_ONLY, GL_R32UI);
6995 GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
6996
6997 Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit);
6998 }
6999
7000 /** Basic implementation
7001 *
7002 * @param ignored
7003 * @param si Shader interface
7004 * @param program Program
7005 * @param cs_buffer Buffer for ssb blocks
7006 **/
7007 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface &si, Utils::Program &program,
7008 Utils::Buffer &buffer)
7009 {
7010 /* Skip if there are no input variables in vertex shader */
7011 if (0 == si.m_ssb_blocks.size())
7012 {
7013 return;
7014 }
7015
7016 /* Calculate vertex stride */
7017 GLint ssbs_stride = 0;
7018
7019 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
7020 {
7021 Utils::Variable &variable = *si.m_ssb_blocks[i];
7022
7023 if (false == variable.IsBlock())
7024 {
7025 continue;
7026 }
7027
7028 GLint variable_stride = variable.GetStride();
7029
7030 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
7031
7032 ssbs_stride = std::max(ssbs_stride, ends_at);
7033 }
7034
7035 /* Set active program */
7036 program.Use();
7037
7038 /* Allocate */
7039 buffer.Bind();
7040 buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0);
7041
7042 /* Set up uniforms */
7043 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
7044 {
7045 Utils::Variable &variable = *si.m_ssb_blocks[i];
7046
7047 /* prepareUnifor should work fine for ssb blocks */
7048 prepareUniform(program, variable, buffer);
7049 }
7050 }
7051
7052 /** Basic implementation
7053 *
7054 * @param test_case_index Test case index
7055 * @param program_interface Program interface
7056 * @param program Program
7057 * @param cs_buffer Buffer for compute shader stage
7058 **/
7059 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface &program_interface,
7060 Utils::Program &program, Utils::Buffer &cs_buffer)
7061 {
7062 cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7063
7064 Utils::ShaderInterface &cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7065
7066 prepareSSBs(test_case_index, cs, program, cs_buffer);
7067
7068 cs_buffer.BindBase(Utils::Shader::COMPUTE);
7069 }
7070
7071 /** Basic implementation
7072 *
7073 * @param test_case_index Test case index
7074 * @param program_interface Program interface
7075 * @param program Program
7076 * @param fs_buffer Buffer for fragment shader stage
7077 * @param gs_buffer Buffer for geometry shader stage
7078 * @param tcs_buffer Buffer for tessellation control shader stage
7079 * @param tes_buffer Buffer for tessellation evaluation shader stage
7080 * @param vs_buffer Buffer for vertex shader stage
7081 **/
7082 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface &program_interface,
7083 Utils::Program &program, Utils::Buffer &fs_buffer, Utils::Buffer &gs_buffer,
7084 Utils::Buffer &tcs_buffer, Utils::Buffer &tes_buffer, Utils::Buffer &vs_buffer)
7085 {
7086 fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7087 gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7088 tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7089 tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7090 vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7091
7092 Utils::ShaderInterface &fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7093 Utils::ShaderInterface &gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7094 Utils::ShaderInterface &tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7095 Utils::ShaderInterface &tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7096 Utils::ShaderInterface &vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7097
7098 prepareSSBs(test_case_index, fs, program, fs_buffer);
7099 prepareSSBs(test_case_index, gs, program, gs_buffer);
7100 prepareSSBs(test_case_index, tcs, program, tcs_buffer);
7101 prepareSSBs(test_case_index, tes, program, tes_buffer);
7102 prepareSSBs(test_case_index, vs, program, vs_buffer);
7103
7104 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7105 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7106 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7107 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7108 vs_buffer.BindBase(Utils::Shader::VERTEX);
7109 }
7110
7111 /** Updates buffer data with variable
7112 *
7113 * @param program Program object
7114 * @param variable Variable
7115 * @param buffer Buffer
7116 **/
7117 void TextureTestBase::prepareUniform(Utils::Program &program, Utils::Variable &variable, Utils::Buffer &buffer)
7118 {
7119 const Functions &gl = m_context.getRenderContext().getFunctions();
7120
7121 GLsizei count = variable.m_descriptor.m_n_array_elements;
7122 if (0 == count)
7123 {
7124 count = 1;
7125 }
7126
7127 if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type)
7128 {
7129 program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location,
7130 variable.m_data);
7131 }
7132 else
7133 {
7134 const bool is_block = variable.IsBlock();
7135
7136 if (false == is_block)
7137 {
7138 TCU_FAIL("Not implemented");
7139 }
7140 else
7141 {
7142 buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count,
7143 variable.m_data);
7144 }
7145 }
7146 }
7147
7148 /** Basic implementation
7149 *
7150 * @param ignored
7151 * @param si Shader interface
7152 * @param program Program
7153 * @param cs_buffer Buffer for uniform blocks
7154 **/
7155 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface &si, Utils::Program &program,
7156 Utils::Buffer &buffer)
7157 {
7158 /* Skip if there are no input variables in vertex shader */
7159 if (0 == si.m_uniforms.size())
7160 {
7161 return;
7162 }
7163
7164 /* Calculate vertex stride */
7165 GLint uniforms_stride = 0;
7166
7167 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7168 {
7169 Utils::Variable &variable = *si.m_uniforms[i];
7170
7171 if (false == variable.IsBlock())
7172 {
7173 continue;
7174 }
7175
7176 GLint variable_stride = variable.GetStride();
7177
7178 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
7179
7180 uniforms_stride = std::max(uniforms_stride, ends_at);
7181 }
7182
7183 /* Set active program */
7184 program.Use();
7185
7186 /* Allocate */
7187 buffer.Bind();
7188 buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0);
7189
7190 /* Set up uniforms */
7191 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7192 {
7193 Utils::Variable &variable = *si.m_uniforms[i];
7194
7195 prepareUniform(program, variable, buffer);
7196 }
7197 }
7198
7199 /** Basic implementation
7200 *
7201 * @param test_case_index Test case index
7202 * @param program_interface Program interface
7203 * @param program Program
7204 * @param cs_buffer Buffer for compute shader stage
7205 **/
7206 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface &program_interface,
7207 Utils::Program &program, Utils::Buffer &cs_buffer)
7208 {
7209 cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7210
7211 Utils::ShaderInterface &cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7212
7213 prepareUniforms(test_case_index, cs, program, cs_buffer);
7214
7215 cs_buffer.BindBase(Utils::Shader::COMPUTE);
7216 }
7217
7218 /** Basic implementation
7219 *
7220 * @param test_case_index Test case index
7221 * @param program_interface Program interface
7222 * @param program Program
7223 * @param fs_buffer Buffer for fragment shader stage
7224 * @param gs_buffer Buffer for geometry shader stage
7225 * @param tcs_buffer Buffer for tessellation control shader stage
7226 * @param tes_buffer Buffer for tessellation evaluation shader stage
7227 * @param vs_buffer Buffer for vertex shader stage
7228 **/
7229 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface &program_interface,
7230 Utils::Program &program, Utils::Buffer &fs_buffer, Utils::Buffer &gs_buffer,
7231 Utils::Buffer &tcs_buffer, Utils::Buffer &tes_buffer, Utils::Buffer &vs_buffer)
7232 {
7233 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7234 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7235 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7236 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7237 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7238
7239 Utils::ShaderInterface &fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7240 Utils::ShaderInterface &gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7241 Utils::ShaderInterface &tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7242 Utils::ShaderInterface &tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7243 Utils::ShaderInterface &vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7244
7245 prepareUniforms(test_case_index, fs, program, fs_buffer);
7246 prepareUniforms(test_case_index, gs, program, gs_buffer);
7247 prepareUniforms(test_case_index, tcs, program, tcs_buffer);
7248 prepareUniforms(test_case_index, tes, program, tes_buffer);
7249 prepareUniforms(test_case_index, vs, program, vs_buffer);
7250
7251 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7252 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7253 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7254 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7255 vs_buffer.BindBase(Utils::Shader::VERTEX);
7256 }
7257
7258 /** Basic implementation
7259 *
7260 * @param test_case_index Test case index
7261 * @param program_interface Program interface
7262 * @param program Program
7263 * @param fs_buffer Buffer for fragment shader stage
7264 * @param gs_buffer Buffer for geometry shader stage
7265 * @param tcs_buffer Buffer for tessellation control shader stage
7266 * @param tes_buffer Buffer for tessellation evaluation shader stage
7267 * @param vs_buffer Buffer for vertex shader stage
7268 **/
7269 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface &program_interface,
7270 Utils::Program &fs_program, Utils::Program &gs_program,
7271 Utils::Program &tcs_program, Utils::Program &tes_program,
7272 Utils::Program &vs_program, Utils::Buffer &fs_buffer, Utils::Buffer &gs_buffer,
7273 Utils::Buffer &tcs_buffer, Utils::Buffer &tes_buffer, Utils::Buffer &vs_buffer)
7274 {
7275 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7276 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7277 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7278 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7279 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7280
7281 Utils::ShaderInterface &fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7282 Utils::ShaderInterface &gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7283 Utils::ShaderInterface &tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7284 Utils::ShaderInterface &tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7285 Utils::ShaderInterface &vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7286
7287 prepareUniforms(test_case_index, fs, fs_program, fs_buffer);
7288 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7289
7290 prepareUniforms(test_case_index, gs, gs_program, gs_buffer);
7291 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7292
7293 prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer);
7294 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7295
7296 prepareUniforms(test_case_index, tes, tes_program, tes_buffer);
7297 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7298
7299 prepareUniforms(test_case_index, vs, vs_program, vs_buffer);
7300 vs_buffer.BindBase(Utils::Shader::VERTEX);
7301 }
7302
7303 /** Prepare source for shader
7304 *
7305 * @param test_case_index Index of test case
7306 * @param program_interface Interface of program
7307 * @param varying_passthrough Collection of connection between in and out variables
7308 * @param stage Shader stage
7309 *
7310 * @return Source of shader
7311 **/
7312 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface &program_interface,
7313 Utils::VaryingPassthrough &varying_passthrough,
7314 Utils::Shader::STAGES stage)
7315 {
7316 /* Get strings */
7317 const GLchar *shader_template = getShaderTemplate(stage);
7318 glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
7319 const char *shader_version = glu::getGLSLVersionDeclaration(glslVersion);
7320 const std::string &shader_interface = program_interface.GetInterfaceForStage(stage);
7321 const std::string &verification = getVerificationSnippet(test_case_index, program_interface, stage);
7322 const std::string &passthrough = getPassSnippet(test_case_index, varying_passthrough, stage);
7323
7324 const GLchar *per_vertex = "";
7325
7326 std::string source = shader_template;
7327 size_t position = 0;
7328
7329 Utils::replaceToken("VERSION", position, shader_version, source);
7330
7331 /* Replace tokens in template */
7332 if (Utils::Shader::GEOMETRY == stage)
7333 {
7334 if (false == useMonolithicProgram(test_case_index))
7335 {
7336 per_vertex = "out gl_PerVertex {\n"
7337 "vec4 gl_Position;\n"
7338 "};\n"
7339 "\n";
7340 }
7341
7342 Utils::replaceToken("PERVERTEX", position, per_vertex, source);
7343 }
7344
7345 Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source);
7346 Utils::replaceToken("VERIFICATION", position, verification.c_str(), source);
7347
7348 if (false == verification.empty())
7349 {
7350 Utils::replaceAllTokens("ELSE", " else ", source);
7351 }
7352 else
7353 {
7354 Utils::replaceAllTokens("ELSE", "", source);
7355 }
7356
7357 Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source);
7358
7359 /* Done */
7360 return source;
7361 }
7362
7363 /** Returns template of shader for given stage
7364 *
7365 * @param stage Shade stage
7366 *
7367 * @return Proper template
7368 **/
7369 const GLchar *TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
7370 {
7371
7372 static const GLchar *compute_shader_template =
7373 "VERSION\n"
7374 "#extension GL_ARB_enhanced_layouts : require\n"
7375 "\n"
7376 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7377 "\n"
7378 "writeonly uniform uimage2D uni_image;\n"
7379 "\n"
7380 "INTERFACE"
7381 "\n"
7382 "void main()\n"
7383 "{\n"
7384 " uint result = 1u;\n"
7385 "\n"
7386 " VERIFICATION"
7387 "\n"
7388 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
7389 "}\n"
7390 "\n";
7391
7392 static const GLchar *fragment_shader_template = "VERSION\n"
7393 "#extension GL_ARB_enhanced_layouts : require\n"
7394 "\n"
7395 "flat in uint gs_fs_result;\n"
7396 " out uint fs_out_result;\n"
7397 "\n"
7398 "INTERFACE"
7399 "\n"
7400 "void main()\n"
7401 "{\n"
7402 " uint result = 1u;\n"
7403 "\n"
7404 " if (1u != gs_fs_result)\n"
7405 " {\n"
7406 " result = gs_fs_result;\n"
7407 " }\n"
7408 "ELSEVERIFICATION"
7409 "\n"
7410 " fs_out_result = result;\n"
7411 " PASSTHROUGH\n"
7412 "}\n"
7413 "\n";
7414
7415 static const GLchar *geometry_shader_template =
7416 "VERSION\n"
7417 "#extension GL_ARB_enhanced_layouts : require\n"
7418 "\n"
7419 "layout(points) in;\n"
7420 "layout(triangle_strip, max_vertices = 4) out;\n"
7421 "\n"
7422 " in uint tes_gs_result[];\n"
7423 " flat out uint gs_fs_result;\n"
7424 "\n"
7425 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
7426 "INTERFACE"
7427 "\n"
7428 "void main()\n"
7429 "{\n"
7430 " uint result = 1u;\n"
7431 "\n"
7432 " if (1u != tes_gs_result[0])\n"
7433 " {\n"
7434 " result = tes_gs_result[0];\n"
7435 " }\n"
7436 "ELSEVERIFICATION"
7437 "\n"
7438 " gs_fs_result = result;\n"
7439 " PASSTHROUGH\n"
7440 " gl_Position = vec4(-1, -1, 0, 1);\n"
7441 " EmitVertex();\n"
7442 " gs_fs_result = result;\n"
7443 " PASSTHROUGH\n"
7444 " gl_Position = vec4(-1, 1, 0, 1);\n"
7445 " EmitVertex();\n"
7446 " gs_fs_result = result;\n"
7447 " PASSTHROUGH\n"
7448 " gl_Position = vec4(1, -1, 0, 1);\n"
7449 " EmitVertex();\n"
7450 " gs_fs_result = result;\n"
7451 " PASSTHROUGH\n"
7452 " gl_Position = vec4(1, 1, 0, 1);\n"
7453 " EmitVertex();\n"
7454 "}\n"
7455 "\n";
7456
7457 static const GLchar *tess_ctrl_shader_template = "VERSION\n"
7458 "#extension GL_ARB_enhanced_layouts : require\n"
7459 "\n"
7460 "layout(vertices = 1) out;\n"
7461 "\n"
7462 "in uint vs_tcs_result[];\n"
7463 "out uint tcs_tes_result[];\n"
7464 "\n"
7465 "INTERFACE"
7466 "\n"
7467 "void main()\n"
7468 "{\n"
7469 " uint result = 1u;\n"
7470 "\n"
7471 " if (1u != vs_tcs_result[gl_InvocationID])\n"
7472 " {\n"
7473 " result = vs_tcs_result[gl_InvocationID];\n"
7474 " }\n"
7475 "ELSEVERIFICATION"
7476 "\n"
7477 " tcs_tes_result[gl_InvocationID] = result;\n"
7478 "\n"
7479 " PASSTHROUGH\n"
7480 "\n"
7481 " gl_TessLevelOuter[0] = 1.0;\n"
7482 " gl_TessLevelOuter[1] = 1.0;\n"
7483 " gl_TessLevelOuter[2] = 1.0;\n"
7484 " gl_TessLevelOuter[3] = 1.0;\n"
7485 " gl_TessLevelInner[0] = 1.0;\n"
7486 " gl_TessLevelInner[1] = 1.0;\n"
7487 "}\n"
7488 "\n";
7489
7490 static const GLchar *tess_eval_shader_template = "VERSION\n"
7491 "#extension GL_ARB_enhanced_layouts : require\n"
7492 "\n"
7493 "layout(isolines, point_mode) in;\n"
7494 "\n"
7495 "in uint tcs_tes_result[];\n"
7496 "out uint tes_gs_result;\n"
7497 "\n"
7498 "INTERFACE"
7499 "\n"
7500 "void main()\n"
7501 "{\n"
7502 " uint result = 1u;\n"
7503 "\n"
7504 " if (1u != tcs_tes_result[0])\n"
7505 " {\n"
7506 " result = tcs_tes_result[0];\n"
7507 " }\n"
7508 "ELSEVERIFICATION"
7509 "\n"
7510 " tes_gs_result = result;\n"
7511 "\n"
7512 " PASSTHROUGH\n"
7513 "}\n"
7514 "\n";
7515
7516 static const GLchar *vertex_shader_template = "VERSION\n"
7517 "#extension GL_ARB_enhanced_layouts : require\n"
7518 "\n"
7519 "out uint vs_tcs_result;\n"
7520 "\n"
7521 "INTERFACE"
7522 "\n"
7523 "void main()\n"
7524 "{\n"
7525 " uint result = 1u;\n"
7526 "\n"
7527 " VERIFICATION\n"
7528 "\n"
7529 " vs_tcs_result = result;\n"
7530 "\n"
7531 " PASSTHROUGH\n"
7532 "}\n"
7533 "\n";
7534
7535 const GLchar *result = 0;
7536
7537 switch (stage)
7538 {
7539 case Utils::Shader::COMPUTE:
7540 result = compute_shader_template;
7541 break;
7542 case Utils::Shader::FRAGMENT:
7543 result = fragment_shader_template;
7544 break;
7545 case Utils::Shader::GEOMETRY:
7546 result = geometry_shader_template;
7547 break;
7548 case Utils::Shader::TESS_CTRL:
7549 result = tess_ctrl_shader_template;
7550 break;
7551 case Utils::Shader::TESS_EVAL:
7552 result = tess_eval_shader_template;
7553 break;
7554 case Utils::Shader::VERTEX:
7555 result = vertex_shader_template;
7556 break;
7557 default:
7558 TCU_FAIL("Invalid enum");
7559 }
7560
7561 return result;
7562 }
7563
7564 /** Runs test case
7565 *
7566 * @param test_case_index Id of test case
7567 *
7568 * @return true if test case pass, false otherwise
7569 **/
7570 bool TextureTestBase::testCase(GLuint test_case_index)
7571 {
7572 try
7573 {
7574 if (true == useMonolithicProgram(test_case_index))
7575 {
7576 return testMonolithic(test_case_index);
7577 }
7578 else
7579 {
7580 return testSeparable(test_case_index);
7581 }
7582 }
7583 catch (Utils::Shader::InvalidSourceException &exc)
7584 {
7585 exc.log(m_context);
7586 TCU_FAIL(exc.what());
7587 }
7588 catch (Utils::Program::BuildException &exc)
7589 {
7590 exc.log(m_context);
7591 TCU_FAIL(exc.what());
7592 }
7593 }
7594
7595 /** Runs "draw" test with monolithic program
7596 *
7597 * @param test_case_index Id of test case
7598 **/
7599 bool TextureTestBase::testMonolithic(GLuint test_case_index)
7600 {
7601 Utils::ProgramInterface program_interface;
7602 Utils::VaryingPassthrough varying_passthrough;
7603
7604 /* */
7605 const std::string &test_name = getTestCaseName(test_case_index);
7606
7607 /* */
7608 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7609
7610 bool result = true;
7611 /* Draw */
7612 if (true == isDrawRelevant(test_case_index))
7613 {
7614 Utils::Buffer buffer_attr(m_context);
7615 Utils::Buffer buffer_ssb_fs(m_context);
7616 Utils::Buffer buffer_ssb_gs(m_context);
7617 Utils::Buffer buffer_ssb_tcs(m_context);
7618 Utils::Buffer buffer_ssb_tes(m_context);
7619 Utils::Buffer buffer_ssb_vs(m_context);
7620 Utils::Buffer buffer_u_fs(m_context);
7621 Utils::Buffer buffer_u_gs(m_context);
7622 Utils::Buffer buffer_u_tcs(m_context);
7623 Utils::Buffer buffer_u_tes(m_context);
7624 Utils::Buffer buffer_u_vs(m_context);
7625 Utils::Framebuffer framebuffer(m_context);
7626 Utils::Program program(m_context);
7627 Utils::Texture texture_fb(m_context);
7628 Utils::VertexArray vao(m_context);
7629
7630 /* */
7631 const std::string &fragment_shader =
7632 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7633 const std::string &geometry_shader =
7634 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7635 const std::string &tess_ctrl_shader =
7636 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7637 const std::string &tess_eval_shader =
7638 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7639 const std::string &vertex_shader =
7640 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7641
7642 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
7643 vertex_shader, false /* is_separable */);
7644
7645 /* */
7646 prepareAttribLocation(program, program_interface);
7647 prepareFragmentDataLoc(program, program_interface);
7648
7649 /* */
7650 std::stringstream stream;
7651 if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream))
7652 {
7653 m_context.getTestContext().getLog()
7654 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7655 << ". Inspection of draw program interface failed:\n"
7656 << stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7657 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7658 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7659
7660 return false;
7661 }
7662
7663 /* */
7664 program.Use();
7665
7666 /* */
7667 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7668 vao.Init();
7669 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7670
7671 /* */
7672 prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs,
7673 buffer_u_tes, buffer_u_vs);
7674
7675 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs,
7676 buffer_ssb_tes, buffer_ssb_vs);
7677
7678 /* */
7679 prepareFramebuffer(framebuffer, texture_fb);
7680
7681 /* Draw */
7682 executeDrawCall(test_case_index);
7683
7684 #if USE_NSIGHT
7685 m_context.getRenderContext().postIterate();
7686 #endif
7687
7688 /* Check results */
7689 if (false == checkResults(test_case_index, texture_fb))
7690 {
7691 m_context.getTestContext().getLog()
7692 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7693 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7694 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7695 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7696
7697 result = false;
7698 }
7699 }
7700
7701 /* Compute */
7702 if (true == isComputeRelevant(test_case_index))
7703 {
7704 Utils::Buffer buffer_ssb_cs(m_context);
7705 Utils::Buffer buffer_u_cs(m_context);
7706 Utils::Program program(m_context);
7707 Utils::Texture texture_im(m_context);
7708 Utils::VertexArray vao(m_context);
7709
7710 /* */
7711 const std::string &compute_shader =
7712 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7713
7714 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7715 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7716
7717 /* */
7718 {
7719 std::stringstream stream;
7720
7721 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7722 {
7723 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7724 << ". Inspection of compute program interface failed:\n"
7725 << stream.str() << tcu::TestLog::EndMessage;
7726
7727 return false;
7728 }
7729 }
7730
7731 /* */
7732 program.Use();
7733
7734 /* */
7735 vao.Init();
7736 vao.Bind();
7737
7738 /* */
7739 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7740
7741 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs);
7742
7743 /* */
7744 GLint image_location = program.GetUniformLocation("uni_image");
7745 prepareImage(image_location, texture_im);
7746
7747 /* Draw */
7748 executeDispatchCall(test_case_index);
7749
7750 #if USE_NSIGHT
7751 m_context.getRenderContext().postIterate();
7752 #endif
7753
7754 /* Check results */
7755 if (false == checkResults(test_case_index, texture_im))
7756 {
7757 m_context.getTestContext().getLog()
7758 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Compute - invalid results."
7759 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(compute_shader);
7760
7761 result = false;
7762 }
7763 }
7764
7765 return result;
7766 }
7767
7768 /** Runs "draw" test with separable program
7769 *
7770 * @param test_case_index Id of test case
7771 **/
7772 bool TextureTestBase::testSeparable(GLuint test_case_index)
7773 {
7774 Utils::ProgramInterface program_interface;
7775 Utils::VaryingPassthrough varying_passthrough;
7776
7777 /* */
7778 const std::string &test_name = getTestCaseName(test_case_index);
7779
7780 /* */
7781 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7782
7783 bool result = true;
7784 /* Draw */
7785 if (true == isDrawRelevant(test_case_index))
7786 {
7787 Utils::Buffer buffer_attr(m_context);
7788 Utils::Buffer buffer_u_fs(m_context);
7789 Utils::Buffer buffer_u_gs(m_context);
7790 Utils::Buffer buffer_u_tcs(m_context);
7791 Utils::Buffer buffer_u_tes(m_context);
7792 Utils::Buffer buffer_u_vs(m_context);
7793 Utils::Framebuffer framebuffer(m_context);
7794 Utils::Pipeline pipeline(m_context);
7795 Utils::Program program_fs(m_context);
7796 Utils::Program program_gs(m_context);
7797 Utils::Program program_tcs(m_context);
7798 Utils::Program program_tes(m_context);
7799 Utils::Program program_vs(m_context);
7800 Utils::Texture texture_fb(m_context);
7801 Utils::VertexArray vao(m_context);
7802
7803 /* */
7804 const std::string &fs =
7805 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7806 const std::string &gs =
7807 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7808 const std::string &tcs =
7809 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7810 const std::string &tes =
7811 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7812 const std::string &vs =
7813 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7814
7815 program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7816 program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7817 program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7818 program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */);
7819 program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */);
7820
7821 /* */
7822 prepareAttribLocation(program_vs, program_interface);
7823 prepareFragmentDataLoc(program_vs, program_interface);
7824
7825 /* */
7826 std::stringstream stream;
7827 if ((false ==
7828 Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) ||
7829 (false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT,
7830 stream)) ||
7831 (false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY,
7832 stream)) ||
7833 (false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface,
7834 Utils::Shader::TESS_CTRL, stream)) ||
7835 (false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface,
7836 Utils::Shader::TESS_EVAL, stream)))
7837 {
7838 m_context.getTestContext().getLog()
7839 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7840 << ". Inspection of separable draw program interface failed:\n"
7841 << stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs)
7842 << tcu::TestLog::KernelSource(tcs) << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7843 << tcu::TestLog::KernelSource(fs);
7844
7845 return false;
7846 }
7847
7848 /* */
7849 pipeline.Init();
7850 pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT);
7851 pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT);
7852 pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT);
7853 pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT);
7854 pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT);
7855 pipeline.Bind();
7856
7857 /* */
7858
7859 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7860 vao.Init();
7861 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7862
7863 /* */
7864 prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes,
7865 program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs);
7866
7867 Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id);
7868
7869 /* */
7870 prepareFramebuffer(framebuffer, texture_fb);
7871
7872 /* Draw */
7873 executeDrawCall(test_case_index);
7874
7875 #if USE_NSIGHT
7876 m_context.getRenderContext().postIterate();
7877 #endif
7878
7879 /* Check results */
7880 if (false == checkResults(test_case_index, texture_fb))
7881 {
7882 m_context.getTestContext().getLog()
7883 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7884 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7885 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs);
7886
7887 result = false;
7888 }
7889 else
7890 {
7891 m_context.getTestContext().getLog()
7892 << tcu::TestLog::Message << "Success." << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs)
7893 << tcu::TestLog::KernelSource(tcs) << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7894 << tcu::TestLog::KernelSource(fs);
7895 }
7896 }
7897
7898 /* Compute */
7899 if (true == isComputeRelevant(test_case_index))
7900 {
7901 Utils::Buffer buffer_u_cs(m_context);
7902 Utils::Program program(m_context);
7903 Utils::Texture texture_im(m_context);
7904 Utils::VertexArray vao(m_context);
7905
7906 /* */
7907 const std::string &compute_shader =
7908 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7909
7910 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7911 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7912
7913 /* */
7914 {
7915 std::stringstream stream;
7916
7917 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7918 {
7919 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7920 << ". Inspection of compute program interface failed:\n"
7921 << stream.str() << tcu::TestLog::EndMessage;
7922
7923 return false;
7924 }
7925 }
7926
7927 /* */
7928 program.Use();
7929
7930 /* */
7931 vao.Init();
7932 vao.Bind();
7933
7934 /* */
7935 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7936
7937 /* */
7938 GLint image_location = program.GetUniformLocation("uni_image");
7939 prepareImage(image_location, texture_im);
7940
7941 /* Draw */
7942 executeDispatchCall(test_case_index);
7943
7944 #if USE_NSIGHT
7945 m_context.getRenderContext().postIterate();
7946 #endif
7947
7948 /* Check results */
7949 if (false == checkResults(test_case_index, texture_im))
7950 {
7951 m_context.getTestContext().getLog()
7952 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Compute - invalid results."
7953 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(compute_shader);
7954
7955 result = false;
7956 }
7957 }
7958
7959 return result;
7960 }
7961
7962 /** Basic implementation
7963 *
7964 * @param ignored
7965 *
7966 * @return false
7967 **/
7968 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */)
7969 {
7970 return false;
7971 }
7972
7973 /** Basic implementation
7974 *
7975 * @param ignored
7976 *
7977 * @return true
7978 **/
7979 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */)
7980 {
7981 return true;
7982 }
7983
7984 /** Constructor
7985 *
7986 * @param context Test framework context
7987 **/
7988 APIConstantValuesTest::APIConstantValuesTest(deqp::Context &context)
7989 : TestCase(context, "api_constant_values", "Test verifies values of api constants")
7990 {
7991 /* Nothing to be done here */
7992 }
7993
7994 /** Execute test
7995 *
7996 * @return tcu::TestNode::STOP otherwise
7997 **/
7998 tcu::TestNode::IterateResult APIConstantValuesTest::iterate()
7999 {
8000 static const GLuint expected_comp = 64;
8001 static const GLuint expected_xfb = 4;
8002 static const GLuint expected_sep = 4;
8003 GLint max_comp = 0;
8004 GLint max_xfb = 0;
8005 GLint max_sep = 0;
8006 bool test_result = true;
8007
8008 const Functions &gl = m_context.getRenderContext().getFunctions();
8009
8010 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
8011 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8012 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp);
8013 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8014 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep);
8015 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8016
8017 if (expected_xfb > (GLuint)max_xfb)
8018 {
8019 m_context.getTestContext().getLog()
8020 << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb
8021 << " Expected at least " << expected_xfb << tcu::TestLog::EndMessage;
8022
8023 test_result = false;
8024 }
8025
8026 if (expected_comp > (GLuint)max_comp)
8027 {
8028 m_context.getTestContext().getLog()
8029 << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp
8030 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
8031
8032 test_result = false;
8033 }
8034
8035 if (expected_sep > (GLuint)max_sep)
8036 {
8037 m_context.getTestContext().getLog()
8038 << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp
8039 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
8040
8041 test_result = false;
8042 }
8043
8044 /* Set result */
8045 if (true == test_result)
8046 {
8047 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
8048 }
8049 else
8050 {
8051 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8052 }
8053
8054 /* Done */
8055 return tcu::TestNode::STOP;
8056 }
8057
8058 /** Constructor
8059 *
8060 * @param context Test framework context
8061 **/
8062 APIErrorsTest::APIErrorsTest(deqp::Context &context)
8063 : TestCase(context, "api_errors", "Test verifies errors reeturned by api")
8064 {
8065 /* Nothing to be done here */
8066 }
8067
8068 /** Execute test
8069 *
8070 * @return tcu::TestNode::STOP otherwise
8071 **/
8072 tcu::TestNode::IterateResult APIErrorsTest::iterate()
8073 {
8074 GLint length = 0;
8075 GLchar name[64];
8076 GLint param = 0;
8077 Utils::Program program(m_context);
8078 bool test_result = true;
8079
8080 const Functions &gl = m_context.getRenderContext().getFunctions();
8081
8082 try
8083 {
8084 program.Init("" /* cs */,
8085 "#version 430 core\n"
8086 "#extension GL_ARB_enhanced_layouts : require\n"
8087 "\n"
8088 "in vec4 vs_fs;\n"
8089 "out vec4 fs_out;\n"
8090 "\n"
8091 "void main()\n"
8092 "{\n"
8093 " fs_out = vs_fs;\n"
8094 "}\n"
8095 "\n" /* fs */,
8096 "" /* gs */, "" /* tcs */, "" /* tes */,
8097 "#version 430 core\n"
8098 "#extension GL_ARB_enhanced_layouts : require\n"
8099 "\n"
8100 "in vec4 in_vs;\n"
8101 "layout (xfb_offset = 16) out vec4 vs_fs;\n"
8102 "\n"
8103 "void main()\n"
8104 "{\n"
8105 " vs_fs = in_vs;\n"
8106 "}\n"
8107 "\n" /* vs */,
8108 false /* separable */);
8109 }
8110 catch (Utils::Shader::InvalidSourceException &exc)
8111 {
8112 exc.log(m_context);
8113 TCU_FAIL(exc.what());
8114 }
8115 catch (Utils::Program::BuildException &exc)
8116 {
8117 TCU_FAIL(exc.what());
8118 }
8119
8120 /*
8121 * - GetProgramInterfaceiv should generate INVALID_OPERATION when
8122 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the
8123 * following:
8124 * * MAX_NAME_LENGTH,
8125 * * MAX_NUM_ACTIVE_VARIABLES;
8126 */
8127 gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, ¶m);
8128 checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)",
8129 test_result);
8130
8131 /*
8132 * - GetProgramResourceIndex should generate INVALID_ENUM when
8133 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
8134 */
8135 gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0");
8136 checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
8137 /*
8138 * - GetProgramResourceName should generate INVALID_ENUM when
8139 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
8140 */
8141 gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length,
8142 name);
8143 checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
8144
8145 /* Set result */
8146 if (true == test_result)
8147 {
8148 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
8149 }
8150 else
8151 {
8152 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8153 }
8154
8155 /* Done */
8156 return tcu::TestNode::STOP;
8157 }
8158
8159 /** Check if error is the expected one.
8160 *
8161 * @param expected_error Expected error
8162 * @param message Message to log in case of error
8163 * @param test_result Test result, set to false in case of invalid error
8164 **/
8165 void APIErrorsTest::checkError(GLenum expected_error, const GLchar *message, bool &test_result)
8166 {
8167 const Functions &gl = m_context.getRenderContext().getFunctions();
8168
8169 GLenum error = gl.getError();
8170
8171 if (error != expected_error)
8172 {
8173 m_context.getTestContext().getLog()
8174 << tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected "
8175 << glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage;
8176
8177 test_result = false;
8178 }
8179 }
8180
8181 /** Constructor
8182 *
8183 * @param context Test framework context
8184 **/
8185 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context &context)
8186 : NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified")
8187 {
8188 /* Nothing to be done here */
8189 }
8190
8191 /** Source for given test case and stage
8192 *
8193 * @param test_case_index Index of test case
8194 * @param stage Shader stage
8195 *
8196 * @return Shader source
8197 **/
8198 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
8199 {
8200 static const GLchar *cs = "#version 430 core\n"
8201 "#extension GL_ARB_enhanced_layouts : require\n"
8202 "\n"
8203 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8204 "\n"
8205 "writeonly uniform uimage2D uni_image;\n"
8206 "\n"
8207 "void main()\n"
8208 "{\n"
8209 " uint result = 1u;\n"
8210 " CONSTANT = 3;\n"
8211 "\n"
8212 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
8213 "}\n"
8214 "\n";
8215 static const GLchar *fs = "#version 430 core\n"
8216 "#extension GL_ARB_enhanced_layouts : require\n"
8217 "\n"
8218 "in vec4 gs_fs;\n"
8219 "out vec4 fs_out;\n"
8220 "\n"
8221 "void main()\n"
8222 "{\n"
8223 "ASSIGNMENT"
8224 " fs_out = gs_fs;\n"
8225 "}\n"
8226 "\n";
8227 static const GLchar *gs = "#version 430 core\n"
8228 "#extension GL_ARB_enhanced_layouts : require\n"
8229 "\n"
8230 "layout(points) in;\n"
8231 "layout(triangle_strip, max_vertices = 4) out;\n"
8232 "\n"
8233 "in vec4 tes_gs[];\n"
8234 "out vec4 gs_fs;\n"
8235 "\n"
8236 "void main()\n"
8237 "{\n"
8238 "ASSIGNMENT"
8239 " gs_fs = tes_gs[0];\n"
8240 " gl_Position = vec4(-1, -1, 0, 1);\n"
8241 " EmitVertex();\n"
8242 " gs_fs = tes_gs[0];\n"
8243 " gl_Position = vec4(-1, 1, 0, 1);\n"
8244 " EmitVertex();\n"
8245 " gs_fs = tes_gs[0];\n"
8246 " gl_Position = vec4(1, -1, 0, 1);\n"
8247 " EmitVertex();\n"
8248 " gs_fs = tes_gs[0];\n"
8249 " gl_Position = vec4(1, 1, 0, 1);\n"
8250 " EmitVertex();\n"
8251 "}\n"
8252 "\n";
8253 static const GLchar *tcs = "#version 430 core\n"
8254 "#extension GL_ARB_enhanced_layouts : require\n"
8255 "\n"
8256 "layout(vertices = 1) out;\n"
8257 "\n"
8258 "in vec4 vs_tcs[];\n"
8259 "out vec4 tcs_tes[];\n"
8260 "\n"
8261 "void main()\n"
8262 "{\n"
8263 "\n"
8264 "ASSIGNMENT"
8265 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
8266 "\n"
8267 " gl_TessLevelOuter[0] = 1.0;\n"
8268 " gl_TessLevelOuter[1] = 1.0;\n"
8269 " gl_TessLevelOuter[2] = 1.0;\n"
8270 " gl_TessLevelOuter[3] = 1.0;\n"
8271 " gl_TessLevelInner[0] = 1.0;\n"
8272 " gl_TessLevelInner[1] = 1.0;\n"
8273 "}\n"
8274 "\n";
8275 static const GLchar *tes = "#version 430 core\n"
8276 "#extension GL_ARB_enhanced_layouts : require\n"
8277 "\n"
8278 "layout(isolines, point_mode) in;\n"
8279 "\n"
8280 "in vec4 tcs_tes[];\n"
8281 "out vec4 tes_gs;\n"
8282 "\n"
8283 "void main()\n"
8284 "{\n"
8285 "ASSIGNMENT"
8286 " tes_gs = tcs_tes[0];\n"
8287 "}\n"
8288 "\n";
8289 static const GLchar *vs = "#version 430 core\n"
8290 "#extension GL_ARB_enhanced_layouts : require\n"
8291 "\n"
8292 "in vec4 in_vs;\n"
8293 "out vec4 vs_tcs;\n"
8294 "\n"
8295 "void main()\n"
8296 "{\n"
8297 "ASSIGNMENT"
8298 " vs_tcs = in_vs;\n"
8299 "}\n"
8300 "\n";
8301
8302 std::string source;
8303 testCase &test_case = m_test_cases[test_case_index];
8304
8305 if (Utils::Shader::COMPUTE == test_case.m_stage)
8306 {
8307 size_t position = 0;
8308
8309 source = cs;
8310
8311 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source);
8312 }
8313 else
8314 {
8315 std::string assignment = " CONSTANT = 3;\n";
8316 size_t position = 0;
8317
8318 switch (stage)
8319 {
8320 case Utils::Shader::FRAGMENT:
8321 source = fs;
8322 break;
8323 case Utils::Shader::GEOMETRY:
8324 source = gs;
8325 break;
8326 case Utils::Shader::TESS_CTRL:
8327 source = tcs;
8328 break;
8329 case Utils::Shader::TESS_EVAL:
8330 source = tes;
8331 break;
8332 case Utils::Shader::VERTEX:
8333 source = vs;
8334 break;
8335 default:
8336 TCU_FAIL("Invalid enum");
8337 }
8338
8339 if (test_case.m_stage == stage)
8340 {
8341 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment);
8342 }
8343 else
8344 {
8345 assignment = "";
8346 }
8347
8348 position = 0;
8349 Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source);
8350 }
8351
8352 return source;
8353 }
8354
8355 /** Get description of test case
8356 *
8357 * @param test_case_index Index of test case
8358 *
8359 * @return Constant name
8360 **/
8361 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index)
8362 {
8363 std::string result = getConstantName(m_test_cases[test_case_index].m_constant);
8364
8365 return result;
8366 }
8367
8368 /** Get number of test cases
8369 *
8370 * @return Number of test cases
8371 **/
8372 GLuint GLSLContantImmutablityTest::getTestCaseNumber()
8373 {
8374 return static_cast<GLuint>(m_test_cases.size());
8375 }
8376
8377 /** Selects if "compute" stage is relevant for test
8378 *
8379 * @param test_case_index Index of test case
8380 *
8381 * @return true when tested stage is compute
8382 **/
8383 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index)
8384 {
8385 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8386 }
8387
8388 /** Prepare all test cases
8389 *
8390 **/
8391 void GLSLContantImmutablityTest::testInit()
8392 {
8393 for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant)
8394 {
8395 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8396 {
8397 testCase test_case = {(CONSTANTS)constant, (Utils::Shader::STAGES)stage};
8398
8399 m_test_cases.push_back(test_case);
8400 }
8401 }
8402 }
8403
8404 /** Get name of glsl constant
8405 *
8406 * @param Constant id
8407 *
8408 * @return Name of constant used in GLSL
8409 **/
8410 const GLchar *GLSLContantImmutablityTest::getConstantName(CONSTANTS constant)
8411 {
8412 const GLchar *name = "";
8413
8414 switch (constant)
8415 {
8416 case GL_ARB_ENHANCED_LAYOUTS:
8417 name = "GL_ARB_enhanced_layouts";
8418 break;
8419 case GL_MAX_XFB:
8420 name = "gl_MaxTransformFeedbackBuffers";
8421 break;
8422 case GL_MAX_XFB_INT_COMP:
8423 name = "gl_MaxTransformFeedbackInterleavedComponents";
8424 break;
8425 default:
8426 TCU_FAIL("Invalid enum");
8427 }
8428
8429 return name;
8430 }
8431
8432 /** Constructor
8433 *
8434 * @param context Test framework context
8435 **/
8436 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context &context)
8437 : TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols")
8438 {
8439 }
8440
8441 /** Selects if "compute" stage is relevant for test
8442 *
8443 * @param ignored
8444 *
8445 * @return false
8446 **/
8447 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */)
8448 {
8449 return false;
8450 }
8451
8452 /** Prepare code snippet that will verify in and uniform variables
8453 *
8454 * @param ignored
8455 * @param ignored
8456 * @param stage Shader stage
8457 *
8458 * @return Code that verify variables
8459 **/
8460 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */,
8461 Utils::ProgramInterface & /* program_interface */,
8462 Utils::Shader::STAGES stage)
8463 {
8464 /* Get constants */
8465 const Functions &gl = m_context.getRenderContext().getFunctions();
8466
8467 GLint max_transform_feedback_buffers = 0;
8468 GLint max_transform_feedback_interleaved_components = 0;
8469
8470 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8471 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8472 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8473 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8474
8475 std::string verification;
8476
8477 if (Utils::Shader::VERTEX == stage)
8478 {
8479 verification = "if (1 != GL_ARB_enhanced_layouts)\n"
8480 " {\n"
8481 " result = 0;\n"
8482 " }\n"
8483 " else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n"
8484 " != gl_MaxTransformFeedbackBuffers)\n"
8485 " {\n"
8486 " result = 0;\n"
8487 " }\n"
8488 " else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n"
8489 " != gl_MaxTransformFeedbackInterleavedComponents)\n"
8490 " {\n"
8491 " result = 0;\n"
8492 " }\n";
8493
8494 size_t position = 0;
8495 GLchar buffer[16];
8496
8497 sprintf(buffer, "%d", max_transform_feedback_buffers);
8498 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification);
8499
8500 sprintf(buffer, "%d", max_transform_feedback_interleaved_components);
8501 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification);
8502 }
8503 else
8504 {
8505 verification = "";
8506 }
8507
8508 return verification;
8509 }
8510
8511 /** Constructor
8512 *
8513 * @param context Test framework context
8514 **/
8515 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context &context)
8516 : TextureTestBase(context, "glsl_constant_integral_expression",
8517 "Test verifies that symbols can be used as constant integral expressions")
8518 {
8519 }
8520
8521 /** Get interface of program
8522 *
8523 * @param ignored
8524 * @param program_interface Interface of program
8525 * @param ignored
8526 **/
8527 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */,
8528 Utils::ProgramInterface &program_interface,
8529 Utils::VaryingPassthrough & /* varying_passthrough */)
8530 {
8531 /* Get constants */
8532 const Functions &gl = m_context.getRenderContext().getFunctions();
8533
8534 GLint max_transform_feedback_buffers = 0;
8535 GLint max_transform_feedback_interleaved_components = 0;
8536
8537 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8538 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8539 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8540 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8541
8542 GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16);
8543 GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16);
8544
8545 m_gohan_length = max_transform_feedback_buffers / gohan_div;
8546 m_goten_length = max_transform_feedback_interleaved_components / goten_div;
8547
8548 /* Globals */
8549 std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n"
8550 "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n"
8551 "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n";
8552
8553 size_t position = 0;
8554 GLchar buffer[16];
8555
8556 sprintf(buffer, "%d", gohan_div);
8557 Utils::replaceToken("GOHAN_DIV", position, buffer, globals);
8558
8559 sprintf(buffer, "%d", goten_div);
8560 Utils::replaceToken("GOTEN_DIV", position, buffer, globals);
8561
8562 program_interface.m_vertex.m_globals = globals;
8563 program_interface.m_tess_ctrl.m_globals = globals;
8564 program_interface.m_tess_eval.m_globals = globals;
8565 program_interface.m_geometry.m_globals = globals;
8566 program_interface.m_fragment.m_globals = globals;
8567 program_interface.m_compute.m_globals = globals;
8568 }
8569
8570 /** Prepare code snippet that will verify in and uniform variables
8571 *
8572 * @param ignored
8573 * @param ignored
8574 * @param ignored
8575 *
8576 * @return Code that verify variables
8577 **/
8578 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(
8579 GLuint /* test_case_index */, Utils::ProgramInterface & /* program_interface */, Utils::Shader::STAGES /* stage */)
8580 {
8581 std::string verification = "{\n"
8582 " uint goku_sum = 0;\n"
8583 " uint gohan_sum = 0;\n"
8584 " uint goten_sum = 0;\n"
8585 "\n"
8586 " for (uint i = 0u; i < goku.length(); ++i)\n"
8587 " {\n"
8588 " goku_sum += goku[i];\n"
8589 " }\n"
8590 "\n"
8591 " for (uint i = 0u; i < gohan.length(); ++i)\n"
8592 " {\n"
8593 " gohan_sum += gohan[i];\n"
8594 " }\n"
8595 "\n"
8596 " for (uint i = 0u; i < goten.length(); ++i)\n"
8597 " {\n"
8598 " goten_sum += goten[i];\n"
8599 " }\n"
8600 "\n"
8601 " if ( (1u != goku_sum) &&\n"
8602 " (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n"
8603 " (EXPECTED_GOTEN_SUMu != goten_sum) )\n"
8604 " {\n"
8605 " result = 0u;\n"
8606 " }\n"
8607 " }\n";
8608
8609 size_t position = 0;
8610 GLchar buffer[16];
8611
8612 sprintf(buffer, "%d", m_gohan_length);
8613 Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification);
8614
8615 sprintf(buffer, "%d", m_goten_length);
8616 Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification);
8617
8618 return verification;
8619 }
8620
8621 /** Prepare unifroms
8622 *
8623 * @param ignored
8624 * @param ignored
8625 * @param program Program object
8626 * @param ignored
8627 **/
8628 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */,
8629 Utils::ProgramInterface & /* program_interface */,
8630 Utils::Program &program, Utils::Buffer & /* cs_buffer */)
8631 {
8632 static const GLuint uniform_data[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
8633
8634 const Functions &gl = m_context.getRenderContext().getFunctions();
8635
8636 GLint goku_location = program.GetUniformLocation("goku");
8637 GLint gohan_location = program.GetUniformLocation("gohan");
8638 GLint goten_location = program.GetUniformLocation("goten");
8639
8640 program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data);
8641 program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data);
8642 program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data);
8643 }
8644
8645 /** Prepare unifroms
8646 *
8647 * @param test_case_index Pass as param to first implemetnation
8648 * @param program_interface Pass as param to first implemetnation
8649 * @param program Pass as param to first implemetnation
8650 * @param ignored
8651 * @param ignored
8652 * @param ignored
8653 * @param ignored
8654 * @param vs_buffer Pass as param to first implemetnation
8655 **/
8656 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint test_case_index,
8657 Utils::ProgramInterface &program_interface,
8658 Utils::Program &program, Utils::Buffer & /* fs_buffer */,
8659 Utils::Buffer & /* gs_buffer */,
8660 Utils::Buffer & /* tcs_buffer */,
8661 Utils::Buffer & /* tes_buffer */, Utils::Buffer &vs_buffer)
8662 {
8663 /* Call first implementation */
8664 prepareUniforms(test_case_index, program_interface, program, vs_buffer);
8665 }
8666
8667 /** Constructor
8668 *
8669 * @param context Test framework context
8670 **/
8671 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context &context)
8672 : TextureTestBase(context, "uniform_block_member_offset_and_align",
8673 "Test verifies offsets and alignment of uniform buffer members")
8674 {
8675 }
8676
8677 /** Get interface of program
8678 *
8679 * @param test_case_index Test case index
8680 * @param program_interface Interface of program
8681 * @param varying_passthrough Collection of connections between in and out variables
8682 **/
8683 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
8684 Utils::ProgramInterface &program_interface,
8685 Utils::VaryingPassthrough &varying_passthrough)
8686 {
8687 std::string globals = "const int basic_size = BASIC_SIZE;\n"
8688 "const int type_align = TYPE_ALIGN;\n"
8689 "const int type_size = TYPE_SIZE;\n";
8690
8691 Utils::Type type = getType(test_case_index);
8692 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
8693 const GLuint base_align = type.GetBaseAlignment(false);
8694 const GLuint array_align = type.GetBaseAlignment(true);
8695 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
8696 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
8697
8698 /* Calculate offsets */
8699 const GLuint first_offset = 0;
8700 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
8701
8702 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
8703
8704 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
8705 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
8706 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8707 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8708 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8709 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
8710
8711 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8712
8713 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
8714 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
8715 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8716 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8717 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8718 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
8719
8720 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8721
8722 /* Prepare data */
8723 const std::vector<GLubyte> &first = type.GenerateData();
8724 const std::vector<GLubyte> &second = type.GenerateData();
8725 const std::vector<GLubyte> &third = type.GenerateData();
8726 const std::vector<GLubyte> &fourth = type.GenerateData();
8727
8728 m_data.resize(eigth_offset + base_stride);
8729 GLubyte *ptr = &m_data[0];
8730 memcpy(ptr + first_offset, &first[0], first.size());
8731 memcpy(ptr + second_offset, &second[0], second.size());
8732 memcpy(ptr + third_offset, &third[0], third.size());
8733 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
8734 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
8735 memcpy(ptr + sixth_offset, &third[0], third.size());
8736 memcpy(ptr + seventh_offset, &second[0], second.size());
8737 memcpy(ptr + eigth_offset, &first[0], first.size());
8738
8739 /* Prepare globals */
8740 size_t position = 0;
8741 GLchar buffer[16];
8742
8743 sprintf(buffer, "%d", basic_size);
8744 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
8745
8746 sprintf(buffer, "%d", type_align);
8747 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
8748
8749 sprintf(buffer, "%d", base_stride);
8750 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
8751
8752 /* Prepare Block */
8753 Utils::Interface *vs_uni_block = program_interface.Block("vs_uni_Block");
8754
8755 vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
8756 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8757 first_offset);
8758
8759 vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
8760 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
8761 0 /* n_array_elements */, base_stride, second_offset);
8762
8763 vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
8764 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8765 third_offset);
8766
8767 vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
8768 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8769 fourth_offset);
8770
8771 vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8772 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
8773
8774 vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8775 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
8776
8777 vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
8778 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8779 eigth_offset);
8780
8781 Utils::ShaderInterface &vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
8782
8783 /* Add globals */
8784 vs_si.m_globals = globals;
8785
8786 /* Add uniform BLOCK */
8787 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
8788 static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size());
8789
8790 /* */
8791 program_interface.CloneVertexInterface(varying_passthrough);
8792 }
8793
8794 /** Get type name
8795 *
8796 * @param test_case_index Index of test case
8797 *
8798 * @return Name of type test in test_case_index
8799 **/
8800 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
8801 {
8802 return getTypeName(test_case_index);
8803 }
8804
8805 /** Returns number of types to test
8806 *
8807 * @return Number of types, 34
8808 **/
8809 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber()
8810 {
8811 return getTypesNumber();
8812 }
8813
8814 /** Prepare code snippet that will verify in and uniform variables
8815 *
8816 * @param ignored
8817 * @param ignored
8818 * @param stage Shader stage
8819 *
8820 * @return Code that verify variables
8821 **/
8822 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet(
8823 GLuint /* test_case_index */, Utils::ProgramInterface & /* program_interface */, Utils::Shader::STAGES stage)
8824 {
8825 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
8826 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
8827 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
8828 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
8829 " {\n"
8830 " result = 0;\n"
8831 " }";
8832
8833 const GLchar *prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM);
8834
8835 Utils::replaceAllTokens("PREFIX", prefix, verification);
8836
8837 return verification;
8838 }
8839
8840 /** Constructor
8841 *
8842 * @param context Test framework context
8843 **/
8844 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context &context)
8845 : NegativeTestBase(
8846 context, "uniform_block_layout_qualifier_conflict",
8847 "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block")
8848 {
8849 /* Nothing to be done here */
8850 }
8851
8852 /** Source for given test case and stage
8853 *
8854 * @param test_case_index Index of test case
8855 * @param stage Shader stage
8856 *
8857 * @return Shader source
8858 **/
8859 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index,
8860 Utils::Shader::STAGES stage)
8861 {
8862 static const GLchar *cs = "#version 430 core\n"
8863 "#extension GL_ARB_enhanced_layouts : require\n"
8864 "\n"
8865 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8866 "\n"
8867 "LAYOUTuniform Block {\n"
8868 " layout(offset = 16) vec4 b;\n"
8869 " layout(align = 64) vec4 a;\n"
8870 "} uni_block;\n"
8871 "\n"
8872 "writeonly uniform image2D uni_image;\n"
8873 "\n"
8874 "void main()\n"
8875 "{\n"
8876 " vec4 result = uni_block.b + uni_block.a;\n"
8877 "\n"
8878 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8879 "}\n"
8880 "\n";
8881 static const GLchar *fs = "#version 430 core\n"
8882 "#extension GL_ARB_enhanced_layouts : require\n"
8883 "\n"
8884 "LAYOUTuniform Block {\n"
8885 " layout(offset = 16) vec4 b;\n"
8886 " layout(align = 64) vec4 a;\n"
8887 "} uni_block;\n"
8888 "\n"
8889 "in vec4 gs_fs;\n"
8890 "out vec4 fs_out;\n"
8891 "\n"
8892 "void main()\n"
8893 "{\n"
8894 " fs_out = gs_fs + uni_block.b + uni_block.a;\n"
8895 "}\n"
8896 "\n";
8897 static const GLchar *gs = "#version 430 core\n"
8898 "#extension GL_ARB_enhanced_layouts : require\n"
8899 "\n"
8900 "layout(points) in;\n"
8901 "layout(triangle_strip, max_vertices = 4) out;\n"
8902 "\n"
8903 "LAYOUTuniform Block {\n"
8904 " layout(offset = 16) vec4 b;\n"
8905 " layout(align = 64) vec4 a;\n"
8906 "} uni_block;\n"
8907 "\n"
8908 "in vec4 tes_gs[];\n"
8909 "out vec4 gs_fs;\n"
8910 "\n"
8911 "void main()\n"
8912 "{\n"
8913 " gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
8914 " gl_Position = vec4(-1, -1, 0, 1);\n"
8915 " EmitVertex();\n"
8916 " gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
8917 " gl_Position = vec4(-1, 1, 0, 1);\n"
8918 " EmitVertex();\n"
8919 " gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
8920 " gl_Position = vec4(1, -1, 0, 1);\n"
8921 " EmitVertex();\n"
8922 " gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
8923 " gl_Position = vec4(1, 1, 0, 1);\n"
8924 " EmitVertex();\n"
8925 "}\n"
8926 "\n";
8927 static const GLchar *tcs = "#version 430 core\n"
8928 "#extension GL_ARB_enhanced_layouts : require\n"
8929 "\n"
8930 "layout(vertices = 1) out;\n"
8931 "\n"
8932 "LAYOUTuniform Block {\n"
8933 " layout(offset = 16) vec4 b;\n"
8934 " layout(align = 64) vec4 a;\n"
8935 "} uni_block;\n"
8936 "\n"
8937 "in vec4 vs_tcs[];\n"
8938 "out vec4 tcs_tes[];\n"
8939 "\n"
8940 "void main()\n"
8941 "{\n"
8942 "\n"
8943 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.b + uni_block.a;\n"
8944 "\n"
8945 " gl_TessLevelOuter[0] = 1.0;\n"
8946 " gl_TessLevelOuter[1] = 1.0;\n"
8947 " gl_TessLevelOuter[2] = 1.0;\n"
8948 " gl_TessLevelOuter[3] = 1.0;\n"
8949 " gl_TessLevelInner[0] = 1.0;\n"
8950 " gl_TessLevelInner[1] = 1.0;\n"
8951 "}\n"
8952 "\n";
8953 static const GLchar *tes = "#version 430 core\n"
8954 "#extension GL_ARB_enhanced_layouts : require\n"
8955 "\n"
8956 "layout(isolines, point_mode) in;\n"
8957 "\n"
8958 "LAYOUTuniform Block {\n"
8959 " layout(offset = 16) vec4 b;\n"
8960 " layout(align = 64) vec4 a;\n"
8961 "} uni_block;\n"
8962 "\n"
8963 "in vec4 tcs_tes[];\n"
8964 "out vec4 tes_gs;\n"
8965 "\n"
8966 "void main()\n"
8967 "{\n"
8968 " tes_gs = tcs_tes[0] + uni_block.b + uni_block.a;\n"
8969 "}\n"
8970 "\n";
8971 static const GLchar *vs = "#version 430 core\n"
8972 "#extension GL_ARB_enhanced_layouts : require\n"
8973 "\n"
8974 "LAYOUTuniform Block {\n"
8975 " layout(offset = 16) vec4 b;\n"
8976 " layout(align = 64) vec4 a;\n"
8977 "} uni_block;\n"
8978 "\n"
8979 "in vec4 in_vs;\n"
8980 "out vec4 vs_tcs;\n"
8981 "\n"
8982 "void main()\n"
8983 "{\n"
8984 " vs_tcs = in_vs + uni_block.b + uni_block.a;\n"
8985 "}\n"
8986 "\n";
8987
8988 std::string layout = "";
8989 size_t position = 0;
8990 testCase &test_case = m_test_cases[test_case_index];
8991 const GLchar *qualifier = getQualifierName(test_case.m_qualifier);
8992 std::string source;
8993
8994 if (0 != qualifier[0])
8995 {
8996 size_t layout_position = 0;
8997
8998 layout = "layout (QUALIFIER) ";
8999
9000 Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout);
9001 }
9002
9003 switch (stage)
9004 {
9005 case Utils::Shader::COMPUTE:
9006 source = cs;
9007 break;
9008 case Utils::Shader::FRAGMENT:
9009 source = fs;
9010 break;
9011 case Utils::Shader::GEOMETRY:
9012 source = gs;
9013 break;
9014 case Utils::Shader::TESS_CTRL:
9015 source = tcs;
9016 break;
9017 case Utils::Shader::TESS_EVAL:
9018 source = tes;
9019 break;
9020 case Utils::Shader::VERTEX:
9021 source = vs;
9022 break;
9023 default:
9024 TCU_FAIL("Invalid enum");
9025 }
9026
9027 if (test_case.m_stage == stage)
9028 {
9029 Utils::replaceToken("LAYOUT", position, layout.c_str(), source);
9030 }
9031 else
9032 {
9033 Utils::replaceToken("LAYOUT", position, "layout (std140) ", source);
9034 }
9035
9036 return source;
9037 }
9038
9039 /** Get description of test case
9040 *
9041 * @param test_case_index Index of test case
9042 *
9043 * @return Qualifier name
9044 **/
9045 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
9046 {
9047 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
9048
9049 return result;
9050 }
9051
9052 /** Get number of test cases
9053 *
9054 * @return Number of test cases
9055 **/
9056 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber()
9057 {
9058 return static_cast<GLuint>(m_test_cases.size());
9059 }
9060
9061 /** Selects if "compute" stage is relevant for test
9062 *
9063 * @param test_case_index Index of test case
9064 *
9065 * @return true when tested stage is compute
9066 **/
9067 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
9068 {
9069 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9070 }
9071
9072 /** Selects if compilation failure is expected result
9073 *
9074 * @param test_case_index Index of test case
9075 *
9076 * @return false for STD140 cases, true otherwise
9077 **/
9078 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
9079 {
9080 return (STD140 != m_test_cases[test_case_index].m_qualifier);
9081 }
9082
9083 /** Prepare all test cases
9084 *
9085 **/
9086 void UniformBlockLayoutQualifierConflictTest::testInit()
9087 {
9088 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
9089 {
9090 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9091 {
9092 testCase test_case = {(QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage};
9093
9094 m_test_cases.push_back(test_case);
9095 }
9096 }
9097 }
9098
9099 /** Get name of glsl constant
9100 *
9101 * @param Constant id
9102 *
9103 * @return Name of constant used in GLSL
9104 **/
9105 const GLchar *UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
9106 {
9107 const GLchar *name = "";
9108
9109 switch (qualifier)
9110 {
9111 case DEFAULT:
9112 name = "";
9113 break;
9114 case STD140:
9115 name = "std140";
9116 break;
9117 case SHARED:
9118 name = "shared";
9119 break;
9120 case PACKED:
9121 name = "packed";
9122 break;
9123 default:
9124 TCU_FAIL("Invalid enum");
9125 }
9126
9127 return name;
9128 }
9129
9130 /** Constructor
9131 *
9132 * @param context Test framework context
9133 **/
9134 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context &context)
9135 : NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment",
9136 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
9137 {
9138 /* Nothing to be done here */
9139 }
9140
9141 /** Constructor
9142 *
9143 * @param context Test framework context
9144 * @param name Test name
9145 * @param description Test description
9146 **/
9147 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(
9148 deqp::Context &context, const glw::GLchar *name, const glw::GLchar *description)
9149 : NegativeTestBase(context, name, description)
9150 {
9151 /* Nothing to be done here */
9152 }
9153
9154 /** Source for given test case and stage
9155 *
9156 * @param test_case_index Index of test case
9157 * @param stage Shader stage
9158 *
9159 * @return Shader source
9160 **/
9161 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index,
9162 Utils::Shader::STAGES stage)
9163 {
9164 static const GLchar *cs = "#version 430 core\n"
9165 "#extension GL_ARB_enhanced_layouts : require\n"
9166 "\n"
9167 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9168 "\n"
9169 "layout (std140) uniform Block {\n"
9170 " layout (offset = OFFSET) TYPE member;\n"
9171 "} block;\n"
9172 "\n"
9173 "writeonly uniform image2D uni_image;\n"
9174 "\n"
9175 "void main()\n"
9176 "{\n"
9177 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9178 "\n"
9179 " if (TYPE(1) == block.member)\n"
9180 " {\n"
9181 " result = vec4(1, 1, 1, 1);\n"
9182 " }\n"
9183 "\n"
9184 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9185 "}\n"
9186 "\n";
9187 static const GLchar *fs = "#version 430 core\n"
9188 "#extension GL_ARB_enhanced_layouts : require\n"
9189 "\n"
9190 "in vec4 gs_fs;\n"
9191 "out vec4 fs_out;\n"
9192 "\n"
9193 "void main()\n"
9194 "{\n"
9195 " fs_out = gs_fs;\n"
9196 "}\n"
9197 "\n";
9198 static const GLchar *fs_tested = "#version 430 core\n"
9199 "#extension GL_ARB_enhanced_layouts : require\n"
9200 "\n"
9201 "layout (std140) uniform Block {\n"
9202 " layout (offset = OFFSET) TYPE member;\n"
9203 "} block;\n"
9204 "\n"
9205 "in vec4 gs_fs;\n"
9206 "out vec4 fs_out;\n"
9207 "\n"
9208 "void main()\n"
9209 "{\n"
9210 " if (TYPE(1) == block.member)\n"
9211 " {\n"
9212 " fs_out = vec4(1, 1, 1, 1);\n"
9213 " }\n"
9214 "\n"
9215 " fs_out += gs_fs;\n"
9216 "}\n"
9217 "\n";
9218 static const GLchar *gs = "#version 430 core\n"
9219 "#extension GL_ARB_enhanced_layouts : require\n"
9220 "\n"
9221 "layout(points) in;\n"
9222 "layout(triangle_strip, max_vertices = 4) out;\n"
9223 "\n"
9224 "in vec4 tes_gs[];\n"
9225 "out vec4 gs_fs;\n"
9226 "\n"
9227 "void main()\n"
9228 "{\n"
9229 " gs_fs = tes_gs[0];\n"
9230 " gl_Position = vec4(-1, -1, 0, 1);\n"
9231 " EmitVertex();\n"
9232 " gs_fs = tes_gs[0];\n"
9233 " gl_Position = vec4(-1, 1, 0, 1);\n"
9234 " EmitVertex();\n"
9235 " gs_fs = tes_gs[0];\n"
9236 " gl_Position = vec4(1, -1, 0, 1);\n"
9237 " EmitVertex();\n"
9238 " gs_fs = tes_gs[0];\n"
9239 " gl_Position = vec4(1, 1, 0, 1);\n"
9240 " EmitVertex();\n"
9241 "}\n"
9242 "\n";
9243 static const GLchar *gs_tested = "#version 430 core\n"
9244 "#extension GL_ARB_enhanced_layouts : require\n"
9245 "\n"
9246 "layout(points) in;\n"
9247 "layout(triangle_strip, max_vertices = 4) out;\n"
9248 "\n"
9249 "layout (std140) uniform Block {\n"
9250 " layout (offset = OFFSET) TYPE member;\n"
9251 "} block;\n"
9252 "\n"
9253 "in vec4 tes_gs[];\n"
9254 "out vec4 gs_fs;\n"
9255 "\n"
9256 "void main()\n"
9257 "{\n"
9258 " if (TYPE(1) == block.member)\n"
9259 " {\n"
9260 " gs_fs = vec4(1, 1, 1, 1);\n"
9261 " }\n"
9262 "\n"
9263 " gs_fs += tes_gs[0];\n"
9264 " gl_Position = vec4(-1, -1, 0, 1);\n"
9265 " EmitVertex();\n"
9266 " gs_fs += tes_gs[0];\n"
9267 " gl_Position = vec4(-1, 1, 0, 1);\n"
9268 " EmitVertex();\n"
9269 " gs_fs += tes_gs[0];\n"
9270 " gl_Position = vec4(1, -1, 0, 1);\n"
9271 " EmitVertex();\n"
9272 " gs_fs += tes_gs[0];\n"
9273 " gl_Position = vec4(1, 1, 0, 1);\n"
9274 " EmitVertex();\n"
9275 "}\n"
9276 "\n";
9277 static const GLchar *tcs = "#version 430 core\n"
9278 "#extension GL_ARB_enhanced_layouts : require\n"
9279 "\n"
9280 "layout(vertices = 1) out;\n"
9281 "\n"
9282 "in vec4 vs_tcs[];\n"
9283 "out vec4 tcs_tes[];\n"
9284 "\n"
9285 "void main()\n"
9286 "{\n"
9287 "\n"
9288 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9289 "\n"
9290 " gl_TessLevelOuter[0] = 1.0;\n"
9291 " gl_TessLevelOuter[1] = 1.0;\n"
9292 " gl_TessLevelOuter[2] = 1.0;\n"
9293 " gl_TessLevelOuter[3] = 1.0;\n"
9294 " gl_TessLevelInner[0] = 1.0;\n"
9295 " gl_TessLevelInner[1] = 1.0;\n"
9296 "}\n"
9297 "\n";
9298 static const GLchar *tcs_tested = "#version 430 core\n"
9299 "#extension GL_ARB_enhanced_layouts : require\n"
9300 "\n"
9301 "layout(vertices = 1) out;\n"
9302 "\n"
9303 "layout (std140) uniform Block {\n"
9304 " layout (offset = OFFSET) TYPE member;\n"
9305 "} block;\n"
9306 "\n"
9307 "in vec4 vs_tcs[];\n"
9308 "out vec4 tcs_tes[];\n"
9309 "\n"
9310 "void main()\n"
9311 "{\n"
9312 " if (TYPE(1) == block.member)\n"
9313 " {\n"
9314 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9315 " }\n"
9316 "\n"
9317 "\n"
9318 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9319 "\n"
9320 " gl_TessLevelOuter[0] = 1.0;\n"
9321 " gl_TessLevelOuter[1] = 1.0;\n"
9322 " gl_TessLevelOuter[2] = 1.0;\n"
9323 " gl_TessLevelOuter[3] = 1.0;\n"
9324 " gl_TessLevelInner[0] = 1.0;\n"
9325 " gl_TessLevelInner[1] = 1.0;\n"
9326 "}\n"
9327 "\n";
9328 static const GLchar *tes = "#version 430 core\n"
9329 "#extension GL_ARB_enhanced_layouts : require\n"
9330 "\n"
9331 "layout(isolines, point_mode) in;\n"
9332 "\n"
9333 "in vec4 tcs_tes[];\n"
9334 "out vec4 tes_gs;\n"
9335 "\n"
9336 "void main()\n"
9337 "{\n"
9338 " tes_gs = tcs_tes[0];\n"
9339 "}\n"
9340 "\n";
9341 static const GLchar *tes_tested = "#version 430 core\n"
9342 "#extension GL_ARB_enhanced_layouts : require\n"
9343 "\n"
9344 "layout(isolines, point_mode) in;\n"
9345 "\n"
9346 "layout (std140) uniform Block {\n"
9347 " layout (offset = OFFSET) TYPE member;\n"
9348 "} block;\n"
9349 "\n"
9350 "in vec4 tcs_tes[];\n"
9351 "out vec4 tes_gs;\n"
9352 "\n"
9353 "void main()\n"
9354 "{\n"
9355 " if (TYPE(1) == block.member)\n"
9356 " {\n"
9357 " tes_gs = vec4(1, 1, 1, 1);\n"
9358 " }\n"
9359 "\n"
9360 " tes_gs += tcs_tes[0];\n"
9361 "}\n"
9362 "\n";
9363 static const GLchar *vs = "#version 430 core\n"
9364 "#extension GL_ARB_enhanced_layouts : require\n"
9365 "\n"
9366 "in vec4 in_vs;\n"
9367 "out vec4 vs_tcs;\n"
9368 "\n"
9369 "void main()\n"
9370 "{\n"
9371 " vs_tcs = in_vs;\n"
9372 "}\n"
9373 "\n";
9374 static const GLchar *vs_tested = "#version 430 core\n"
9375 "#extension GL_ARB_enhanced_layouts : require\n"
9376 "\n"
9377 "layout (std140) uniform Block {\n"
9378 " layout (offset = OFFSET) TYPE member;\n"
9379 "} block;\n"
9380 "\n"
9381 "in vec4 in_vs;\n"
9382 "out vec4 vs_tcs;\n"
9383 "\n"
9384 "void main()\n"
9385 "{\n"
9386 " if (TYPE(1) == block.member)\n"
9387 " {\n"
9388 " vs_tcs = vec4(1, 1, 1, 1);\n"
9389 " }\n"
9390 "\n"
9391 " vs_tcs += in_vs;\n"
9392 "}\n"
9393 "\n";
9394
9395 std::string source;
9396 testCase &test_case = m_test_cases[test_case_index];
9397
9398 if (test_case.m_stage == stage)
9399 {
9400 GLchar buffer[16];
9401 const GLuint offset = test_case.m_offset;
9402 size_t position = 0;
9403 const Utils::Type &type = test_case.m_type;
9404 const GLchar *type_name = type.GetGLSLTypeName();
9405
9406 sprintf(buffer, "%d", offset);
9407
9408 switch (stage)
9409 {
9410 case Utils::Shader::COMPUTE:
9411 source = cs;
9412 break;
9413 case Utils::Shader::FRAGMENT:
9414 source = fs_tested;
9415 break;
9416 case Utils::Shader::GEOMETRY:
9417 source = gs_tested;
9418 break;
9419 case Utils::Shader::TESS_CTRL:
9420 source = tcs_tested;
9421 break;
9422 case Utils::Shader::TESS_EVAL:
9423 source = tes_tested;
9424 break;
9425 case Utils::Shader::VERTEX:
9426 source = vs_tested;
9427 break;
9428 default:
9429 TCU_FAIL("Invalid enum");
9430 }
9431
9432 Utils::replaceToken("OFFSET", position, buffer, source);
9433 Utils::replaceToken("TYPE", position, type_name, source);
9434 Utils::replaceToken("TYPE", position, type_name, source);
9435 }
9436 else
9437 {
9438 switch (stage)
9439 {
9440 case Utils::Shader::FRAGMENT:
9441 source = fs;
9442 break;
9443 case Utils::Shader::GEOMETRY:
9444 source = gs;
9445 break;
9446 case Utils::Shader::TESS_CTRL:
9447 source = tcs;
9448 break;
9449 case Utils::Shader::TESS_EVAL:
9450 source = tes;
9451 break;
9452 case Utils::Shader::VERTEX:
9453 source = vs;
9454 break;
9455 default:
9456 TCU_FAIL("Invalid enum");
9457 }
9458 }
9459
9460 return source;
9461 }
9462
9463 /** Get description of test case
9464 *
9465 * @param test_case_index Index of test case
9466 *
9467 * @return Type name and offset
9468 **/
9469 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
9470 {
9471 std::stringstream stream;
9472 testCase &test_case = m_test_cases[test_case_index];
9473
9474 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
9475
9476 return stream.str();
9477 }
9478
9479 /** Get number of test cases
9480 *
9481 * @return Number of test cases
9482 **/
9483 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber()
9484 {
9485 return static_cast<GLuint>(m_test_cases.size());
9486 }
9487
9488 /** Get the maximum size for an uniform block
9489 *
9490 * @return The maximum size in basic machine units of a uniform block.
9491 **/
9492 GLint UniformBlockMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
9493 {
9494 const Functions &gl = m_context.getRenderContext().getFunctions();
9495 GLint max_size = 0;
9496
9497 gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
9498 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
9499
9500 return max_size;
9501 }
9502
9503 /** Selects if "compute" stage is relevant for test
9504 *
9505 * @param test_case_index Index of test case
9506 *
9507 * @return true when tested stage is compute
9508 **/
9509 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index)
9510 {
9511 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9512 }
9513
9514 /** Selects if compilation failure is expected result
9515 *
9516 * @param test_case_index Index of test case
9517 *
9518 * @return should_fail field from testCase
9519 **/
9520 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index)
9521 {
9522 return m_test_cases[test_case_index].m_should_fail;
9523 }
9524
9525 /** Checks if stage is supported
9526 *
9527 * @param stage ignored
9528 *
9529 * @return true
9530 **/
9531 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9532 {
9533 return true;
9534 }
9535
9536 /** Prepare all test cases
9537 *
9538 **/
9539 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit()
9540 {
9541 const GLuint n_types = getTypesNumber();
9542 bool stage_support[Utils::Shader::STAGE_MAX];
9543
9544 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9545 {
9546 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9547 }
9548
9549 for (GLuint i = 0; i < n_types; ++i)
9550 {
9551 const Utils::Type &type = getType(i);
9552 const GLuint alignment = type.GetBaseAlignment(false);
9553 const GLuint type_size = type.GetSize(true);
9554 const GLuint sec_to_end = getMaxBlockSize() - 2 * type_size;
9555
9556 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9557 {
9558 if (false == stage_support[stage])
9559 {
9560 continue;
9561 }
9562
9563 for (GLuint offset = 0; offset <= type_size; ++offset)
9564 {
9565 const GLuint modulo = offset % alignment;
9566 const bool is_aligned = (0 == modulo) ? true : false;
9567 const bool should_fail = !is_aligned;
9568
9569 testCase test_case = {offset, should_fail, (Utils::Shader::STAGES)stage, type};
9570
9571 m_test_cases.push_back(test_case);
9572 }
9573
9574 for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset)
9575 {
9576 const GLuint modulo = offset % alignment;
9577 const bool is_aligned = (0 == modulo) ? true : false;
9578 const bool should_fail = !is_aligned;
9579
9580 testCase test_case = {offset, should_fail, (Utils::Shader::STAGES)stage, type};
9581
9582 m_test_cases.push_back(test_case);
9583 }
9584 }
9585 }
9586 }
9587
9588 /** Constructor
9589 *
9590 * @param context Test framework context
9591 **/
9592 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context &context)
9593 : NegativeTestBase(context, "uniform_block_member_overlapping_offsets",
9594 "Test verifies that overlapping offsets qualifiers cause compilation failure")
9595 {
9596 /* Nothing to be done here */
9597 }
9598
9599 /** Constructor
9600 *
9601 * @param context Test framework context
9602 * @param name Test name
9603 * @param description Test description
9604 **/
9605 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context &context,
9606 const glw::GLchar *name,
9607 const glw::GLchar *description)
9608 : NegativeTestBase(context, name, description)
9609 {
9610 /* Nothing to be done here */
9611 }
9612
9613 /** Source for given test case and stage
9614 *
9615 * @param test_case_index Index of test case
9616 * @param stage Shader stage
9617 *
9618 * @return Shader source
9619 **/
9620 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index,
9621 Utils::Shader::STAGES stage)
9622 {
9623 static const GLchar *cs = "#version 430 core\n"
9624 "#extension GL_ARB_enhanced_layouts : require\n"
9625 "\n"
9626 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9627 "\n"
9628 "layout (std140) uniform Block {\n"
9629 " layout (offset = B_OFFSET) B_TYPE b;\n"
9630 " layout (offset = A_OFFSET) A_TYPE a;\n"
9631 "} block;\n"
9632 "\n"
9633 "writeonly uniform image2D uni_image;\n"
9634 "\n"
9635 "void main()\n"
9636 "{\n"
9637 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9638 "\n"
9639 " if ((B_TYPE(1) == block.b) ||\n"
9640 " (A_TYPE(0) == block.a) )\n"
9641 " {\n"
9642 " result = vec4(1, 1, 1, 1);\n"
9643 " }\n"
9644 "\n"
9645 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9646 "}\n"
9647 "\n";
9648 static const GLchar *fs = "#version 430 core\n"
9649 "#extension GL_ARB_enhanced_layouts : require\n"
9650 "\n"
9651 "in vec4 gs_fs;\n"
9652 "out vec4 fs_out;\n"
9653 "\n"
9654 "void main()\n"
9655 "{\n"
9656 " fs_out = gs_fs;\n"
9657 "}\n"
9658 "\n";
9659 static const GLchar *fs_tested = "#version 430 core\n"
9660 "#extension GL_ARB_enhanced_layouts : require\n"
9661 "\n"
9662 "layout (std140) uniform Block {\n"
9663 " layout (offset = B_OFFSET) B_TYPE b;\n"
9664 " layout (offset = A_OFFSET) A_TYPE a;\n"
9665 "} block;\n"
9666 "\n"
9667 "in vec4 gs_fs;\n"
9668 "out vec4 fs_out;\n"
9669 "\n"
9670 "void main()\n"
9671 "{\n"
9672 " if ((B_TYPE(1) == block.b) ||\n"
9673 " (A_TYPE(0) == block.a) )\n"
9674 " {\n"
9675 " fs_out = vec4(1, 1, 1, 1);\n"
9676 " }\n"
9677 "\n"
9678 " fs_out += gs_fs;\n"
9679 "}\n"
9680 "\n";
9681 static const GLchar *gs = "#version 430 core\n"
9682 "#extension GL_ARB_enhanced_layouts : require\n"
9683 "\n"
9684 "layout(points) in;\n"
9685 "layout(triangle_strip, max_vertices = 4) out;\n"
9686 "\n"
9687 "in vec4 tes_gs[];\n"
9688 "out vec4 gs_fs;\n"
9689 "\n"
9690 "void main()\n"
9691 "{\n"
9692 " gs_fs = tes_gs[0];\n"
9693 " gl_Position = vec4(-1, -1, 0, 1);\n"
9694 " EmitVertex();\n"
9695 " gs_fs = tes_gs[0];\n"
9696 " gl_Position = vec4(-1, 1, 0, 1);\n"
9697 " EmitVertex();\n"
9698 " gs_fs = tes_gs[0];\n"
9699 " gl_Position = vec4(1, -1, 0, 1);\n"
9700 " EmitVertex();\n"
9701 " gs_fs = tes_gs[0];\n"
9702 " gl_Position = vec4(1, 1, 0, 1);\n"
9703 " EmitVertex();\n"
9704 "}\n"
9705 "\n";
9706 static const GLchar *gs_tested = "#version 430 core\n"
9707 "#extension GL_ARB_enhanced_layouts : require\n"
9708 "\n"
9709 "layout(points) in;\n"
9710 "layout(triangle_strip, max_vertices = 4) out;\n"
9711 "\n"
9712 "layout (std140) uniform Block {\n"
9713 " layout (offset = B_OFFSET) B_TYPE b;\n"
9714 " layout (offset = A_OFFSET) A_TYPE a;\n"
9715 "} block;\n"
9716 "\n"
9717 "in vec4 tes_gs[];\n"
9718 "out vec4 gs_fs;\n"
9719 "\n"
9720 "void main()\n"
9721 "{\n"
9722 " if ((B_TYPE(1) == block.b) ||\n"
9723 " (A_TYPE(0) == block.a) )\n"
9724 " {\n"
9725 " gs_fs = vec4(1, 1, 1, 1);\n"
9726 " }\n"
9727 "\n"
9728 " gs_fs += tes_gs[0];\n"
9729 " gl_Position = vec4(-1, -1, 0, 1);\n"
9730 " EmitVertex();\n"
9731 " gs_fs += tes_gs[0];\n"
9732 " gl_Position = vec4(-1, 1, 0, 1);\n"
9733 " EmitVertex();\n"
9734 " gs_fs += tes_gs[0];\n"
9735 " gl_Position = vec4(1, -1, 0, 1);\n"
9736 " EmitVertex();\n"
9737 " gs_fs += tes_gs[0];\n"
9738 " gl_Position = vec4(1, 1, 0, 1);\n"
9739 " EmitVertex();\n"
9740 "}\n"
9741 "\n";
9742 static const GLchar *tcs = "#version 430 core\n"
9743 "#extension GL_ARB_enhanced_layouts : require\n"
9744 "\n"
9745 "layout(vertices = 1) out;\n"
9746 "\n"
9747 "in vec4 vs_tcs[];\n"
9748 "out vec4 tcs_tes[];\n"
9749 "\n"
9750 "void main()\n"
9751 "{\n"
9752 "\n"
9753 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9754 "\n"
9755 " gl_TessLevelOuter[0] = 1.0;\n"
9756 " gl_TessLevelOuter[1] = 1.0;\n"
9757 " gl_TessLevelOuter[2] = 1.0;\n"
9758 " gl_TessLevelOuter[3] = 1.0;\n"
9759 " gl_TessLevelInner[0] = 1.0;\n"
9760 " gl_TessLevelInner[1] = 1.0;\n"
9761 "}\n"
9762 "\n";
9763 static const GLchar *tcs_tested = "#version 430 core\n"
9764 "#extension GL_ARB_enhanced_layouts : require\n"
9765 "\n"
9766 "layout(vertices = 1) out;\n"
9767 "\n"
9768 "layout (std140) uniform Block {\n"
9769 " layout (offset = B_OFFSET) B_TYPE b;\n"
9770 " layout (offset = A_OFFSET) A_TYPE a;\n"
9771 "} block;\n"
9772 "\n"
9773 "in vec4 vs_tcs[];\n"
9774 "out vec4 tcs_tes[];\n"
9775 "\n"
9776 "void main()\n"
9777 "{\n"
9778 " if ((B_TYPE(1) == block.b) ||\n"
9779 " (A_TYPE(0) == block.a) )\n"
9780 " {\n"
9781 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9782 " }\n"
9783 "\n"
9784 "\n"
9785 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9786 "\n"
9787 " gl_TessLevelOuter[0] = 1.0;\n"
9788 " gl_TessLevelOuter[1] = 1.0;\n"
9789 " gl_TessLevelOuter[2] = 1.0;\n"
9790 " gl_TessLevelOuter[3] = 1.0;\n"
9791 " gl_TessLevelInner[0] = 1.0;\n"
9792 " gl_TessLevelInner[1] = 1.0;\n"
9793 "}\n"
9794 "\n";
9795 static const GLchar *tes = "#version 430 core\n"
9796 "#extension GL_ARB_enhanced_layouts : require\n"
9797 "\n"
9798 "layout(isolines, point_mode) in;\n"
9799 "\n"
9800 "in vec4 tcs_tes[];\n"
9801 "out vec4 tes_gs;\n"
9802 "\n"
9803 "void main()\n"
9804 "{\n"
9805 " tes_gs = tcs_tes[0];\n"
9806 "}\n"
9807 "\n";
9808 static const GLchar *tes_tested = "#version 430 core\n"
9809 "#extension GL_ARB_enhanced_layouts : require\n"
9810 "\n"
9811 "layout(isolines, point_mode) in;\n"
9812 "\n"
9813 "layout (std140) uniform Block {\n"
9814 " layout (offset = B_OFFSET) B_TYPE b;\n"
9815 " layout (offset = A_OFFSET) A_TYPE a;\n"
9816 "} block;\n"
9817 "\n"
9818 "in vec4 tcs_tes[];\n"
9819 "out vec4 tes_gs;\n"
9820 "\n"
9821 "void main()\n"
9822 "{\n"
9823 " if ((B_TYPE(1) == block.b) ||\n"
9824 " (A_TYPE(0) == block.a) )\n"
9825 " {\n"
9826 " tes_gs = vec4(1, 1, 1, 1);\n"
9827 " }\n"
9828 "\n"
9829 " tes_gs += tcs_tes[0];\n"
9830 "}\n"
9831 "\n";
9832 static const GLchar *vs = "#version 430 core\n"
9833 "#extension GL_ARB_enhanced_layouts : require\n"
9834 "\n"
9835 "in vec4 in_vs;\n"
9836 "out vec4 vs_tcs;\n"
9837 "\n"
9838 "void main()\n"
9839 "{\n"
9840 " vs_tcs = in_vs;\n"
9841 "}\n"
9842 "\n";
9843 static const GLchar *vs_tested = "#version 430 core\n"
9844 "#extension GL_ARB_enhanced_layouts : require\n"
9845 "\n"
9846 "layout (std140) uniform Block {\n"
9847 " layout (offset = B_OFFSET) B_TYPE b;\n"
9848 " layout (offset = A_OFFSET) A_TYPE a;\n"
9849 "} block;\n"
9850 "\n"
9851 "in vec4 in_vs;\n"
9852 "out vec4 vs_tcs;\n"
9853 "\n"
9854 "void main()\n"
9855 "{\n"
9856 " if ((B_TYPE(1) == block.b) ||\n"
9857 " (A_TYPE(0) == block.a) )\n"
9858 " {\n"
9859 " vs_tcs = vec4(1, 1, 1, 1);\n"
9860 " }\n"
9861 "\n"
9862 " vs_tcs += in_vs;\n"
9863 "}\n"
9864 "\n";
9865
9866 std::string source;
9867 testCase &test_case = m_test_cases[test_case_index];
9868
9869 if (test_case.m_stage == stage)
9870 {
9871 GLchar buffer[16];
9872 const GLuint b_offset = test_case.m_b_offset;
9873 const Utils::Type &b_type = test_case.m_b_type;
9874 const GLchar *b_type_name = b_type.GetGLSLTypeName();
9875 const GLuint a_offset = test_case.m_a_offset;
9876 const Utils::Type &a_type = test_case.m_a_type;
9877 const GLchar *a_type_name = a_type.GetGLSLTypeName();
9878 size_t position = 0;
9879
9880 switch (stage)
9881 {
9882 case Utils::Shader::COMPUTE:
9883 source = cs;
9884 break;
9885 case Utils::Shader::FRAGMENT:
9886 source = fs_tested;
9887 break;
9888 case Utils::Shader::GEOMETRY:
9889 source = gs_tested;
9890 break;
9891 case Utils::Shader::TESS_CTRL:
9892 source = tcs_tested;
9893 break;
9894 case Utils::Shader::TESS_EVAL:
9895 source = tes_tested;
9896 break;
9897 case Utils::Shader::VERTEX:
9898 source = vs_tested;
9899 break;
9900 default:
9901 TCU_FAIL("Invalid enum");
9902 }
9903
9904 sprintf(buffer, "%d", b_offset);
9905 Utils::replaceToken("B_OFFSET", position, buffer, source);
9906 Utils::replaceToken("B_TYPE", position, b_type_name, source);
9907 sprintf(buffer, "%d", a_offset);
9908 Utils::replaceToken("A_OFFSET", position, buffer, source);
9909 Utils::replaceToken("A_TYPE", position, a_type_name, source);
9910 Utils::replaceToken("B_TYPE", position, b_type_name, source);
9911 Utils::replaceToken("A_TYPE", position, a_type_name, source);
9912 }
9913 else
9914 {
9915 switch (stage)
9916 {
9917 case Utils::Shader::FRAGMENT:
9918 source = fs;
9919 break;
9920 case Utils::Shader::GEOMETRY:
9921 source = gs;
9922 break;
9923 case Utils::Shader::TESS_CTRL:
9924 source = tcs;
9925 break;
9926 case Utils::Shader::TESS_EVAL:
9927 source = tes;
9928 break;
9929 case Utils::Shader::VERTEX:
9930 source = vs;
9931 break;
9932 default:
9933 TCU_FAIL("Invalid enum");
9934 }
9935 }
9936
9937 return source;
9938 }
9939
9940 /** Get description of test case
9941 *
9942 * @param test_case_index Index of test case
9943 *
9944 * @return Type name and offset
9945 **/
9946 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index)
9947 {
9948 std::stringstream stream;
9949 testCase &test_case = m_test_cases[test_case_index];
9950
9951 stream << "Type: " << test_case.m_b_type.GetGLSLTypeName() << ", offset: " << test_case.m_b_offset
9952 << ". Type: " << test_case.m_a_type.GetGLSLTypeName() << ", offset: " << test_case.m_a_offset;
9953
9954 return stream.str();
9955 }
9956
9957 /** Get number of test cases
9958 *
9959 * @return Number of test cases
9960 **/
9961 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber()
9962 {
9963 return static_cast<GLuint>(m_test_cases.size());
9964 }
9965
9966 /** Selects if "compute" stage is relevant for test
9967 *
9968 * @param test_case_index Index of test case
9969 *
9970 * @return true when tested stage is compute
9971 **/
9972 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index)
9973 {
9974 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9975 }
9976
9977 /** Checks if stage is supported
9978 *
9979 * @param stage ignored
9980 *
9981 * @return true
9982 **/
9983 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9984 {
9985 return true;
9986 }
9987
9988 /** Prepare all test cases
9989 *
9990 **/
9991 void UniformBlockMemberOverlappingOffsetsTest::testInit()
9992 {
9993 const GLuint n_types = getTypesNumber();
9994 bool stage_support[Utils::Shader::STAGE_MAX];
9995
9996 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9997 {
9998 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9999 }
10000
10001 for (GLuint i = 0; i < n_types; ++i)
10002 {
10003 const Utils::Type &b_type = getType(i);
10004 const GLuint b_size = b_type.GetActualAlignment(1 /* align */, false /* is_array*/);
10005
10006 for (GLuint j = 0; j < n_types; ++j)
10007 {
10008 const Utils::Type &a_type = getType(j);
10009 const GLuint a_align = a_type.GetBaseAlignment(false);
10010 const GLuint a_size = a_type.GetActualAlignment(1 /* align */, false /* is_array*/);
10011
10012 const GLuint b_offset = lcm(b_size, a_size);
10013 const GLuint a_after_start = b_offset + 1;
10014 const GLuint a_after_off = a_type.GetActualOffset(a_after_start, a_size);
10015 const GLuint a_before_start = b_offset - a_align;
10016 const GLuint a_before_off = a_type.GetActualOffset(a_before_start, a_size);
10017
10018 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10019 {
10020 if (false == stage_support[stage])
10021 {
10022 continue;
10023 }
10024
10025 if ((b_offset > a_before_off) && (b_offset < a_before_off + a_size))
10026 {
10027 testCase test_case = {b_offset, b_type, a_before_off, a_type, (Utils::Shader::STAGES)stage};
10028
10029 m_test_cases.push_back(test_case);
10030 }
10031
10032 if ((b_offset < a_after_off) && (b_offset + b_size > a_after_off))
10033 {
10034 testCase test_case = {b_offset, b_type, a_after_off, a_type, (Utils::Shader::STAGES)stage};
10035
10036 m_test_cases.push_back(test_case);
10037 }
10038
10039 /* b offset, should be fine for both types */
10040 testCase test_case = {b_offset, b_type, b_offset, a_type, (Utils::Shader::STAGES)stage};
10041
10042 m_test_cases.push_back(test_case);
10043 }
10044 }
10045 }
10046 }
10047
10048 /** Find greatest common divisor for a and b
10049 *
10050 * @param a A argument
10051 * @param b B argument
10052 *
10053 * @return Found gcd value
10054 **/
10055 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b)
10056 {
10057 if ((0 != a) && (0 == b))
10058 {
10059 return a;
10060 }
10061 else
10062 {
10063 GLuint greater = std::max(a, b);
10064 GLuint lesser = std::min(a, b);
10065
10066 return gcd(lesser, greater % lesser);
10067 }
10068 }
10069
10070 /** Find lowest common multiple for a and b
10071 *
10072 * @param a A argument
10073 * @param b B argument
10074 *
10075 * @return Found gcd value
10076 **/
10077 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b)
10078 {
10079 return (a * b) / gcd(a, b);
10080 }
10081
10082 /** Constructor
10083 *
10084 * @param context Test framework context
10085 **/
10086 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context &context)
10087 : NegativeTestBase(context, "uniform_block_member_align_non_power_of_2",
10088 "Test verifies that align qualifier requires value that is a power of 2")
10089 {
10090 /* Nothing to be done here */
10091 }
10092
10093 /** Constructor
10094 *
10095 * @param context Test framework context
10096 * @param name Test name
10097 * @param description Test description
10098 **/
10099 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context &context,
10100 const glw::GLchar *name,
10101 const glw::GLchar *description)
10102 : NegativeTestBase(context, name, description)
10103 {
10104 /* Nothing to be done here */
10105 }
10106
10107 /** Source for given test case and stage
10108 *
10109 * @param test_case_index Index of test case
10110 * @param stage Shader stage
10111 *
10112 * @return Shader source
10113 **/
10114 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10115 {
10116 static const GLchar *cs = "#version 430 core\n"
10117 "#extension GL_ARB_enhanced_layouts : require\n"
10118 "\n"
10119 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10120 "\n"
10121 "layout (std140) uniform Block {\n"
10122 " vec4 b;\n"
10123 " layout (align = ALIGN) TYPE a;\n"
10124 "} block;\n"
10125 "\n"
10126 "writeonly uniform image2D uni_image;\n"
10127 "\n"
10128 "void main()\n"
10129 "{\n"
10130 " vec4 result = vec4(1, 0, 0.5, 1);\n"
10131 "\n"
10132 " if (TYPE(0) == block.a)\n"
10133 " {\n"
10134 " result = vec4(1, 1, 1, 1) - block.b;\n"
10135 " }\n"
10136 "\n"
10137 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10138 "}\n"
10139 "\n";
10140 static const GLchar *fs = "#version 430 core\n"
10141 "#extension GL_ARB_enhanced_layouts : require\n"
10142 "\n"
10143 "in vec4 gs_fs;\n"
10144 "out vec4 fs_out;\n"
10145 "\n"
10146 "void main()\n"
10147 "{\n"
10148 " fs_out = gs_fs;\n"
10149 "}\n"
10150 "\n";
10151 static const GLchar *fs_tested = "#version 430 core\n"
10152 "#extension GL_ARB_enhanced_layouts : require\n"
10153 "\n"
10154 "layout (std140) uniform Block {\n"
10155 " vec4 b;\n"
10156 " layout (align = ALIGN) TYPE a;\n"
10157 "} block;\n"
10158 "\n"
10159 "in vec4 gs_fs;\n"
10160 "out vec4 fs_out;\n"
10161 "\n"
10162 "void main()\n"
10163 "{\n"
10164 " if (TYPE(0) == block.a)\n"
10165 " {\n"
10166 " fs_out = block.b;\n"
10167 " }\n"
10168 "\n"
10169 " fs_out += gs_fs;\n"
10170 "}\n"
10171 "\n";
10172 static const GLchar *gs = "#version 430 core\n"
10173 "#extension GL_ARB_enhanced_layouts : require\n"
10174 "\n"
10175 "layout(points) in;\n"
10176 "layout(triangle_strip, max_vertices = 4) out;\n"
10177 "\n"
10178 "in vec4 tes_gs[];\n"
10179 "out vec4 gs_fs;\n"
10180 "\n"
10181 "void main()\n"
10182 "{\n"
10183 " gs_fs = tes_gs[0];\n"
10184 " gl_Position = vec4(-1, -1, 0, 1);\n"
10185 " EmitVertex();\n"
10186 " gs_fs = tes_gs[0];\n"
10187 " gl_Position = vec4(-1, 1, 0, 1);\n"
10188 " EmitVertex();\n"
10189 " gs_fs = tes_gs[0];\n"
10190 " gl_Position = vec4(1, -1, 0, 1);\n"
10191 " EmitVertex();\n"
10192 " gs_fs = tes_gs[0];\n"
10193 " gl_Position = vec4(1, 1, 0, 1);\n"
10194 " EmitVertex();\n"
10195 "}\n"
10196 "\n";
10197 static const GLchar *gs_tested = "#version 430 core\n"
10198 "#extension GL_ARB_enhanced_layouts : require\n"
10199 "\n"
10200 "layout(points) in;\n"
10201 "layout(triangle_strip, max_vertices = 4) out;\n"
10202 "\n"
10203 "layout (std140) uniform Block {\n"
10204 " vec4 b;\n"
10205 " layout (align = ALIGN) TYPE a;\n"
10206 "} block;\n"
10207 "\n"
10208 "in vec4 tes_gs[];\n"
10209 "out vec4 gs_fs;\n"
10210 "\n"
10211 "void main()\n"
10212 "{\n"
10213 " if (TYPE(0) == block.a)\n"
10214 " {\n"
10215 " gs_fs = block.b;\n"
10216 " }\n"
10217 "\n"
10218 " gs_fs += tes_gs[0];\n"
10219 " gl_Position = vec4(-1, -1, 0, 1);\n"
10220 " EmitVertex();\n"
10221 " gs_fs += tes_gs[0];\n"
10222 " gl_Position = vec4(-1, 1, 0, 1);\n"
10223 " EmitVertex();\n"
10224 " gs_fs += tes_gs[0];\n"
10225 " gl_Position = vec4(1, -1, 0, 1);\n"
10226 " EmitVertex();\n"
10227 " gs_fs += tes_gs[0];\n"
10228 " gl_Position = vec4(1, 1, 0, 1);\n"
10229 " EmitVertex();\n"
10230 "}\n"
10231 "\n";
10232 static const GLchar *tcs = "#version 430 core\n"
10233 "#extension GL_ARB_enhanced_layouts : require\n"
10234 "\n"
10235 "layout(vertices = 1) out;\n"
10236 "\n"
10237 "in vec4 vs_tcs[];\n"
10238 "out vec4 tcs_tes[];\n"
10239 "\n"
10240 "void main()\n"
10241 "{\n"
10242 "\n"
10243 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
10244 "\n"
10245 " gl_TessLevelOuter[0] = 1.0;\n"
10246 " gl_TessLevelOuter[1] = 1.0;\n"
10247 " gl_TessLevelOuter[2] = 1.0;\n"
10248 " gl_TessLevelOuter[3] = 1.0;\n"
10249 " gl_TessLevelInner[0] = 1.0;\n"
10250 " gl_TessLevelInner[1] = 1.0;\n"
10251 "}\n"
10252 "\n";
10253 static const GLchar *tcs_tested = "#version 430 core\n"
10254 "#extension GL_ARB_enhanced_layouts : require\n"
10255 "\n"
10256 "layout(vertices = 1) out;\n"
10257 "\n"
10258 "layout (std140) uniform Block {\n"
10259 " vec4 b;\n"
10260 " layout (align = ALIGN) TYPE a;\n"
10261 "} block;\n"
10262 "\n"
10263 "in vec4 vs_tcs[];\n"
10264 "out vec4 tcs_tes[];\n"
10265 "\n"
10266 "void main()\n"
10267 "{\n"
10268 " if (TYPE(0) == block.a)\n"
10269 " {\n"
10270 " tcs_tes[gl_InvocationID] = block.b;\n"
10271 " }\n"
10272 "\n"
10273 "\n"
10274 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
10275 "\n"
10276 " gl_TessLevelOuter[0] = 1.0;\n"
10277 " gl_TessLevelOuter[1] = 1.0;\n"
10278 " gl_TessLevelOuter[2] = 1.0;\n"
10279 " gl_TessLevelOuter[3] = 1.0;\n"
10280 " gl_TessLevelInner[0] = 1.0;\n"
10281 " gl_TessLevelInner[1] = 1.0;\n"
10282 "}\n"
10283 "\n";
10284 static const GLchar *tes = "#version 430 core\n"
10285 "#extension GL_ARB_enhanced_layouts : require\n"
10286 "\n"
10287 "layout(isolines, point_mode) in;\n"
10288 "\n"
10289 "in vec4 tcs_tes[];\n"
10290 "out vec4 tes_gs;\n"
10291 "\n"
10292 "void main()\n"
10293 "{\n"
10294 " tes_gs = tcs_tes[0];\n"
10295 "}\n"
10296 "\n";
10297 static const GLchar *tes_tested = "#version 430 core\n"
10298 "#extension GL_ARB_enhanced_layouts : require\n"
10299 "\n"
10300 "layout(isolines, point_mode) in;\n"
10301 "\n"
10302 "layout (std140) uniform Block {\n"
10303 " vec4 b;\n"
10304 " layout (align = ALIGN) TYPE a;\n"
10305 "} block;\n"
10306 "\n"
10307 "in vec4 tcs_tes[];\n"
10308 "out vec4 tes_gs;\n"
10309 "\n"
10310 "void main()\n"
10311 "{\n"
10312 " if (TYPE(0) == block.a)\n"
10313 " {\n"
10314 " tes_gs = block.b;\n"
10315 " }\n"
10316 "\n"
10317 " tes_gs += tcs_tes[0];\n"
10318 "}\n"
10319 "\n";
10320 static const GLchar *vs = "#version 430 core\n"
10321 "#extension GL_ARB_enhanced_layouts : require\n"
10322 "\n"
10323 "in vec4 in_vs;\n"
10324 "out vec4 vs_tcs;\n"
10325 "\n"
10326 "void main()\n"
10327 "{\n"
10328 " vs_tcs = in_vs;\n"
10329 "}\n"
10330 "\n";
10331 static const GLchar *vs_tested = "#version 430 core\n"
10332 "#extension GL_ARB_enhanced_layouts : require\n"
10333 "\n"
10334 "layout (std140) uniform Block {\n"
10335 " vec4 b;\n"
10336 " layout (align = ALIGN) TYPE a;\n"
10337 "} block;\n"
10338 "\n"
10339 "in vec4 in_vs;\n"
10340 "out vec4 vs_tcs;\n"
10341 "\n"
10342 "void main()\n"
10343 "{\n"
10344 " if (TYPE(0) == block.a)\n"
10345 " {\n"
10346 " vs_tcs = block.b;\n"
10347 " }\n"
10348 "\n"
10349 " vs_tcs += in_vs;\n"
10350 "}\n"
10351 "\n";
10352
10353 std::string source;
10354 testCase &test_case = m_test_cases[test_case_index];
10355
10356 if (test_case.m_stage == stage)
10357 {
10358 GLchar buffer[16];
10359 const GLuint alignment = test_case.m_alignment;
10360 const Utils::Type &type = test_case.m_type;
10361 const GLchar *type_name = type.GetGLSLTypeName();
10362 size_t position = 0;
10363
10364 switch (stage)
10365 {
10366 case Utils::Shader::COMPUTE:
10367 source = cs;
10368 break;
10369 case Utils::Shader::FRAGMENT:
10370 source = fs_tested;
10371 break;
10372 case Utils::Shader::GEOMETRY:
10373 source = gs_tested;
10374 break;
10375 case Utils::Shader::TESS_CTRL:
10376 source = tcs_tested;
10377 break;
10378 case Utils::Shader::TESS_EVAL:
10379 source = tes_tested;
10380 break;
10381 case Utils::Shader::VERTEX:
10382 source = vs_tested;
10383 break;
10384 default:
10385 TCU_FAIL("Invalid enum");
10386 }
10387
10388 sprintf(buffer, "%d", alignment);
10389 Utils::replaceToken("ALIGN", position, buffer, source);
10390 Utils::replaceToken("TYPE", position, type_name, source);
10391 Utils::replaceToken("TYPE", position, type_name, source);
10392 }
10393 else
10394 {
10395 switch (stage)
10396 {
10397 case Utils::Shader::FRAGMENT:
10398 source = fs;
10399 break;
10400 case Utils::Shader::GEOMETRY:
10401 source = gs;
10402 break;
10403 case Utils::Shader::TESS_CTRL:
10404 source = tcs;
10405 break;
10406 case Utils::Shader::TESS_EVAL:
10407 source = tes;
10408 break;
10409 case Utils::Shader::VERTEX:
10410 source = vs;
10411 break;
10412 default:
10413 TCU_FAIL("Invalid enum");
10414 }
10415 }
10416
10417 return source;
10418 }
10419
10420 /** Get description of test case
10421 *
10422 * @param test_case_index Index of test case
10423 *
10424 * @return Type name and offset
10425 **/
10426 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index)
10427 {
10428 std::stringstream stream;
10429 testCase &test_case = m_test_cases[test_case_index];
10430
10431 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment;
10432
10433 return stream.str();
10434 }
10435
10436 /** Get number of test cases
10437 *
10438 * @return Number of test cases
10439 **/
10440 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber()
10441 {
10442 return static_cast<GLuint>(m_test_cases.size());
10443 }
10444
10445 /** Selects if "compute" stage is relevant for test
10446 *
10447 * @param test_case_index Index of test case
10448 *
10449 * @return true when tested stage is compute
10450 **/
10451 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index)
10452 {
10453 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10454 }
10455
10456 /** Checks if stage is supported
10457 *
10458 * @param ignored
10459 *
10460 * @return true
10461 **/
10462 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */)
10463 {
10464 return true;
10465 }
10466
10467 /** Selects if compilation failure is expected result
10468 *
10469 * @param test_case_index Index of test case
10470 *
10471 * @return should_fail field from testCase
10472 **/
10473 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index)
10474 {
10475 return m_test_cases[test_case_index].m_should_fail;
10476 }
10477
10478 /** Prepare all test cases
10479 *
10480 **/
10481 void UniformBlockMemberAlignNonPowerOf2Test::testInit()
10482 {
10483 static const GLuint dmat4_size = 128;
10484 const GLuint n_types = getTypesNumber();
10485 bool stage_support[Utils::Shader::STAGE_MAX];
10486
10487 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10488 {
10489 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10490 }
10491
10492 for (GLuint j = 0; j < n_types; ++j)
10493 {
10494 const Utils::Type &type = getType(j);
10495
10496 for (GLuint align = 0; align <= dmat4_size; ++align)
10497 {
10498
10499 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST
10500
10501 const bool should_fail = (0 == align) ? false : !isPowerOf2(align);
10502
10503 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10504
10505 const bool should_fail = !isPowerOf2(align);
10506
10507 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10508
10509 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10510 {
10511 if (false == stage_support[stage])
10512 {
10513 continue;
10514 }
10515
10516 testCase test_case = {align, type, should_fail, (Utils::Shader::STAGES)stage};
10517
10518 m_test_cases.push_back(test_case);
10519 }
10520 }
10521 }
10522 }
10523
10524 /** Check if value is power of 2
10525 *
10526 * @param val Tested value
10527 *
10528 * @return true if val is power of 2, false otherwise
10529 **/
10530 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val)
10531 {
10532 if (0 == val)
10533 {
10534 return false;
10535 }
10536
10537 return (0 == (val & (val - 1)));
10538 }
10539
10540 /** Constructor
10541 *
10542 * @param context Test framework context
10543 **/
10544 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context &context)
10545 : TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer")
10546 {
10547 }
10548
10549 /** Get interface of program
10550 *
10551 * @param ignored
10552 * @param program_interface Interface of program
10553 * @param varying_passthrough Collection of connections between in and out variables
10554 **/
10555 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */,
10556 Utils::ProgramInterface &program_interface,
10557 Utils::VaryingPassthrough &varying_passthrough)
10558 {
10559 static const Utils::Type vec4 = Utils::Type::vec4;
10560
10561 #if WRKARD_UNIFORMBLOCKALIGNMENT
10562
10563 static const GLuint block_align = 16;
10564
10565 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10566
10567 static const GLuint block_align = 64;
10568
10569 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10570
10571 static const GLuint vec4_stride = 16;
10572 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
10573
10574 /*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual
10575 alignment of a member will be the greater of the specified alignment and the base aligment for the member type
10576 */
10577 const GLuint first_offset = 0; /* vec4 at 0 */
10578 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
10579 const GLuint third_offset =
10580 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
10581 const GLuint fourth_offset =
10582 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
10583 const GLuint fifth_offset =
10584 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */
10585 const GLuint sixth_offset =
10586 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
10587
10588 Utils::Interface *structure = program_interface.Structure("Data");
10589
10590 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10591 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
10592
10593 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
10594 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
10595 Utils::Type::vec4.GetSize() /* offset */);
10596
10597 /* Prepare Block */
10598 Utils::Interface *vs_uni_block = program_interface.Block("vs_uni_Block");
10599
10600 vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10601 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
10602
10603 vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10604 0 /* n_array_elements */, data_stride, second_offset);
10605
10606 vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10607 2 /* n_array_elements */, data_stride, third_offset);
10608
10609 vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
10610 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
10611
10612 vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4,
10613 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
10614
10615 vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10616 0 /* n_array_elements */, data_stride, sixth_offset);
10617
10618 const GLuint stride = calculateStride(*vs_uni_block);
10619 m_data.resize(stride);
10620 generateData(*vs_uni_block, 0, m_data);
10621
10622 Utils::ShaderInterface &vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10623
10624 /* Add uniform BLOCK */
10625 #if WRKARD_UNIFORMBLOCKALIGNMENT
10626 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
10627 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10628 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10629 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0,
10630 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10631 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10632
10633 program_interface.CloneVertexInterface(varying_passthrough);
10634 }
10635
10636 /** Constructor
10637 *
10638 * @param context Test framework context
10639 **/
10640 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context &context)
10641 : TextureTestBase(context, "ssb_member_offset_and_align",
10642 "Test verifies offsets and alignment of storage buffer members")
10643 {
10644 }
10645
10646 /** Get interface of program
10647 *
10648 * @param test_case_index Test case index
10649 * @param program_interface Interface of program
10650 * @param varying_passthrough Collection of connections between in and out variables
10651 **/
10652 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
10653 Utils::ProgramInterface &program_interface,
10654 Utils::VaryingPassthrough &varying_passthrough)
10655 {
10656 std::string globals = "const int basic_size = BASIC_SIZE;\n"
10657 "const int type_align = TYPE_ALIGN;\n"
10658 "const int type_size = TYPE_SIZE;\n";
10659
10660 Utils::Type type = getType(test_case_index);
10661 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
10662 const GLuint base_align = type.GetBaseAlignment(false);
10663 const GLuint array_align = type.GetBaseAlignment(true);
10664 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
10665 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
10666
10667 /* Calculate offsets */
10668 const GLuint first_offset = 0;
10669 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
10670
10671 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
10672
10673 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
10674 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
10675 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10676 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10677 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10678 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
10679
10680 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10681
10682 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
10683 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
10684 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10685 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10686 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10687 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
10688
10689 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10690
10691 /* Prepare data */
10692 const std::vector<GLubyte> &first = type.GenerateData();
10693 const std::vector<GLubyte> &second = type.GenerateData();
10694 const std::vector<GLubyte> &third = type.GenerateData();
10695 const std::vector<GLubyte> &fourth = type.GenerateData();
10696
10697 m_data.resize(eigth_offset + base_stride);
10698 GLubyte *ptr = &m_data[0];
10699 memcpy(ptr + first_offset, &first[0], first.size());
10700 memcpy(ptr + second_offset, &second[0], second.size());
10701 memcpy(ptr + third_offset, &third[0], third.size());
10702 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
10703 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
10704 memcpy(ptr + sixth_offset, &third[0], third.size());
10705 memcpy(ptr + seventh_offset, &second[0], second.size());
10706 memcpy(ptr + eigth_offset, &first[0], first.size());
10707
10708 /* Prepare globals */
10709 size_t position = 0;
10710 GLchar buffer[16];
10711
10712 sprintf(buffer, "%d", basic_size);
10713 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
10714
10715 sprintf(buffer, "%d", type_align);
10716 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
10717
10718 sprintf(buffer, "%d", base_stride);
10719 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
10720
10721 /* Prepare Block */
10722 Utils::Interface *vs_buf_block = program_interface.Block("vs_buf_Block");
10723
10724 vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
10725 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10726 first_offset);
10727
10728 vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
10729 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
10730 0 /* n_array_elements */, base_stride, second_offset);
10731
10732 vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
10733 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10734 third_offset);
10735
10736 vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
10737 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10738 fourth_offset);
10739
10740 vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10741 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
10742
10743 vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10744 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
10745
10746 vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
10747 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10748 eigth_offset);
10749
10750 Utils::ShaderInterface &vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10751
10752 /* Add globals */
10753 vs_si.m_globals = globals;
10754
10755 /* Add uniform BLOCK */
10756 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0,
10757 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10758
10759 /* */
10760 program_interface.CloneVertexInterface(varying_passthrough);
10761 }
10762
10763 /** Get type name
10764 *
10765 * @param test_case_index Index of test case
10766 *
10767 * @return Name of type test in test_case_index
10768 **/
10769 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
10770 {
10771 return getTypeName(test_case_index);
10772 }
10773
10774 /** Returns number of types to test
10775 *
10776 * @return Number of types, 34
10777 **/
10778 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber()
10779 {
10780 return getTypesNumber();
10781 }
10782
10783 /** Prepare code snippet that will verify in and uniform variables
10784 *
10785 * @param ignored
10786 * @param ignored
10787 * @param stage Shader stage
10788 *
10789 * @return Code that verify variables
10790 **/
10791 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */,
10792 Utils::ProgramInterface & /* program_interface */,
10793 Utils::Shader::STAGES stage)
10794 {
10795 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
10796 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
10797 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
10798 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
10799 " {\n"
10800 " result = 0;\n"
10801 " }";
10802
10803 const GLchar *prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB);
10804
10805 Utils::replaceAllTokens("PREFIX", prefix, verification);
10806
10807 return verification;
10808 }
10809
10810 /** Selects if "draw" stages are relevant for test
10811 *
10812 * @param ignored
10813 *
10814 * @return true if all stages support shader storage buffers, false otherwise
10815 **/
10816 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */)
10817 {
10818 const Functions &gl = m_context.getRenderContext().getFunctions();
10819 GLint gs_supported_buffers = 0;
10820 GLint tcs_supported_buffers = 0;
10821 GLint tes_supported_buffers = 0;
10822 GLint vs_supported_buffers = 0;
10823
10824 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
10825 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
10826 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
10827 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
10828
10829 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10830
10831 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
10832 (1 <= vs_supported_buffers));
10833 }
10834
10835 /** Constructor
10836 *
10837 * @param context Test framework context
10838 **/
10839 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context &context)
10840 : NegativeTestBase(context, "ssb_layout_qualifier_conflict",
10841 "Test verifies that std140 or std430 is required when "
10842 "offset and/or align qualifiers are used with storage "
10843 "block")
10844 {
10845 /* Nothing to be done here */
10846 }
10847
10848 /** Source for given test case and stage
10849 *
10850 * @param test_case_index Index of test case
10851 * @param stage Shader stage
10852 *
10853 * @return Shader source
10854 **/
10855 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10856 {
10857 static const GLchar *cs = "#version 430 core\n"
10858 "#extension GL_ARB_enhanced_layouts : require\n"
10859 "\n"
10860 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10861 "\n"
10862 "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n"
10863 " layout(offset = 16) vec4 b;\n"
10864 " layout(align = 64) vec4 a;\n"
10865 "} uni_block;\n"
10866 "\n"
10867 "writeonly uniform image2D uni_image;\n"
10868 "\n"
10869 "void main()\n"
10870 "{\n"
10871 " vec4 result = uni_block.b + uni_block.a;\n"
10872 "\n"
10873 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10874 "}\n"
10875 "\n";
10876 static const GLchar *fs = "#version 430 core\n"
10877 "#extension GL_ARB_enhanced_layouts : require\n"
10878 "\n"
10879 "layout (QUALIFIERbinding = BINDING) buffer Block {\n"
10880 " layout(offset = 16) vec4 b;\n"
10881 " layout(align = 64) vec4 a;\n"
10882 "} uni_block;\n"
10883 "\n"
10884 "in vec4 gs_fs;\n"
10885 "out vec4 fs_out;\n"
10886 "\n"
10887 "void main()\n"
10888 "{\n"
10889 " fs_out = gs_fs + uni_block.b + uni_block.a;\n"
10890 "}\n"
10891 "\n";
10892 static const GLchar *gs = "#version 430 core\n"
10893 "#extension GL_ARB_enhanced_layouts : require\n"
10894 "\n"
10895 "layout(points) in;\n"
10896 "layout(triangle_strip, max_vertices = 4) out;\n"
10897 "\n"
10898 "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n"
10899 " layout(offset = 16) vec4 b;\n"
10900 " layout(align = 64) vec4 a;\n"
10901 "} uni_block;\n"
10902 "\n"
10903 "in vec4 tes_gs[];\n"
10904 "out vec4 gs_fs;\n"
10905 "\n"
10906 "void main()\n"
10907 "{\n"
10908 " gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
10909 " gl_Position = vec4(-1, -1, 0, 1);\n"
10910 " EmitVertex();\n"
10911 " gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
10912 " gl_Position = vec4(-1, 1, 0, 1);\n"
10913 " EmitVertex();\n"
10914 " gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
10915 " gl_Position = vec4(1, -1, 0, 1);\n"
10916 " EmitVertex();\n"
10917 " gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
10918 " gl_Position = vec4(1, 1, 0, 1);\n"
10919 " EmitVertex();\n"
10920 "}\n"
10921 "\n";
10922 static const GLchar *tcs = "#version 430 core\n"
10923 "#extension GL_ARB_enhanced_layouts : require\n"
10924 "\n"
10925 "layout(vertices = 1) out;\n"
10926 "\n"
10927 "layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n"
10928 " layout(offset = 16) vec4 b;\n"
10929 " layout(align = 64) vec4 a;\n"
10930 "} uni_block;\n"
10931 "\n"
10932 "in vec4 vs_tcs[];\n"
10933 "out vec4 tcs_tes[];\n"
10934 "\n"
10935 "void main()\n"
10936 "{\n"
10937 "\n"
10938 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.b + uni_block.a;\n"
10939 "\n"
10940 " gl_TessLevelOuter[0] = 1.0;\n"
10941 " gl_TessLevelOuter[1] = 1.0;\n"
10942 " gl_TessLevelOuter[2] = 1.0;\n"
10943 " gl_TessLevelOuter[3] = 1.0;\n"
10944 " gl_TessLevelInner[0] = 1.0;\n"
10945 " gl_TessLevelInner[1] = 1.0;\n"
10946 "}\n"
10947 "\n";
10948 static const GLchar *tes = "#version 430 core\n"
10949 "#extension GL_ARB_enhanced_layouts : require\n"
10950 "\n"
10951 "layout(isolines, point_mode) in;\n"
10952 "\n"
10953 "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n"
10954 " layout(offset = 16) vec4 b;\n"
10955 " layout(align = 64) vec4 a;\n"
10956 "} uni_block;\n"
10957 "\n"
10958 "in vec4 tcs_tes[];\n"
10959 "out vec4 tes_gs;\n"
10960 "\n"
10961 "void main()\n"
10962 "{\n"
10963 " tes_gs = tcs_tes[0] + uni_block.b + uni_block.a;\n"
10964 "}\n"
10965 "\n";
10966 static const GLchar *vs = "#version 430 core\n"
10967 "#extension GL_ARB_enhanced_layouts : require\n"
10968 "\n"
10969 "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n"
10970 " layout(offset = 16) vec4 b;\n"
10971 " layout(align = 64) vec4 a;\n"
10972 "} uni_block;\n"
10973 "\n"
10974 "in vec4 in_vs;\n"
10975 "out vec4 vs_tcs;\n"
10976 "\n"
10977 "void main()\n"
10978 "{\n"
10979 " vs_tcs = in_vs + uni_block.b + uni_block.a;\n"
10980 "}\n"
10981 "\n";
10982
10983 GLchar buffer[16];
10984 size_t position = 0;
10985 std::string source;
10986 testCase &test_case = m_test_cases[test_case_index];
10987 std::string qualifier = getQualifierName(test_case.m_qualifier);
10988
10989 if (false == qualifier.empty())
10990 {
10991 qualifier.append(", ");
10992 }
10993
10994 sprintf(buffer, "%d", stage);
10995
10996 switch (stage)
10997 {
10998 case Utils::Shader::COMPUTE:
10999 source = cs;
11000 break;
11001 case Utils::Shader::FRAGMENT:
11002 source = fs;
11003 break;
11004 case Utils::Shader::GEOMETRY:
11005 source = gs;
11006 break;
11007 case Utils::Shader::TESS_CTRL:
11008 source = tcs;
11009 break;
11010 case Utils::Shader::TESS_EVAL:
11011 source = tes;
11012 break;
11013 case Utils::Shader::VERTEX:
11014 source = vs;
11015 break;
11016 default:
11017 TCU_FAIL("Invalid enum");
11018 }
11019
11020 if (test_case.m_stage == stage)
11021 {
11022 Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source);
11023 }
11024 else
11025 {
11026 Utils::replaceToken("QUALIFIER", position, "std140, ", source);
11027 }
11028
11029 Utils::replaceToken("BINDING", position, buffer, source);
11030
11031 return source;
11032 }
11033
11034 /** Get description of test case
11035 *
11036 * @param test_case_index Index of test case
11037 *
11038 * @return Qualifier name
11039 **/
11040 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
11041 {
11042 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
11043
11044 return result;
11045 }
11046
11047 /** Get number of test cases
11048 *
11049 * @return Number of test cases
11050 **/
11051 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber()
11052 {
11053 return static_cast<GLuint>(m_test_cases.size());
11054 }
11055
11056 /** Selects if "compute" stage is relevant for test
11057 *
11058 * @param test_case_index Index of test case
11059 *
11060 * @return true when tested stage is compute
11061 **/
11062 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
11063 {
11064 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
11065 }
11066
11067 /** Selects if compilation failure is expected result
11068 *
11069 * @param test_case_index Index of test case
11070 *
11071 * @return false for STD140 and STD430 cases, true otherwise
11072 **/
11073 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
11074 {
11075 const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier;
11076
11077 return !((STD140 == qualifier) || (STD430 == qualifier));
11078 }
11079
11080 /** Checks if stage is supported
11081 *
11082 * @param stage Shader stage
11083 *
11084 * @return true if supported, false otherwise
11085 **/
11086 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage)
11087 {
11088 const Functions &gl = m_context.getRenderContext().getFunctions();
11089 GLint max_supported_buffers = 0;
11090 GLenum pname = 0;
11091
11092 switch (stage)
11093 {
11094 case Utils::Shader::COMPUTE:
11095 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11096 break;
11097 case Utils::Shader::FRAGMENT:
11098 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11099 break;
11100 case Utils::Shader::GEOMETRY:
11101 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11102 break;
11103 case Utils::Shader::TESS_CTRL:
11104 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11105 break;
11106 case Utils::Shader::TESS_EVAL:
11107 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11108 break;
11109 case Utils::Shader::VERTEX:
11110 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11111 break;
11112 default:
11113 TCU_FAIL("Invalid enum");
11114 }
11115
11116 gl.getIntegerv(pname, &max_supported_buffers);
11117 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11118
11119 return 1 <= max_supported_buffers;
11120 }
11121
11122 /** Prepare all test cases
11123 *
11124 **/
11125 void SSBLayoutQualifierConflictTest::testInit()
11126 {
11127 bool stage_support[Utils::Shader::STAGE_MAX];
11128
11129 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
11130 {
11131 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
11132 }
11133
11134 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
11135 {
11136 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
11137 {
11138 if (false == stage_support[stage])
11139 {
11140 continue;
11141 }
11142
11143 testCase test_case = {(QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage};
11144
11145 m_test_cases.push_back(test_case);
11146 }
11147 }
11148 }
11149
11150 /** Get name of glsl constant
11151 *
11152 * @param Constant id
11153 *
11154 * @return Name of constant used in GLSL
11155 **/
11156 const GLchar *SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
11157 {
11158 const GLchar *name = "";
11159
11160 switch (qualifier)
11161 {
11162 case DEFAULT:
11163 name = "";
11164 break;
11165 case STD140:
11166 name = "std140";
11167 break;
11168 case STD430:
11169 name = "std430";
11170 break;
11171 case SHARED:
11172 name = "shared";
11173 break;
11174 case PACKED:
11175 name = "packed";
11176 break;
11177 default:
11178 TCU_FAIL("Invalid enum");
11179 }
11180
11181 return name;
11182 }
11183
11184 /** Constructor
11185 *
11186 * @param context Test framework context
11187 **/
11188 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context &context)
11189 : UniformBlockMemberInvalidOffsetAlignmentTest(
11190 context, "ssb_member_invalid_offset_alignment",
11191 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
11192 {
11193 /* Nothing to be done here */
11194 }
11195
11196 /** Get the maximum size for a shader storage block
11197 *
11198 * @return The maximum size in basic machine units of a shader storage block.
11199 **/
11200 GLint SSBMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
11201 {
11202 const Functions &gl = m_context.getRenderContext().getFunctions();
11203 GLint max_size = 0;
11204
11205 gl.getIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_size);
11206 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11207
11208 return max_size;
11209 }
11210
11211 /** Source for given test case and stage
11212 *
11213 * @param test_case_index Index of test case
11214 * @param stage Shader stage
11215 *
11216 * @return Shader source
11217 **/
11218 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11219 {
11220 static const GLchar *cs = "#version 430 core\n"
11221 "#extension GL_ARB_enhanced_layouts : require\n"
11222 "\n"
11223 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11224 "\n"
11225 "layout (std140) buffer Block {\n"
11226 " layout (offset = OFFSET) TYPE member;\n"
11227 "} block;\n"
11228 "\n"
11229 "writeonly uniform image2D uni_image;\n"
11230 "\n"
11231 "void main()\n"
11232 "{\n"
11233 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11234 "\n"
11235 " if (TYPE(1) == block.member)\n"
11236 " {\n"
11237 " result = vec4(1, 1, 1, 1);\n"
11238 " }\n"
11239 "\n"
11240 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11241 "}\n"
11242 "\n";
11243 static const GLchar *fs = "#version 430 core\n"
11244 "#extension GL_ARB_enhanced_layouts : require\n"
11245 "\n"
11246 "in vec4 gs_fs;\n"
11247 "out vec4 fs_out;\n"
11248 "\n"
11249 "void main()\n"
11250 "{\n"
11251 " fs_out = gs_fs;\n"
11252 "}\n"
11253 "\n";
11254 static const GLchar *fs_tested = "#version 430 core\n"
11255 "#extension GL_ARB_enhanced_layouts : require\n"
11256 "\n"
11257 "layout (std140) buffer Block {\n"
11258 " layout (offset = OFFSET) TYPE member;\n"
11259 "} block;\n"
11260 "\n"
11261 "in vec4 gs_fs;\n"
11262 "out vec4 fs_out;\n"
11263 "\n"
11264 "void main()\n"
11265 "{\n"
11266 " if (TYPE(1) == block.member)\n"
11267 " {\n"
11268 " fs_out = vec4(1, 1, 1, 1);\n"
11269 " }\n"
11270 "\n"
11271 " fs_out += gs_fs;\n"
11272 "}\n"
11273 "\n";
11274 static const GLchar *gs = "#version 430 core\n"
11275 "#extension GL_ARB_enhanced_layouts : require\n"
11276 "\n"
11277 "layout(points) in;\n"
11278 "layout(triangle_strip, max_vertices = 4) out;\n"
11279 "\n"
11280 "in vec4 tes_gs[];\n"
11281 "out vec4 gs_fs;\n"
11282 "\n"
11283 "void main()\n"
11284 "{\n"
11285 " gs_fs = tes_gs[0];\n"
11286 " gl_Position = vec4(-1, -1, 0, 1);\n"
11287 " EmitVertex();\n"
11288 " gs_fs = tes_gs[0];\n"
11289 " gl_Position = vec4(-1, 1, 0, 1);\n"
11290 " EmitVertex();\n"
11291 " gs_fs = tes_gs[0];\n"
11292 " gl_Position = vec4(1, -1, 0, 1);\n"
11293 " EmitVertex();\n"
11294 " gs_fs = tes_gs[0];\n"
11295 " gl_Position = vec4(1, 1, 0, 1);\n"
11296 " EmitVertex();\n"
11297 "}\n"
11298 "\n";
11299 static const GLchar *gs_tested = "#version 430 core\n"
11300 "#extension GL_ARB_enhanced_layouts : require\n"
11301 "\n"
11302 "layout(points) in;\n"
11303 "layout(triangle_strip, max_vertices = 4) out;\n"
11304 "\n"
11305 "layout (std140) buffer Block {\n"
11306 " layout (offset = OFFSET) TYPE member;\n"
11307 "} block;\n"
11308 "\n"
11309 "in vec4 tes_gs[];\n"
11310 "out vec4 gs_fs;\n"
11311 "\n"
11312 "void main()\n"
11313 "{\n"
11314 " if (TYPE(1) == block.member)\n"
11315 " {\n"
11316 " gs_fs = vec4(1, 1, 1, 1);\n"
11317 " }\n"
11318 "\n"
11319 " gs_fs += tes_gs[0];\n"
11320 " gl_Position = vec4(-1, -1, 0, 1);\n"
11321 " EmitVertex();\n"
11322 " gs_fs += tes_gs[0];\n"
11323 " gl_Position = vec4(-1, 1, 0, 1);\n"
11324 " EmitVertex();\n"
11325 " gs_fs += tes_gs[0];\n"
11326 " gl_Position = vec4(1, -1, 0, 1);\n"
11327 " EmitVertex();\n"
11328 " gs_fs += tes_gs[0];\n"
11329 " gl_Position = vec4(1, 1, 0, 1);\n"
11330 " EmitVertex();\n"
11331 "}\n"
11332 "\n";
11333 static const GLchar *tcs = "#version 430 core\n"
11334 "#extension GL_ARB_enhanced_layouts : require\n"
11335 "\n"
11336 "layout(vertices = 1) out;\n"
11337 "\n"
11338 "in vec4 vs_tcs[];\n"
11339 "out vec4 tcs_tes[];\n"
11340 "\n"
11341 "void main()\n"
11342 "{\n"
11343 "\n"
11344 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11345 "\n"
11346 " gl_TessLevelOuter[0] = 1.0;\n"
11347 " gl_TessLevelOuter[1] = 1.0;\n"
11348 " gl_TessLevelOuter[2] = 1.0;\n"
11349 " gl_TessLevelOuter[3] = 1.0;\n"
11350 " gl_TessLevelInner[0] = 1.0;\n"
11351 " gl_TessLevelInner[1] = 1.0;\n"
11352 "}\n"
11353 "\n";
11354 static const GLchar *tcs_tested = "#version 430 core\n"
11355 "#extension GL_ARB_enhanced_layouts : require\n"
11356 "\n"
11357 "layout(vertices = 1) out;\n"
11358 "\n"
11359 "layout (std140) buffer Block {\n"
11360 " layout (offset = OFFSET) TYPE member;\n"
11361 "} block;\n"
11362 "\n"
11363 "in vec4 vs_tcs[];\n"
11364 "out vec4 tcs_tes[];\n"
11365 "\n"
11366 "void main()\n"
11367 "{\n"
11368 " if (TYPE(1) == block.member)\n"
11369 " {\n"
11370 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11371 " }\n"
11372 "\n"
11373 "\n"
11374 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11375 "\n"
11376 " gl_TessLevelOuter[0] = 1.0;\n"
11377 " gl_TessLevelOuter[1] = 1.0;\n"
11378 " gl_TessLevelOuter[2] = 1.0;\n"
11379 " gl_TessLevelOuter[3] = 1.0;\n"
11380 " gl_TessLevelInner[0] = 1.0;\n"
11381 " gl_TessLevelInner[1] = 1.0;\n"
11382 "}\n"
11383 "\n";
11384 static const GLchar *tes = "#version 430 core\n"
11385 "#extension GL_ARB_enhanced_layouts : require\n"
11386 "\n"
11387 "layout(isolines, point_mode) in;\n"
11388 "\n"
11389 "in vec4 tcs_tes[];\n"
11390 "out vec4 tes_gs;\n"
11391 "\n"
11392 "void main()\n"
11393 "{\n"
11394 " tes_gs = tcs_tes[0];\n"
11395 "}\n"
11396 "\n";
11397 static const GLchar *tes_tested = "#version 430 core\n"
11398 "#extension GL_ARB_enhanced_layouts : require\n"
11399 "\n"
11400 "layout(isolines, point_mode) in;\n"
11401 "\n"
11402 "layout (std140) buffer Block {\n"
11403 " layout (offset = OFFSET) TYPE member;\n"
11404 "} block;\n"
11405 "\n"
11406 "in vec4 tcs_tes[];\n"
11407 "out vec4 tes_gs;\n"
11408 "\n"
11409 "void main()\n"
11410 "{\n"
11411 " if (TYPE(1) == block.member)\n"
11412 " {\n"
11413 " tes_gs = vec4(1, 1, 1, 1);\n"
11414 " }\n"
11415 "\n"
11416 " tes_gs += tcs_tes[0];\n"
11417 "}\n"
11418 "\n";
11419 static const GLchar *vs = "#version 430 core\n"
11420 "#extension GL_ARB_enhanced_layouts : require\n"
11421 "\n"
11422 "in vec4 in_vs;\n"
11423 "out vec4 vs_tcs;\n"
11424 "\n"
11425 "void main()\n"
11426 "{\n"
11427 " vs_tcs = in_vs;\n"
11428 "}\n"
11429 "\n";
11430 static const GLchar *vs_tested = "#version 430 core\n"
11431 "#extension GL_ARB_enhanced_layouts : require\n"
11432 "\n"
11433 "layout (std140) buffer Block {\n"
11434 " layout (offset = OFFSET) TYPE member;\n"
11435 "} block;\n"
11436 "\n"
11437 "in vec4 in_vs;\n"
11438 "out vec4 vs_tcs;\n"
11439 "\n"
11440 "void main()\n"
11441 "{\n"
11442 " if (TYPE(1) == block.member)\n"
11443 " {\n"
11444 " vs_tcs = vec4(1, 1, 1, 1);\n"
11445 " }\n"
11446 "\n"
11447 " vs_tcs += in_vs;\n"
11448 "}\n"
11449 "\n";
11450
11451 std::string source;
11452 testCase &test_case = m_test_cases[test_case_index];
11453
11454 if (test_case.m_stage == stage)
11455 {
11456 GLchar buffer[16];
11457 const GLuint offset = test_case.m_offset;
11458 size_t position = 0;
11459 const Utils::Type &type = test_case.m_type;
11460 const GLchar *type_name = type.GetGLSLTypeName();
11461
11462 sprintf(buffer, "%d", offset);
11463
11464 switch (stage)
11465 {
11466 case Utils::Shader::COMPUTE:
11467 source = cs;
11468 break;
11469 case Utils::Shader::FRAGMENT:
11470 source = fs_tested;
11471 break;
11472 case Utils::Shader::GEOMETRY:
11473 source = gs_tested;
11474 break;
11475 case Utils::Shader::TESS_CTRL:
11476 source = tcs_tested;
11477 break;
11478 case Utils::Shader::TESS_EVAL:
11479 source = tes_tested;
11480 break;
11481 case Utils::Shader::VERTEX:
11482 source = vs_tested;
11483 break;
11484 default:
11485 TCU_FAIL("Invalid enum");
11486 }
11487
11488 Utils::replaceToken("OFFSET", position, buffer, source);
11489 Utils::replaceToken("TYPE", position, type_name, source);
11490 Utils::replaceToken("TYPE", position, type_name, source);
11491 }
11492 else
11493 {
11494 switch (stage)
11495 {
11496 case Utils::Shader::FRAGMENT:
11497 source = fs;
11498 break;
11499 case Utils::Shader::GEOMETRY:
11500 source = gs;
11501 break;
11502 case Utils::Shader::TESS_CTRL:
11503 source = tcs;
11504 break;
11505 case Utils::Shader::TESS_EVAL:
11506 source = tes;
11507 break;
11508 case Utils::Shader::VERTEX:
11509 source = vs;
11510 break;
11511 default:
11512 TCU_FAIL("Invalid enum");
11513 }
11514 }
11515
11516 return source;
11517 }
11518
11519 /** Checks if stage is supported
11520 *
11521 * @param stage Shader stage
11522 *
11523 * @return true if supported, false otherwise
11524 **/
11525 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage)
11526 {
11527 const Functions &gl = m_context.getRenderContext().getFunctions();
11528 GLint max_supported_buffers = 0;
11529 GLenum pname = 0;
11530
11531 switch (stage)
11532 {
11533 case Utils::Shader::COMPUTE:
11534 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11535 break;
11536 case Utils::Shader::FRAGMENT:
11537 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11538 break;
11539 case Utils::Shader::GEOMETRY:
11540 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11541 break;
11542 case Utils::Shader::TESS_CTRL:
11543 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11544 break;
11545 case Utils::Shader::TESS_EVAL:
11546 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11547 break;
11548 case Utils::Shader::VERTEX:
11549 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11550 break;
11551 default:
11552 TCU_FAIL("Invalid enum");
11553 }
11554
11555 gl.getIntegerv(pname, &max_supported_buffers);
11556 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11557
11558 return 1 <= max_supported_buffers;
11559 }
11560
11561 /** Constructor
11562 *
11563 * @param context Test framework context
11564 **/
11565 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context &context)
11566 : UniformBlockMemberOverlappingOffsetsTest(
11567 context, "ssb_member_overlapping_offsets",
11568 "Test verifies that overlapping offsets qualifiers cause compilation failure")
11569 {
11570 /* Nothing to be done here */
11571 }
11572
11573 /** Source for given test case and stage
11574 *
11575 * @param test_case_index Index of test case
11576 * @param stage Shader stage
11577 *
11578 * @return Shader source
11579 **/
11580 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11581 {
11582 static const GLchar *cs = "#version 430 core\n"
11583 "#extension GL_ARB_enhanced_layouts : require\n"
11584 "\n"
11585 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11586 "\n"
11587 "layout (std140) buffer Block {\n"
11588 " layout (offset = B_OFFSET) B_TYPE b;\n"
11589 " layout (offset = A_OFFSET) A_TYPE a;\n"
11590 "} block;\n"
11591 "\n"
11592 "writeonly uniform image2D uni_image;\n"
11593 "\n"
11594 "void main()\n"
11595 "{\n"
11596 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11597 "\n"
11598 " if ((B_TYPE(1) == block.b) ||\n"
11599 " (A_TYPE(0) == block.a) )\n"
11600 " {\n"
11601 " result = vec4(1, 1, 1, 1);\n"
11602 " }\n"
11603 "\n"
11604 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11605 "}\n"
11606 "\n";
11607 static const GLchar *fs = "#version 430 core\n"
11608 "#extension GL_ARB_enhanced_layouts : require\n"
11609 "\n"
11610 "in vec4 gs_fs;\n"
11611 "out vec4 fs_out;\n"
11612 "\n"
11613 "void main()\n"
11614 "{\n"
11615 " fs_out = gs_fs;\n"
11616 "}\n"
11617 "\n";
11618 static const GLchar *fs_tested = "#version 430 core\n"
11619 "#extension GL_ARB_enhanced_layouts : require\n"
11620 "\n"
11621 "layout (std140) buffer Block {\n"
11622 " layout (offset = B_OFFSET) B_TYPE b;\n"
11623 " layout (offset = A_OFFSET) A_TYPE a;\n"
11624 "} block;\n"
11625 "\n"
11626 "in vec4 gs_fs;\n"
11627 "out vec4 fs_out;\n"
11628 "\n"
11629 "void main()\n"
11630 "{\n"
11631 " if ((B_TYPE(1) == block.b) ||\n"
11632 " (A_TYPE(0) == block.a) )\n"
11633 " {\n"
11634 " fs_out = vec4(1, 1, 1, 1);\n"
11635 " }\n"
11636 "\n"
11637 " fs_out += gs_fs;\n"
11638 "}\n"
11639 "\n";
11640 static const GLchar *gs = "#version 430 core\n"
11641 "#extension GL_ARB_enhanced_layouts : require\n"
11642 "\n"
11643 "layout(points) in;\n"
11644 "layout(triangle_strip, max_vertices = 4) out;\n"
11645 "\n"
11646 "in vec4 tes_gs[];\n"
11647 "out vec4 gs_fs;\n"
11648 "\n"
11649 "void main()\n"
11650 "{\n"
11651 " gs_fs = tes_gs[0];\n"
11652 " gl_Position = vec4(-1, -1, 0, 1);\n"
11653 " EmitVertex();\n"
11654 " gs_fs = tes_gs[0];\n"
11655 " gl_Position = vec4(-1, 1, 0, 1);\n"
11656 " EmitVertex();\n"
11657 " gs_fs = tes_gs[0];\n"
11658 " gl_Position = vec4(1, -1, 0, 1);\n"
11659 " EmitVertex();\n"
11660 " gs_fs = tes_gs[0];\n"
11661 " gl_Position = vec4(1, 1, 0, 1);\n"
11662 " EmitVertex();\n"
11663 "}\n"
11664 "\n";
11665 static const GLchar *gs_tested = "#version 430 core\n"
11666 "#extension GL_ARB_enhanced_layouts : require\n"
11667 "\n"
11668 "layout(points) in;\n"
11669 "layout(triangle_strip, max_vertices = 4) out;\n"
11670 "\n"
11671 "layout (std140) buffer Block {\n"
11672 " layout (offset = B_OFFSET) B_TYPE b;\n"
11673 " layout (offset = A_OFFSET) A_TYPE a;\n"
11674 "} block;\n"
11675 "\n"
11676 "in vec4 tes_gs[];\n"
11677 "out vec4 gs_fs;\n"
11678 "\n"
11679 "void main()\n"
11680 "{\n"
11681 " if ((B_TYPE(1) == block.b) ||\n"
11682 " (A_TYPE(0) == block.a) )\n"
11683 " {\n"
11684 " gs_fs = vec4(1, 1, 1, 1);\n"
11685 " }\n"
11686 "\n"
11687 " gs_fs += tes_gs[0];\n"
11688 " gl_Position = vec4(-1, -1, 0, 1);\n"
11689 " EmitVertex();\n"
11690 " gs_fs += tes_gs[0];\n"
11691 " gl_Position = vec4(-1, 1, 0, 1);\n"
11692 " EmitVertex();\n"
11693 " gs_fs += tes_gs[0];\n"
11694 " gl_Position = vec4(1, -1, 0, 1);\n"
11695 " EmitVertex();\n"
11696 " gs_fs += tes_gs[0];\n"
11697 " gl_Position = vec4(1, 1, 0, 1);\n"
11698 " EmitVertex();\n"
11699 "}\n"
11700 "\n";
11701 static const GLchar *tcs = "#version 430 core\n"
11702 "#extension GL_ARB_enhanced_layouts : require\n"
11703 "\n"
11704 "layout(vertices = 1) out;\n"
11705 "\n"
11706 "in vec4 vs_tcs[];\n"
11707 "out vec4 tcs_tes[];\n"
11708 "\n"
11709 "void main()\n"
11710 "{\n"
11711 "\n"
11712 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11713 "\n"
11714 " gl_TessLevelOuter[0] = 1.0;\n"
11715 " gl_TessLevelOuter[1] = 1.0;\n"
11716 " gl_TessLevelOuter[2] = 1.0;\n"
11717 " gl_TessLevelOuter[3] = 1.0;\n"
11718 " gl_TessLevelInner[0] = 1.0;\n"
11719 " gl_TessLevelInner[1] = 1.0;\n"
11720 "}\n"
11721 "\n";
11722 static const GLchar *tcs_tested = "#version 430 core\n"
11723 "#extension GL_ARB_enhanced_layouts : require\n"
11724 "\n"
11725 "layout(vertices = 1) out;\n"
11726 "\n"
11727 "layout (std140) buffer Block {\n"
11728 " layout (offset = B_OFFSET) B_TYPE b;\n"
11729 " layout (offset = A_OFFSET) A_TYPE a;\n"
11730 "} block;\n"
11731 "\n"
11732 "in vec4 vs_tcs[];\n"
11733 "out vec4 tcs_tes[];\n"
11734 "\n"
11735 "void main()\n"
11736 "{\n"
11737 " if ((B_TYPE(1) == block.b) ||\n"
11738 " (A_TYPE(0) == block.a) )\n"
11739 " {\n"
11740 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11741 " }\n"
11742 "\n"
11743 "\n"
11744 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11745 "\n"
11746 " gl_TessLevelOuter[0] = 1.0;\n"
11747 " gl_TessLevelOuter[1] = 1.0;\n"
11748 " gl_TessLevelOuter[2] = 1.0;\n"
11749 " gl_TessLevelOuter[3] = 1.0;\n"
11750 " gl_TessLevelInner[0] = 1.0;\n"
11751 " gl_TessLevelInner[1] = 1.0;\n"
11752 "}\n"
11753 "\n";
11754 static const GLchar *tes = "#version 430 core\n"
11755 "#extension GL_ARB_enhanced_layouts : require\n"
11756 "\n"
11757 "layout(isolines, point_mode) in;\n"
11758 "\n"
11759 "in vec4 tcs_tes[];\n"
11760 "out vec4 tes_gs;\n"
11761 "\n"
11762 "void main()\n"
11763 "{\n"
11764 " tes_gs = tcs_tes[0];\n"
11765 "}\n"
11766 "\n";
11767 static const GLchar *tes_tested = "#version 430 core\n"
11768 "#extension GL_ARB_enhanced_layouts : require\n"
11769 "\n"
11770 "layout(isolines, point_mode) in;\n"
11771 "\n"
11772 "layout (std140) buffer Block {\n"
11773 " layout (offset = B_OFFSET) B_TYPE b;\n"
11774 " layout (offset = A_OFFSET) A_TYPE a;\n"
11775 "} block;\n"
11776 "\n"
11777 "in vec4 tcs_tes[];\n"
11778 "out vec4 tes_gs;\n"
11779 "\n"
11780 "void main()\n"
11781 "{\n"
11782 " if ((B_TYPE(1) == block.b) ||\n"
11783 " (A_TYPE(0) == block.a) )\n"
11784 " {\n"
11785 " tes_gs = vec4(1, 1, 1, 1);\n"
11786 " }\n"
11787 "\n"
11788 " tes_gs += tcs_tes[0];\n"
11789 "}\n"
11790 "\n";
11791 static const GLchar *vs = "#version 430 core\n"
11792 "#extension GL_ARB_enhanced_layouts : require\n"
11793 "\n"
11794 "in vec4 in_vs;\n"
11795 "out vec4 vs_tcs;\n"
11796 "\n"
11797 "void main()\n"
11798 "{\n"
11799 " vs_tcs = in_vs;\n"
11800 "}\n"
11801 "\n";
11802 static const GLchar *vs_tested = "#version 430 core\n"
11803 "#extension GL_ARB_enhanced_layouts : require\n"
11804 "\n"
11805 "layout (std140) buffer Block {\n"
11806 " layout (offset = B_OFFSET) B_TYPE b;\n"
11807 " layout (offset = A_OFFSET) A_TYPE a;\n"
11808 "} block;\n"
11809 "\n"
11810 "in vec4 in_vs;\n"
11811 "out vec4 vs_tcs;\n"
11812 "\n"
11813 "void main()\n"
11814 "{\n"
11815 " if ((B_TYPE(1) == block.b) ||\n"
11816 " (A_TYPE(0) == block.a) )\n"
11817 " {\n"
11818 " vs_tcs = vec4(1, 1, 1, 1);\n"
11819 " }\n"
11820 "\n"
11821 " vs_tcs += in_vs;\n"
11822 "}\n"
11823 "\n";
11824
11825 std::string source;
11826 testCase &test_case = m_test_cases[test_case_index];
11827
11828 if (test_case.m_stage == stage)
11829 {
11830 GLchar buffer[16];
11831 const GLuint b_offset = test_case.m_b_offset;
11832 const Utils::Type &b_type = test_case.m_b_type;
11833 const GLchar *b_type_name = b_type.GetGLSLTypeName();
11834 const GLuint a_offset = test_case.m_a_offset;
11835 const Utils::Type &a_type = test_case.m_a_type;
11836 const GLchar *a_type_name = a_type.GetGLSLTypeName();
11837 size_t position = 0;
11838
11839 switch (stage)
11840 {
11841 case Utils::Shader::COMPUTE:
11842 source = cs;
11843 break;
11844 case Utils::Shader::FRAGMENT:
11845 source = fs_tested;
11846 break;
11847 case Utils::Shader::GEOMETRY:
11848 source = gs_tested;
11849 break;
11850 case Utils::Shader::TESS_CTRL:
11851 source = tcs_tested;
11852 break;
11853 case Utils::Shader::TESS_EVAL:
11854 source = tes_tested;
11855 break;
11856 case Utils::Shader::VERTEX:
11857 source = vs_tested;
11858 break;
11859 default:
11860 TCU_FAIL("Invalid enum");
11861 }
11862
11863 sprintf(buffer, "%d", b_offset);
11864 Utils::replaceToken("B_OFFSET", position, buffer, source);
11865 Utils::replaceToken("B_TYPE", position, b_type_name, source);
11866 sprintf(buffer, "%d", a_offset);
11867 Utils::replaceToken("A_OFFSET", position, buffer, source);
11868 Utils::replaceToken("A_TYPE", position, a_type_name, source);
11869 Utils::replaceToken("B_TYPE", position, b_type_name, source);
11870 Utils::replaceToken("A_TYPE", position, a_type_name, source);
11871 }
11872 else
11873 {
11874 switch (stage)
11875 {
11876 case Utils::Shader::FRAGMENT:
11877 source = fs;
11878 break;
11879 case Utils::Shader::GEOMETRY:
11880 source = gs;
11881 break;
11882 case Utils::Shader::TESS_CTRL:
11883 source = tcs;
11884 break;
11885 case Utils::Shader::TESS_EVAL:
11886 source = tes;
11887 break;
11888 case Utils::Shader::VERTEX:
11889 source = vs;
11890 break;
11891 default:
11892 TCU_FAIL("Invalid enum");
11893 }
11894 }
11895
11896 return source;
11897 }
11898
11899 /** Checks if stage is supported
11900 *
11901 * @param stage Shader stage
11902 *
11903 * @return true if supported, false otherwise
11904 **/
11905 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage)
11906 {
11907 const Functions &gl = m_context.getRenderContext().getFunctions();
11908 GLint max_supported_buffers = 0;
11909 GLenum pname = 0;
11910
11911 switch (stage)
11912 {
11913 case Utils::Shader::COMPUTE:
11914 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11915 break;
11916 case Utils::Shader::FRAGMENT:
11917 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11918 break;
11919 case Utils::Shader::GEOMETRY:
11920 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11921 break;
11922 case Utils::Shader::TESS_CTRL:
11923 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11924 break;
11925 case Utils::Shader::TESS_EVAL:
11926 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11927 break;
11928 case Utils::Shader::VERTEX:
11929 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11930 break;
11931 default:
11932 TCU_FAIL("Invalid enum");
11933 }
11934
11935 gl.getIntegerv(pname, &max_supported_buffers);
11936 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11937
11938 return 1 <= max_supported_buffers;
11939 }
11940
11941 /** Constructor
11942 *
11943 * @param context Test framework context
11944 **/
11945 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context &context)
11946 : UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2",
11947 "Test verifies that align qualifier requires value that is a power of 2")
11948 {
11949 /* Nothing to be done here */
11950 }
11951
11952 /** Source for given test case and stage
11953 *
11954 * @param test_case_index Index of test case
11955 * @param stage Shader stage
11956 *
11957 * @return Shader source
11958 **/
11959 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11960 {
11961 static const GLchar *cs = "#version 430 core\n"
11962 "#extension GL_ARB_enhanced_layouts : require\n"
11963 "\n"
11964 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11965 "\n"
11966 "layout (std140) buffer Block {\n"
11967 " vec4 b;\n"
11968 " layout (align = ALIGN) TYPE a;\n"
11969 "} block;\n"
11970 "\n"
11971 "writeonly uniform image2D uni_image;\n"
11972 "\n"
11973 "void main()\n"
11974 "{\n"
11975 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11976 "\n"
11977 " if (TYPE(0) == block.a)\n"
11978 " {\n"
11979 " result = vec4(1, 1, 1, 1) - block.b;\n"
11980 " }\n"
11981 "\n"
11982 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11983 "}\n"
11984 "\n";
11985 static const GLchar *fs = "#version 430 core\n"
11986 "#extension GL_ARB_enhanced_layouts : require\n"
11987 "\n"
11988 "in vec4 gs_fs;\n"
11989 "out vec4 fs_out;\n"
11990 "\n"
11991 "void main()\n"
11992 "{\n"
11993 " fs_out = gs_fs;\n"
11994 "}\n"
11995 "\n";
11996 static const GLchar *fs_tested = "#version 430 core\n"
11997 "#extension GL_ARB_enhanced_layouts : require\n"
11998 "\n"
11999 "layout (std140) buffer Block {\n"
12000 " vec4 b;\n"
12001 " layout (align = ALIGN) TYPE a;\n"
12002 "} block;\n"
12003 "\n"
12004 "in vec4 gs_fs;\n"
12005 "out vec4 fs_out;\n"
12006 "\n"
12007 "void main()\n"
12008 "{\n"
12009 " if (TYPE(0) == block.a)\n"
12010 " {\n"
12011 " fs_out = block.b;\n"
12012 " }\n"
12013 "\n"
12014 " fs_out += gs_fs;\n"
12015 "}\n"
12016 "\n";
12017 static const GLchar *gs = "#version 430 core\n"
12018 "#extension GL_ARB_enhanced_layouts : require\n"
12019 "\n"
12020 "layout(points) in;\n"
12021 "layout(triangle_strip, max_vertices = 4) out;\n"
12022 "\n"
12023 "in vec4 tes_gs[];\n"
12024 "out vec4 gs_fs;\n"
12025 "\n"
12026 "void main()\n"
12027 "{\n"
12028 " gs_fs = tes_gs[0];\n"
12029 " gl_Position = vec4(-1, -1, 0, 1);\n"
12030 " EmitVertex();\n"
12031 " gs_fs = tes_gs[0];\n"
12032 " gl_Position = vec4(-1, 1, 0, 1);\n"
12033 " EmitVertex();\n"
12034 " gs_fs = tes_gs[0];\n"
12035 " gl_Position = vec4(1, -1, 0, 1);\n"
12036 " EmitVertex();\n"
12037 " gs_fs = tes_gs[0];\n"
12038 " gl_Position = vec4(1, 1, 0, 1);\n"
12039 " EmitVertex();\n"
12040 "}\n"
12041 "\n";
12042 static const GLchar *gs_tested = "#version 430 core\n"
12043 "#extension GL_ARB_enhanced_layouts : require\n"
12044 "\n"
12045 "layout(points) in;\n"
12046 "layout(triangle_strip, max_vertices = 4) out;\n"
12047 "\n"
12048 "layout (std140) buffer Block {\n"
12049 " vec4 b;\n"
12050 " layout (align = ALIGN) TYPE a;\n"
12051 "} block;\n"
12052 "\n"
12053 "in vec4 tes_gs[];\n"
12054 "out vec4 gs_fs;\n"
12055 "\n"
12056 "void main()\n"
12057 "{\n"
12058 " if (TYPE(0) == block.a)\n"
12059 " {\n"
12060 " gs_fs = block.b;\n"
12061 " }\n"
12062 "\n"
12063 " gs_fs += tes_gs[0];\n"
12064 " gl_Position = vec4(-1, -1, 0, 1);\n"
12065 " EmitVertex();\n"
12066 " gs_fs += tes_gs[0];\n"
12067 " gl_Position = vec4(-1, 1, 0, 1);\n"
12068 " EmitVertex();\n"
12069 " gs_fs += tes_gs[0];\n"
12070 " gl_Position = vec4(1, -1, 0, 1);\n"
12071 " EmitVertex();\n"
12072 " gs_fs += tes_gs[0];\n"
12073 " gl_Position = vec4(1, 1, 0, 1);\n"
12074 " EmitVertex();\n"
12075 "}\n"
12076 "\n";
12077 static const GLchar *tcs = "#version 430 core\n"
12078 "#extension GL_ARB_enhanced_layouts : require\n"
12079 "\n"
12080 "layout(vertices = 1) out;\n"
12081 "\n"
12082 "in vec4 vs_tcs[];\n"
12083 "out vec4 tcs_tes[];\n"
12084 "\n"
12085 "void main()\n"
12086 "{\n"
12087 "\n"
12088 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
12089 "\n"
12090 " gl_TessLevelOuter[0] = 1.0;\n"
12091 " gl_TessLevelOuter[1] = 1.0;\n"
12092 " gl_TessLevelOuter[2] = 1.0;\n"
12093 " gl_TessLevelOuter[3] = 1.0;\n"
12094 " gl_TessLevelInner[0] = 1.0;\n"
12095 " gl_TessLevelInner[1] = 1.0;\n"
12096 "}\n"
12097 "\n";
12098 static const GLchar *tcs_tested = "#version 430 core\n"
12099 "#extension GL_ARB_enhanced_layouts : require\n"
12100 "\n"
12101 "layout(vertices = 1) out;\n"
12102 "\n"
12103 "layout (std140) buffer Block {\n"
12104 " vec4 b;\n"
12105 " layout (align = ALIGN) TYPE a;\n"
12106 "} block;\n"
12107 "\n"
12108 "in vec4 vs_tcs[];\n"
12109 "out vec4 tcs_tes[];\n"
12110 "\n"
12111 "void main()\n"
12112 "{\n"
12113 " if (TYPE(0) == block.a)\n"
12114 " {\n"
12115 " tcs_tes[gl_InvocationID] = block.b;\n"
12116 " }\n"
12117 "\n"
12118 "\n"
12119 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
12120 "\n"
12121 " gl_TessLevelOuter[0] = 1.0;\n"
12122 " gl_TessLevelOuter[1] = 1.0;\n"
12123 " gl_TessLevelOuter[2] = 1.0;\n"
12124 " gl_TessLevelOuter[3] = 1.0;\n"
12125 " gl_TessLevelInner[0] = 1.0;\n"
12126 " gl_TessLevelInner[1] = 1.0;\n"
12127 "}\n"
12128 "\n";
12129 static const GLchar *tes = "#version 430 core\n"
12130 "#extension GL_ARB_enhanced_layouts : require\n"
12131 "\n"
12132 "layout(isolines, point_mode) in;\n"
12133 "\n"
12134 "in vec4 tcs_tes[];\n"
12135 "out vec4 tes_gs;\n"
12136 "\n"
12137 "void main()\n"
12138 "{\n"
12139 " tes_gs = tcs_tes[0];\n"
12140 "}\n"
12141 "\n";
12142 static const GLchar *tes_tested = "#version 430 core\n"
12143 "#extension GL_ARB_enhanced_layouts : require\n"
12144 "\n"
12145 "layout(isolines, point_mode) in;\n"
12146 "\n"
12147 "layout (std140) buffer Block {\n"
12148 " vec4 b;\n"
12149 " layout (align = ALIGN) TYPE a;\n"
12150 "} block;\n"
12151 "\n"
12152 "in vec4 tcs_tes[];\n"
12153 "out vec4 tes_gs;\n"
12154 "\n"
12155 "void main()\n"
12156 "{\n"
12157 " if (TYPE(0) == block.a)\n"
12158 " {\n"
12159 " tes_gs = block.b;\n"
12160 " }\n"
12161 "\n"
12162 " tes_gs += tcs_tes[0];\n"
12163 "}\n"
12164 "\n";
12165 static const GLchar *vs = "#version 430 core\n"
12166 "#extension GL_ARB_enhanced_layouts : require\n"
12167 "\n"
12168 "in vec4 in_vs;\n"
12169 "out vec4 vs_tcs;\n"
12170 "\n"
12171 "void main()\n"
12172 "{\n"
12173 " vs_tcs = in_vs;\n"
12174 "}\n"
12175 "\n";
12176 static const GLchar *vs_tested = "#version 430 core\n"
12177 "#extension GL_ARB_enhanced_layouts : require\n"
12178 "\n"
12179 "layout (std140) buffer Block {\n"
12180 " vec4 b;\n"
12181 " layout (align = ALIGN) TYPE a;\n"
12182 "} block;\n"
12183 "\n"
12184 "in vec4 in_vs;\n"
12185 "out vec4 vs_tcs;\n"
12186 "\n"
12187 "void main()\n"
12188 "{\n"
12189 " if (TYPE(0) == block.a)\n"
12190 " {\n"
12191 " vs_tcs = block.b;\n"
12192 " }\n"
12193 "\n"
12194 " vs_tcs += in_vs;\n"
12195 "}\n"
12196 "\n";
12197
12198 std::string source;
12199 testCase &test_case = m_test_cases[test_case_index];
12200
12201 if (test_case.m_stage == stage)
12202 {
12203 GLchar buffer[16];
12204 const GLuint alignment = test_case.m_alignment;
12205 const Utils::Type &type = test_case.m_type;
12206 const GLchar *type_name = type.GetGLSLTypeName();
12207 size_t position = 0;
12208
12209 switch (stage)
12210 {
12211 case Utils::Shader::COMPUTE:
12212 source = cs;
12213 break;
12214 case Utils::Shader::FRAGMENT:
12215 source = fs_tested;
12216 break;
12217 case Utils::Shader::GEOMETRY:
12218 source = gs_tested;
12219 break;
12220 case Utils::Shader::TESS_CTRL:
12221 source = tcs_tested;
12222 break;
12223 case Utils::Shader::TESS_EVAL:
12224 source = tes_tested;
12225 break;
12226 case Utils::Shader::VERTEX:
12227 source = vs_tested;
12228 break;
12229 default:
12230 TCU_FAIL("Invalid enum");
12231 }
12232
12233 sprintf(buffer, "%d", alignment);
12234 Utils::replaceToken("ALIGN", position, buffer, source);
12235 Utils::replaceToken("TYPE", position, type_name, source);
12236 Utils::replaceToken("TYPE", position, type_name, source);
12237 }
12238 else
12239 {
12240 switch (stage)
12241 {
12242 case Utils::Shader::FRAGMENT:
12243 source = fs;
12244 break;
12245 case Utils::Shader::GEOMETRY:
12246 source = gs;
12247 break;
12248 case Utils::Shader::TESS_CTRL:
12249 source = tcs;
12250 break;
12251 case Utils::Shader::TESS_EVAL:
12252 source = tes;
12253 break;
12254 case Utils::Shader::VERTEX:
12255 source = vs;
12256 break;
12257 default:
12258 TCU_FAIL("Invalid enum");
12259 }
12260 }
12261
12262 return source;
12263 }
12264
12265 /** Checks if stage is supported
12266 *
12267 * @param stage Shader stage
12268 *
12269 * @return true if supported, false otherwise
12270 **/
12271 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage)
12272 {
12273 const Functions &gl = m_context.getRenderContext().getFunctions();
12274 GLint max_supported_buffers = 0;
12275 GLenum pname = 0;
12276
12277 switch (stage)
12278 {
12279 case Utils::Shader::COMPUTE:
12280 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
12281 break;
12282 case Utils::Shader::FRAGMENT:
12283 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
12284 break;
12285 case Utils::Shader::GEOMETRY:
12286 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
12287 break;
12288 case Utils::Shader::TESS_CTRL:
12289 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
12290 break;
12291 case Utils::Shader::TESS_EVAL:
12292 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
12293 break;
12294 case Utils::Shader::VERTEX:
12295 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
12296 break;
12297 default:
12298 TCU_FAIL("Invalid enum");
12299 }
12300
12301 gl.getIntegerv(pname, &max_supported_buffers);
12302 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12303
12304 return 1 <= max_supported_buffers;
12305 }
12306
12307 /** Constructor
12308 *
12309 * @param context Test framework context
12310 **/
12311 SSBAlignmentTest::SSBAlignmentTest(deqp::Context &context)
12312 : TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer")
12313 {
12314 }
12315
12316 /** Get interface of program
12317 *
12318 * @param ignored
12319 * @param program_interface Interface of program
12320 * @param varying_passthrough Collection of connections between in and out variables
12321 **/
12322 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface &program_interface,
12323 Utils::VaryingPassthrough &varying_passthrough)
12324 {
12325 static const Utils::Type vec4 = Utils::Type::vec4;
12326
12327 #if WRKARD_UNIFORMBLOCKALIGNMENT
12328
12329 static const GLuint block_align = 16;
12330
12331 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12332
12333 static const GLuint block_align = 64;
12334
12335 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12336
12337 static const GLuint fifth_align = 16;
12338 static const GLuint vec4_stride = 16;
12339 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
12340
12341 const GLuint first_offset = 0; /* vec4 at 0 */
12342 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
12343 const GLuint third_offset =
12344 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
12345 const GLuint fourth_offset =
12346 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
12347 const GLuint fifth_offset =
12348 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */
12349 const GLuint sixth_offset =
12350 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
12351
12352 Utils::Interface *structure = program_interface.Structure("Data");
12353
12354 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12355 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
12356
12357 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
12358 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
12359 Utils::Type::vec4.GetSize() /* offset */);
12360
12361 /* Prepare Block */
12362 Utils::Interface *vs_buf_Block = program_interface.Block("vs_buf_Block");
12363
12364 vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12365 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
12366
12367 vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12368 0 /* n_array_elements */, data_stride, second_offset);
12369
12370 vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12371 2 /* n_array_elements */, data_stride, third_offset);
12372
12373 vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
12374 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
12375
12376 vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4,
12377 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
12378
12379 vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12380 0 /* n_array_elements */, data_stride, sixth_offset);
12381
12382 const GLuint stride = calculateStride(*vs_buf_Block);
12383 m_data.resize(stride);
12384 generateData(*vs_buf_Block, 0, m_data);
12385
12386 Utils::ShaderInterface &vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12387
12388 /* Add uniform BLOCK */
12389 #if WRKARD_UNIFORMBLOCKALIGNMENT
12390 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0,
12391 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12392 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12393 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0,
12394 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12395 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12396
12397 program_interface.CloneVertexInterface(varying_passthrough);
12398 }
12399
12400 /** Selects if "draw" stages are relevant for test
12401 *
12402 * @param ignored
12403 *
12404 * @return true if all stages support shader storage buffers, false otherwise
12405 **/
12406 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */)
12407 {
12408 const Functions &gl = m_context.getRenderContext().getFunctions();
12409 GLint gs_supported_buffers = 0;
12410 GLint tcs_supported_buffers = 0;
12411 GLint tes_supported_buffers = 0;
12412 GLint vs_supported_buffers = 0;
12413
12414 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
12415 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
12416 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
12417 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
12418
12419 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12420
12421 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
12422 (1 <= vs_supported_buffers));
12423 }
12424
12425 /** Constructor
12426 *
12427 * @param context Test framework context
12428 **/
12429 VaryingLocationsTest::VaryingLocationsTest(deqp::Context &context)
12430 : TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected")
12431 {
12432 }
12433
12434 /** Constructor
12435 *
12436 * @param context Test context
12437 * @param test_name Name of test
12438 * @param test_description Description of test
12439 **/
12440 VaryingLocationsTest::VaryingLocationsTest(deqp::Context &context, const glw::GLchar *test_name,
12441 const glw::GLchar *test_description)
12442 : TextureTestBase(context, test_name, test_description)
12443 {
12444 }
12445
12446 /** Get interface of program
12447 *
12448 * @param test_case_index Test case
12449 * @param program_interface Interface of program
12450 * @param varying_passthrough Collection of connections between in and out variables
12451 **/
12452 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface &program_interface,
12453 Utils::VaryingPassthrough &varying_passthrough)
12454 {
12455 const Utils::Type type = getType(test_case_index);
12456
12457 m_first_data = type.GenerateDataPacked();
12458 m_last_data = type.GenerateDataPacked();
12459
12460 prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough);
12461 prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough);
12462 prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough);
12463 prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough);
12464 prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough);
12465 }
12466
12467 /** Get type name
12468 *
12469 * @param test_case_index Index of test case
12470 *
12471 * @return Name of type test in test_case_index
12472 **/
12473 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12474 {
12475 return getTypeName(test_case_index);
12476 }
12477
12478 /** Returns number of types to test
12479 *
12480 * @return Number of types, 34
12481 **/
12482 glw::GLuint VaryingLocationsTest::getTestCaseNumber()
12483 {
12484 return getTypesNumber();
12485 }
12486
12487 /** Selects if "compute" stage is relevant for test
12488 *
12489 * @param ignored
12490 *
12491 * @return false
12492 **/
12493 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12494 {
12495 return false;
12496 }
12497
12498 /**
12499 *
12500 *
12501 **/
12502 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc)
12503 {
12504 GLchar buffer[16];
12505 std::string globals = "const uint first_input_location = 0u;\n"
12506 "const uint first_output_location = 0u;\n"
12507 "const uint last_input_location = LAST_INPUTu;\n"
12508 "const uint last_output_location = LAST_OUTPUTu;\n";
12509 size_t position = 100; /* Skip first part */
12510
12511 sprintf(buffer, "%d", last_in_loc);
12512 Utils::replaceToken("LAST_INPUT", position, buffer, globals);
12513
12514 sprintf(buffer, "%d", last_out_loc);
12515 Utils::replaceToken("LAST_OUTPUT", position, buffer, globals);
12516
12517 return globals;
12518 }
12519
12520 /**
12521 *
12522 **/
12523 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type &type,
12524 Utils::ProgramInterface &program_interface,
12525 Utils::VaryingPassthrough &varying_passthrough)
12526 {
12527 const GLuint array_length = 1;
12528 const GLuint first_in_loc = 0;
12529 const GLuint first_out_loc = 0;
12530 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length, false);
12531 size_t position = 0;
12532
12533 const GLchar *prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12534
12535 const GLchar *prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12536
12537 const GLchar *qual_first_in = "layout (location = first_input_location)";
12538 const GLchar *qual_first_out = "layout (location = first_output_location)";
12539 const GLchar *qual_last_in = "layout (location = last_input_location)";
12540 const GLchar *qual_last_out = "layout (location = last_output_location)";
12541
12542 Utils::ShaderInterface &si = program_interface.GetShaderInterface(stage);
12543 const GLuint type_size = type.GetSize();
12544
12545 std::string first_in_name = "PREFIXfirst";
12546 std::string first_out_name = "PREFIXfirst";
12547 std::string last_in_name = "PREFIXlast";
12548 std::string last_out_name = "PREFIXlast";
12549
12550 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12551 position = 0;
12552 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12553 position = 0;
12554 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12555 position = 0;
12556 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12557
12558 if (Utils::Shader::FRAGMENT == stage)
12559 {
12560 qual_first_in = "layout (location = first_input_location) flat";
12561 qual_last_in = "layout (location = last_input_location) flat";
12562 }
12563 if (Utils::Shader::GEOMETRY == stage)
12564 {
12565 qual_first_out = "layout (location = first_output_location) flat";
12566 qual_last_out = "layout (location = last_output_location) flat";
12567 }
12568
12569 Utils::Variable *first_in = si.Input(
12570 first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12571 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12572 0u /* stride */, 0u /* offset */, (GLvoid *)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12573
12574 Utils::Variable *last_in =
12575 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12576 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12577 0u /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12578 (GLvoid *)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12579
12580 if (Utils::Shader::FRAGMENT != stage)
12581 {
12582 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length, false);
12583
12584 Utils::Variable *first_out =
12585 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12586 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12587 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12588 (GLvoid *)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12589
12590 Utils::Variable *last_out = si.Output(
12591 last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12592 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12593 0u /* stride */, 0u /* offset */, (GLvoid *)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12594
12595 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12596
12597 varying_passthrough.Add(stage, first_in, first_out);
12598 varying_passthrough.Add(stage, last_in, last_out);
12599 }
12600 else
12601 {
12602 /* No outputs for fragment shader, so last_output_location can be 0 */
12603 si.m_globals = prepareGlobals(last_in_loc, 0);
12604 }
12605 }
12606
12607 /** This test should be run with separable programs
12608 *
12609 * @param ignored
12610 *
12611 * @return true
12612 **/
12613 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12614 {
12615 return false;
12616 }
12617
12618 /* Constants used by VertexAttribLocationsTest */
12619 const GLuint VertexAttribLocationsTest::m_base_vertex = 4;
12620 const GLuint VertexAttribLocationsTest::m_base_instance = 2;
12621 const GLuint VertexAttribLocationsTest::m_loc_vertex = 2;
12622 const GLuint VertexAttribLocationsTest::m_loc_instance = 5;
12623 const GLuint VertexAttribLocationsTest::m_n_instances = 4;
12624
12625 /** Constructor
12626 *
12627 * @param context Test framework context
12628 **/
12629 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context &context)
12630 : TextureTestBase(context, "vertex_attrib_locations",
12631 "Test verifies that attribute locations are respected by drawing operations")
12632 {
12633 }
12634
12635 /** Execute proper draw command for test case
12636 *
12637 * @param test_case_index Index of test case
12638 **/
12639 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index)
12640 {
12641 const Functions &gl = m_context.getRenderContext().getFunctions();
12642
12643 switch (test_case_index)
12644 {
12645 case DRAWARRAYS:
12646 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
12647 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
12648 break;
12649 case DRAWARRAYSINSTANCED:
12650 gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances);
12651 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced");
12652 break;
12653 case DRAWELEMENTS:
12654 gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL);
12655 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
12656 break;
12657 case DRAWELEMENTSBASEVERTEX:
12658 gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_base_vertex);
12659 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex");
12660 break;
12661 case DRAWELEMENTSINSTANCED:
12662 gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances);
12663 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced");
12664 break;
12665 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12666 gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12667 m_base_instance);
12668 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance");
12669 break;
12670 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12671 gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12672 m_base_vertex);
12673 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex");
12674 break;
12675 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12676 gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL,
12677 m_n_instances, m_base_vertex, m_base_instance);
12678 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance");
12679 break;
12680 default:
12681 TCU_FAIL("Invalid enum");
12682 }
12683 }
12684
12685 /** Get interface of program
12686 *
12687 * @param ignored
12688 * @param program_interface Interface of program
12689 * @param ignored
12690 **/
12691 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */,
12692 Utils::ProgramInterface &program_interface,
12693 Utils::VaryingPassthrough & /* varying_passthrough */)
12694 {
12695 Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12696
12697 /* Globals */
12698 si.m_globals = "const uint vertex_index_location = 2;\n"
12699 "const uint instance_index_location = 5;\n";
12700
12701 /* Attributes */
12702 si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */,
12703 0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */,
12704 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */,
12705 (GLvoid *)0 /* data */, 0 /* data_size */);
12706 si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */,
12707 0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */,
12708 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */,
12709 (GLvoid *)0 /* data */, 0 /* data_size */);
12710 }
12711
12712 /** Get name of test case
12713 *
12714 * @param test_case_index Index of test case
12715 *
12716 * @return Name of test case
12717 **/
12718 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12719 {
12720 std::string result;
12721
12722 switch (test_case_index)
12723 {
12724 case DRAWARRAYS:
12725 result = "DrawArrays";
12726 break;
12727 case DRAWARRAYSINSTANCED:
12728 result = "DrawArraysInstanced";
12729 break;
12730 case DRAWELEMENTS:
12731 result = "DrawElements";
12732 break;
12733 case DRAWELEMENTSBASEVERTEX:
12734 result = "DrawElementsBaseVertex";
12735 break;
12736 case DRAWELEMENTSINSTANCED:
12737 result = "DrawElementsInstanced";
12738 break;
12739 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12740 result = "DrawElementsInstancedBaseInstance";
12741 break;
12742 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12743 result = "DrawElementsInstancedBaseVertex";
12744 break;
12745 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12746 result = "DrawElementsInstancedBaseVertexBaseInstance";
12747 break;
12748 default:
12749 TCU_FAIL("Invalid enum");
12750 }
12751
12752 return result;
12753 }
12754
12755 /** Get number of test cases
12756 *
12757 * @return Number of test cases
12758 **/
12759 GLuint VertexAttribLocationsTest::getTestCaseNumber()
12760 {
12761 return TESTCASES_MAX;
12762 }
12763
12764 /** Prepare code snippet that will verify in and uniform variables
12765 *
12766 * @param ignored
12767 * @param ignored
12768 * @param stage Shader stage
12769 *
12770 * @return Code that verify variables
12771 **/
12772 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */,
12773 Utils::ProgramInterface & /* program_interface */,
12774 Utils::Shader::STAGES stage)
12775 {
12776 std::string verification;
12777
12778 if (Utils::Shader::VERTEX == stage)
12779 {
12780
12781 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE
12782
12783 verification = "if (gl_InstanceID != instance_index)\n"
12784 " {\n"
12785 " result = 12u;\n"
12786 " }\n"
12787 " else if (gl_VertexID != vertex_index)\n"
12788 " {\n"
12789 " result = 11u;\n"
12790 " }\n";
12791
12792 #else
12793
12794 verification = "if ((gl_VertexID != vertex_index) ||\n"
12795 " (gl_InstanceID != instance_index) )\n"
12796 " {\n"
12797 " result = 0u;\n"
12798 " }\n";
12799
12800 #endif
12801 }
12802 else
12803 {
12804 verification = "";
12805 }
12806
12807 return verification;
12808 }
12809
12810 /** Selects if "compute" stage is relevant for test
12811 *
12812 * @param ignored
12813 *
12814 * @return false
12815 **/
12816 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12817 {
12818 return false;
12819 }
12820
12821 /** Prepare attributes, vertex array object and array buffer
12822 *
12823 * @param ignored
12824 * @param ignored Interface of program
12825 * @param buffer Array buffer
12826 * @param vao Vertex array object
12827 **/
12828 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */,
12829 Utils::ProgramInterface & /* program_interface */,
12830 Utils::Buffer &buffer, Utils::VertexArray &vao)
12831 {
12832 static const GLuint vertex_index_data[8] = {0, 1, 2, 3, 4, 5, 6, 7};
12833 static const GLuint instance_index_data[8] = {0, 1, 2, 3, 4, 5, 6, 7};
12834
12835 std::vector<GLuint> buffer_data;
12836 buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */
12837
12838 GLubyte *ptr = (GLubyte *)&buffer_data[0];
12839
12840 /*
12841 When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on,
12842 So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER
12843 */
12844 if (test_case_index >= 2)
12845 {
12846 buffer.m_buffer = Utils::Buffer::Element;
12847 }
12848 vao.Bind();
12849 buffer.Bind();
12850
12851 vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */,
12852 0 /* stride */, 0 /* offset */);
12853
12854 vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */,
12855 false /* normalized */, 0 /* stride */, (GLvoid *)sizeof(vertex_index_data) /* offset */);
12856 // when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance
12857 // the instancecount is 4, the baseinstance is 2, the divisor should be set 2
12858 bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE ||
12859 test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE);
12860 vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */,
12861 isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */);
12862
12863 memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data));
12864 memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data));
12865
12866 buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr);
12867 }
12868
12869 /** This test should be run with separable programs
12870 *
12871 * @param ignored
12872 *
12873 * @return true
12874 **/
12875 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12876 {
12877 return false;
12878 }
12879
12880 /** Constructor
12881 *
12882 * @param context Test framework context
12883 **/
12884 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context &context)
12885 : VaryingLocationsTest(context, "varying_array_locations",
12886 "Test verifies that input and output locations are respected for arrays")
12887 {
12888 }
12889
12890 /**
12891 *
12892 **/
12893 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type &type,
12894 Utils::ProgramInterface &program_interface,
12895 Utils::VaryingPassthrough &varying_passthrough)
12896 {
12897 const GLuint array_length = 1u;
12898 const GLuint first_in_loc = 0;
12899 const GLuint first_out_loc = 0;
12900 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length, false);
12901 size_t position = 0;
12902
12903 const GLchar *prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12904
12905 const GLchar *prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12906
12907 const GLchar *qual_first_in = "layout (location = first_input_location)";
12908 const GLchar *qual_first_out = "layout (location = first_output_location)";
12909 const GLchar *qual_last_in = "layout (location = last_input_location)";
12910 const GLchar *qual_last_out = "layout (location = last_output_location)";
12911
12912 Utils::ShaderInterface &si = program_interface.GetShaderInterface(stage);
12913 const GLuint type_size = type.GetSize();
12914
12915 std::string first_in_name = "PREFIXfirst";
12916 std::string first_out_name = "PREFIXfirst";
12917 std::string last_in_name = "PREFIXlast";
12918 std::string last_out_name = "PREFIXlast";
12919
12920 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12921 position = 0;
12922 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12923 position = 0;
12924 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12925 position = 0;
12926 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12927
12928 if (Utils::Shader::FRAGMENT == stage)
12929 {
12930 qual_first_in = "layout (location = first_input_location) flat";
12931 qual_last_in = "layout (location = last_input_location) flat";
12932 }
12933 if (Utils::Shader::GEOMETRY == stage)
12934 {
12935 qual_first_out = "layout (location = first_output_location) flat";
12936 qual_last_out = "layout (location = last_output_location) flat";
12937 }
12938
12939 Utils::Variable *first_in =
12940 si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12941 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12942 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12943 (GLvoid *)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12944
12945 Utils::Variable *last_in =
12946 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12947 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12948 array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12949 (GLvoid *)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12950
12951 if (Utils::Shader::FRAGMENT != stage)
12952 {
12953 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length, false);
12954
12955 Utils::Variable *first_out =
12956 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12957 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12958 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12959 (GLvoid *)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12960
12961 Utils::Variable *last_out =
12962 si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12963 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12964 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12965 (GLvoid *)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12966
12967 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12968
12969 varying_passthrough.Add(stage, first_in, first_out);
12970 varying_passthrough.Add(stage, last_in, last_out);
12971 }
12972 else
12973 {
12974 /* No outputs for fragment shader, so last_output_location can be 0 */
12975 si.m_globals = prepareGlobals(last_in_loc, 0);
12976 }
12977 }
12978
12979 /** Constructor
12980 *
12981 * @param context Test framework context
12982 **/
12983 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context &context)
12984 : TextureTestBase(context, "varying_structure_locations",
12985 "Test verifies that locations are respected when structures are used as in and out ")
12986 {
12987 }
12988
12989 /** Prepare code snippet that will pass in variables to out variables
12990 *
12991 * @param ignored
12992 * @param varying_passthrough Collection of connections between in and out variables
12993 * @param stage Shader stage
12994 *
12995 * @return Code that pass in variables to next stage
12996 **/
12997 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */,
12998 Utils::VaryingPassthrough &varying_passthrough,
12999 Utils::Shader::STAGES stage)
13000 {
13001 std::string result;
13002
13003 if (Utils::Shader::VERTEX != stage)
13004 {
13005 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13006 }
13007 else
13008 {
13009 result = " vs_tcs_output[0].single = vs_in_single[0];\n"
13010 " vs_tcs_output[0].array[0] = vs_in_array[0];\n";
13011 }
13012
13013 return result;
13014 }
13015
13016 /** Get interface of program
13017 *
13018 * @param test_case_index Test case
13019 * @param program_interface Interface of program
13020 * @param varying_passthrough Collection of connections between in and out variables
13021 **/
13022 void VaryingStructureLocationsTest::getProgramInterface(GLuint test_case_index,
13023 Utils::ProgramInterface &program_interface,
13024 Utils::VaryingPassthrough &varying_passthrough)
13025 {
13026 Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13027 const Utils::Type type = getType(test_case_index);
13028
13029 /* Prepare data */
13030 // We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct
13031 m_single_data = type.GenerateDataPacked();
13032 m_array_data = type.GenerateDataPacked();
13033
13034 m_data.resize(m_single_data.size() + m_array_data.size());
13035 GLubyte *ptr = (GLubyte *)&m_data[0];
13036 memcpy(ptr, &m_single_data[0], m_single_data.size());
13037 memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size());
13038
13039 Utils::Interface *structure = program_interface.Structure("Data");
13040
13041 structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */,
13042 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */);
13043
13044 // the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed.
13045 structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type,
13046 false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */);
13047
13048 si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */,
13049 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)&m_single_data[0] /* data */,
13050 m_single_data.size() /* data_size */);
13051
13052 si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */,
13053 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */,
13054 (GLvoid *)&m_array_data[0] /* data */, m_array_data.size() /* data_size */);
13055
13056 si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure,
13057 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)&m_data[0] /* data */,
13058 m_data.size() /* data_size */);
13059
13060 program_interface.CloneVertexInterface(varying_passthrough);
13061 }
13062
13063 /** Get type name
13064 *
13065 * @param test_case_index Index of test case
13066 *
13067 * @return Name of type test in test_case_index
13068 **/
13069 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index)
13070 {
13071 return getTypeName(test_case_index);
13072 }
13073
13074 /** Returns number of types to test
13075 *
13076 * @return Number of types, 34
13077 **/
13078 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber()
13079 {
13080 return getTypesNumber();
13081 }
13082
13083 /** Selects if "compute" stage is relevant for test
13084 *
13085 * @param ignored
13086 *
13087 * @return false
13088 **/
13089 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13090 {
13091 return false;
13092 }
13093
13094 /** This test should be run with separable programs
13095 *
13096 * @param ignored
13097 *
13098 * @return true
13099 **/
13100 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13101 {
13102 return false;
13103 }
13104
13105 /** Constructor
13106 *
13107 * @param context Test context
13108 * @param test_name Name of test
13109 * @param test_description Description of test
13110 **/
13111 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context &context)
13112 : NegativeTestBase(context, "varying_structure_member_location",
13113 "Test verifies that compiler does not allow location qualifier on member of structure")
13114 {
13115 }
13116
13117 /** Source for given test case and stage
13118 *
13119 * @param test_case_index Index of test case
13120 * @param stage Shader stage
13121 *
13122 * @return Shader source
13123 **/
13124 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13125 {
13126 static const GLchar *struct_definition = "struct Data {\n"
13127 " vec4 gohan;\n"
13128 #if DEBUG_NEG_REMOVE_ERROR
13129 " /* layout (location = 4) */ vec4 goten;\n"
13130 #else
13131 " layout (location = 4) vec4 goten;\n"
13132 #endif /* DEBUG_NEG_REMOVE_ERROR */
13133 "};\n";
13134 static const GLchar *input_use = " result += data.gohan + data.goten;\n";
13135 static const GLchar *input_var = "in Data dataARRAY;\n";
13136 static const GLchar *output_var = "out Data dataARRAY;\n";
13137 static const GLchar *output_use = " dataINDEX.gohan = result / 2;\n"
13138 " dataINDEX.goten = result / 4 - dataINDEX.gohan;\n";
13139 static const GLchar *fs = "#version 430 core\n"
13140 "#extension GL_ARB_enhanced_layouts : require\n"
13141 "\n"
13142 "in vec4 gs_fs;\n"
13143 "out vec4 fs_out;\n"
13144 "\n"
13145 "void main()\n"
13146 "{\n"
13147 " fs_out = gs_fs;\n"
13148 "}\n"
13149 "\n";
13150 static const GLchar *fs_tested = "#version 430 core\n"
13151 "#extension GL_ARB_enhanced_layouts : require\n"
13152 "\n"
13153 "STRUCT_DEFINITION"
13154 "\n"
13155 "VARIABLE_DEFINITION"
13156 "\n"
13157 "in vec4 gs_fs;\n"
13158 "out vec4 fs_out;\n"
13159 "\n"
13160 "void main()\n"
13161 "{\n"
13162 " vec4 result = gs_fs;\n"
13163 "\n"
13164 "VARIABLE_USE"
13165 "\n"
13166 " fs_out += result;\n"
13167 "}\n"
13168 "\n";
13169 static const GLchar *gs = "#version 430 core\n"
13170 "#extension GL_ARB_enhanced_layouts : require\n"
13171 "\n"
13172 "layout(points) in;\n"
13173 "layout(triangle_strip, max_vertices = 4) out;\n"
13174 "\n"
13175 "in vec4 tes_gs[];\n"
13176 "out vec4 gs_fs;\n"
13177 "\n"
13178 "void main()\n"
13179 "{\n"
13180 " gs_fs = tes_gs[0];\n"
13181 " gl_Position = vec4(-1, -1, 0, 1);\n"
13182 " EmitVertex();\n"
13183 " gs_fs = tes_gs[0];\n"
13184 " gl_Position = vec4(-1, 1, 0, 1);\n"
13185 " EmitVertex();\n"
13186 " gs_fs = tes_gs[0];\n"
13187 " gl_Position = vec4(1, -1, 0, 1);\n"
13188 " EmitVertex();\n"
13189 " gs_fs = tes_gs[0];\n"
13190 " gl_Position = vec4(1, 1, 0, 1);\n"
13191 " EmitVertex();\n"
13192 "}\n"
13193 "\n";
13194 static const GLchar *gs_tested = "#version 430 core\n"
13195 "#extension GL_ARB_enhanced_layouts : require\n"
13196 "\n"
13197 "layout(points) in;\n"
13198 "layout(triangle_strip, max_vertices = 4) out;\n"
13199 "\n"
13200 "STRUCT_DEFINITION"
13201 "\n"
13202 "VARIABLE_DEFINITION"
13203 "\n"
13204 "in vec4 tes_gs[];\n"
13205 "out vec4 gs_fs;\n"
13206 "\n"
13207 "void main()\n"
13208 "{\n"
13209 " vec4 result = tes_gs[0];\n"
13210 "\n"
13211 "VARIABLE_USE"
13212 "\n"
13213 " gs_fs = result;\n"
13214 " gl_Position = vec4(-1, -1, 0, 1);\n"
13215 " EmitVertex();\n"
13216 " gs_fs = result;\n"
13217 " gl_Position = vec4(-1, 1, 0, 1);\n"
13218 " EmitVertex();\n"
13219 " gs_fs = result;\n"
13220 " gl_Position = vec4(1, -1, 0, 1);\n"
13221 " EmitVertex();\n"
13222 " gs_fs = result;\n"
13223 " gl_Position = vec4(1, 1, 0, 1);\n"
13224 " EmitVertex();\n"
13225 "}\n"
13226 "\n";
13227 static const GLchar *tcs = "#version 430 core\n"
13228 "#extension GL_ARB_enhanced_layouts : require\n"
13229 "\n"
13230 "layout(vertices = 1) out;\n"
13231 "\n"
13232 "in vec4 vs_tcs[];\n"
13233 "out vec4 tcs_tes[];\n"
13234 "\n"
13235 "void main()\n"
13236 "{\n"
13237 "\n"
13238 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13239 "\n"
13240 " gl_TessLevelOuter[0] = 1.0;\n"
13241 " gl_TessLevelOuter[1] = 1.0;\n"
13242 " gl_TessLevelOuter[2] = 1.0;\n"
13243 " gl_TessLevelOuter[3] = 1.0;\n"
13244 " gl_TessLevelInner[0] = 1.0;\n"
13245 " gl_TessLevelInner[1] = 1.0;\n"
13246 "}\n"
13247 "\n";
13248 static const GLchar *tcs_tested = "#version 430 core\n"
13249 "#extension GL_ARB_enhanced_layouts : require\n"
13250 "\n"
13251 "layout(vertices = 1) out;\n"
13252 "\n"
13253 "STRUCT_DEFINITION"
13254 "\n"
13255 "VARIABLE_DEFINITION"
13256 "\n"
13257 "in vec4 vs_tcs[];\n"
13258 "out vec4 tcs_tes[];\n"
13259 "\n"
13260 "void main()\n"
13261 "{\n"
13262 " vec4 result = vs_tcs[gl_InvocationID];\n"
13263 "\n"
13264 "VARIABLE_USE"
13265 "\n"
13266 " tcs_tes[gl_InvocationID] = result;\n"
13267 "\n"
13268 " gl_TessLevelOuter[0] = 1.0;\n"
13269 " gl_TessLevelOuter[1] = 1.0;\n"
13270 " gl_TessLevelOuter[2] = 1.0;\n"
13271 " gl_TessLevelOuter[3] = 1.0;\n"
13272 " gl_TessLevelInner[0] = 1.0;\n"
13273 " gl_TessLevelInner[1] = 1.0;\n"
13274 "}\n"
13275 "\n";
13276 static const GLchar *tes = "#version 430 core\n"
13277 "#extension GL_ARB_enhanced_layouts : require\n"
13278 "\n"
13279 "layout(isolines, point_mode) in;\n"
13280 "\n"
13281 "in vec4 tcs_tes[];\n"
13282 "out vec4 tes_gs;\n"
13283 "\n"
13284 "void main()\n"
13285 "{\n"
13286 " tes_gs = tcs_tes[0];\n"
13287 "}\n"
13288 "\n";
13289 static const GLchar *tes_tested = "#version 430 core\n"
13290 "#extension GL_ARB_enhanced_layouts : require\n"
13291 "\n"
13292 "layout(isolines, point_mode) in;\n"
13293 "\n"
13294 "STRUCT_DEFINITION"
13295 "\n"
13296 "VARIABLE_DEFINITION"
13297 "\n"
13298 "in vec4 tcs_tes[];\n"
13299 "out vec4 tes_gs;\n"
13300 "\n"
13301 "void main()\n"
13302 "{\n"
13303 " vec4 result = tcs_tes[0];\n"
13304 "\n"
13305 "VARIABLE_USE"
13306 "\n"
13307 " tes_gs += result;\n"
13308 "}\n"
13309 "\n";
13310 static const GLchar *vs = "#version 430 core\n"
13311 "#extension GL_ARB_enhanced_layouts : require\n"
13312 "\n"
13313 "in vec4 in_vs;\n"
13314 "out vec4 vs_tcs;\n"
13315 "\n"
13316 "void main()\n"
13317 "{\n"
13318 " vs_tcs = in_vs;\n"
13319 "}\n"
13320 "\n";
13321 static const GLchar *vs_tested = "#version 430 core\n"
13322 "#extension GL_ARB_enhanced_layouts : require\n"
13323 "\n"
13324 "STRUCT_DEFINITION"
13325 "\n"
13326 "VARIABLE_DEFINITION"
13327 "\n"
13328 "in vec4 in_vs;\n"
13329 "out vec4 vs_tcs;\n"
13330 "\n"
13331 "void main()\n"
13332 "{\n"
13333 " vec4 result = in_vs;\n"
13334 "\n"
13335 "VARIABLE_USE"
13336 "\n"
13337 " vs_tcs += result;\n"
13338 "}\n"
13339 "\n";
13340
13341 std::string source;
13342 testCase &test_case = m_test_cases[test_case_index];
13343 const GLchar *var_definition = input_var;
13344 const GLchar *var_use = Utils::Shader::VERTEX == test_case.m_stage ? input_use : "\n";
13345 const GLchar *array = "";
13346 const GLchar *index = "";
13347
13348 if (!test_case.m_is_input)
13349 {
13350 var_definition = output_var;
13351 var_use = output_use;
13352 }
13353
13354 if (test_case.m_stage == stage)
13355 {
13356 size_t position = 0;
13357 size_t temp = 0;
13358
13359 switch (stage)
13360 {
13361 case Utils::Shader::FRAGMENT:
13362 source = fs_tested;
13363 break;
13364 case Utils::Shader::GEOMETRY:
13365 source = gs_tested;
13366 array = test_case.m_is_input ? "[]" : "";
13367 index = test_case.m_is_input ? "[0]" : "";
13368 break;
13369 case Utils::Shader::TESS_CTRL:
13370 source = tcs_tested;
13371 array = "[]";
13372 index = "[gl_InvocationID]";
13373 break;
13374 case Utils::Shader::TESS_EVAL:
13375 source = tes_tested;
13376 array = test_case.m_is_input ? "[]" : "";
13377 index = test_case.m_is_input ? "[0]" : "";
13378 break;
13379 case Utils::Shader::VERTEX:
13380 source = vs_tested;
13381 break;
13382 default:
13383 TCU_FAIL("Invalid enum");
13384 }
13385
13386 Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source);
13387 temp = position;
13388 Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source);
13389 position = temp;
13390 Utils::replaceToken("ARRAY", position, array, source);
13391 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13392
13393 Utils::replaceAllTokens("INDEX", index, source);
13394 }
13395 else
13396 {
13397 switch (stage)
13398 {
13399 case Utils::Shader::FRAGMENT:
13400 source = fs;
13401 break;
13402 case Utils::Shader::GEOMETRY:
13403 source = gs;
13404 break;
13405 case Utils::Shader::TESS_CTRL:
13406 source = tcs;
13407 break;
13408 case Utils::Shader::TESS_EVAL:
13409 source = tes;
13410 break;
13411 case Utils::Shader::VERTEX:
13412 source = vs;
13413 break;
13414 default:
13415 TCU_FAIL("Invalid enum");
13416 }
13417 }
13418
13419 return source;
13420 }
13421
13422 /** Get description of test case
13423 *
13424 * @param test_case_index Index of test case
13425 *
13426 * @return Test case description
13427 **/
13428 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index)
13429 {
13430 std::stringstream stream;
13431 testCase &test_case = m_test_cases[test_case_index];
13432
13433 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13434
13435 if (true == test_case.m_is_input)
13436 {
13437 stream << "input";
13438 }
13439 else
13440 {
13441 stream << "output";
13442 }
13443
13444 return stream.str();
13445 }
13446
13447 /** Get number of test cases
13448 *
13449 * @return Number of test cases
13450 **/
13451 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber()
13452 {
13453 return static_cast<GLuint>(m_test_cases.size());
13454 }
13455
13456 /** Selects if "compute" stage is relevant for test
13457 *
13458 * @param ignored
13459 *
13460 * @return false
13461 **/
13462 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */)
13463 {
13464 return false;
13465 }
13466
13467 /** Prepare all test cases
13468 *
13469 **/
13470 void VaryingStructureMemberLocationTest::testInit()
13471 {
13472 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13473 {
13474 if (Utils::Shader::COMPUTE == stage)
13475 {
13476 continue;
13477 }
13478
13479 testCase test_case_in = {true, (Utils::Shader::STAGES)stage};
13480 testCase test_case_out = {false, (Utils::Shader::STAGES)stage};
13481
13482 /* It is a compile-time error to declare a struct as a VS input */
13483 if (Utils::Shader::VERTEX != stage)
13484 {
13485 m_test_cases.push_back(test_case_in);
13486 }
13487
13488 if (Utils::Shader::FRAGMENT != stage)
13489 {
13490 m_test_cases.push_back(test_case_out);
13491 }
13492 }
13493 }
13494
13495 /** Constructor
13496 *
13497 * @param context Test framework context
13498 **/
13499 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context &context)
13500 : TextureTestBase(context, "varying_block_locations",
13501 "Test verifies that locations are respected when blocks are used as in and out ")
13502 {
13503 }
13504
13505 /** Prepare code snippet that will pass in variables to out variables
13506 *
13507 * @param ignored
13508 * @param varying_passthrough Collection of connections between in and out variables
13509 * @param stage Shader stage
13510 *
13511 * @return Code that pass in variables to next stage
13512 **/
13513 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */,
13514 Utils::VaryingPassthrough &varying_passthrough,
13515 Utils::Shader::STAGES stage)
13516 {
13517 std::string result;
13518
13519 if (Utils::Shader::VERTEX != stage)
13520 {
13521 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13522 }
13523 else
13524 {
13525 result = "vs_tcs_block.third = vs_in_third;\n"
13526 " vs_tcs_block.fourth = vs_in_fourth;\n"
13527 " vs_tcs_block.fifth = vs_in_fifth;\n";
13528 }
13529
13530 return result;
13531 }
13532
13533 /** Get interface of program
13534 *
13535 * @param ignored
13536 * @param program_interface Interface of program
13537 * @param varying_passthrough Collection of connections between in and out variables
13538 **/
13539 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */,
13540 Utils::ProgramInterface &program_interface,
13541 Utils::VaryingPassthrough &varying_passthrough)
13542 {
13543 Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13544 const Utils::Type vec4 = Utils::Type::vec4;
13545
13546 /* Prepare data */
13547 m_third_data = vec4.GenerateData();
13548 m_fourth_data = vec4.GenerateData();
13549 m_fifth_data = vec4.GenerateData();
13550
13551 /* Memory layout is different from location layout */
13552 const GLuint fifth_offset = 0u;
13553 const GLuint third_offset = static_cast<GLuint>(fifth_offset + m_fifth_data.size());
13554 const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size());
13555
13556 m_data.resize(fourth_offset + m_fourth_data.size());
13557 GLubyte *ptr = (GLubyte *)&m_data[0];
13558 memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size());
13559 memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size());
13560 memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size());
13561
13562 Utils::Interface *block = program_interface.Block("vs_tcs_Block");
13563
13564 block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */,
13565 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */);
13566
13567 block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4,
13568 false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */);
13569
13570 block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */,
13571 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */);
13572
13573 si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block,
13574 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)&m_data[0] /* data */,
13575 m_data.size() /* data_size */);
13576
13577 si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */,
13578 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */,
13579 (GLvoid *)&m_third_data[0] /* data */, m_third_data.size() /* data_size */);
13580
13581 si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */,
13582 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */,
13583 (GLvoid *)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */);
13584
13585 si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */,
13586 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */,
13587 (GLvoid *)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */);
13588
13589 program_interface.CloneVertexInterface(varying_passthrough);
13590 }
13591
13592 /** Selects if "compute" stage is relevant for test
13593 *
13594 * @param ignored
13595 *
13596 * @return false
13597 **/
13598 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13599 {
13600 return false;
13601 }
13602
13603 /** This test should be run with separable programs
13604 *
13605 * @param ignored
13606 *
13607 * @return true
13608 **/
13609 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13610 {
13611 return false;
13612 }
13613
13614 /** Constructor
13615 *
13616 * @param context Test framework context
13617 **/
13618 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context &context)
13619 : NegativeTestBase(
13620 context, "varying_block_member_locations",
13621 "Test verifies that compilation error is reported when not all members of block are qualified with location")
13622 {
13623 }
13624
13625 /** Source for given test case and stage
13626 *
13627 * @param test_case_index Index of test case
13628 * @param stage Shader stage
13629 *
13630 * @return Shader source
13631 **/
13632 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13633 {
13634 static const GLchar *block_definition_all = "Goku {\n"
13635 " layout (location = 2) vec4 gohan;\n"
13636 " layout (location = 4) vec4 goten;\n"
13637 " layout (location = 6) vec4 chichi;\n"
13638 "} gokuARRAY;\n";
13639 static const GLchar *block_definition_one = "Goku {\n"
13640 " vec4 gohan;\n"
13641 #if DEBUG_NEG_REMOVE_ERROR
13642 " /* layout (location = 4) */ vec4 goten;\n"
13643 #else
13644 " layout (location = 4) vec4 goten;\n"
13645 #endif /* DEBUG_NEG_REMOVE_ERROR */
13646 " vec4 chichi;\n"
13647 "} gokuARRAY;\n";
13648 static const GLchar *input_use = " result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n";
13649 static const GLchar *output_use = " gokuINDEX.gohan = result / 2;\n"
13650 " gokuINDEX.goten = result / 4 - gokuINDEX.gohan;\n"
13651 " gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n";
13652 static const GLchar *fs = "#version 430 core\n"
13653 "#extension GL_ARB_enhanced_layouts : require\n"
13654 "\n"
13655 "in vec4 gs_fs;\n"
13656 "out vec4 fs_out;\n"
13657 "\n"
13658 "void main()\n"
13659 "{\n"
13660 " fs_out = gs_fs;\n"
13661 "}\n"
13662 "\n";
13663 static const GLchar *fs_tested = "#version 430 core\n"
13664 "#extension GL_ARB_enhanced_layouts : require\n"
13665 "\n"
13666 "DIRECTION BLOCK_DEFINITION"
13667 "\n"
13668 "in vec4 gs_fs;\n"
13669 "out vec4 fs_out;\n"
13670 "\n"
13671 "void main()\n"
13672 "{\n"
13673 " vec4 result = gs_fs;\n"
13674 "\n"
13675 "VARIABLE_USE"
13676 "\n"
13677 " fs_out = result;\n"
13678 "}\n"
13679 "\n";
13680 static const GLchar *gs = "#version 430 core\n"
13681 "#extension GL_ARB_enhanced_layouts : require\n"
13682 "\n"
13683 "layout(points) in;\n"
13684 "layout(triangle_strip, max_vertices = 4) out;\n"
13685 "\n"
13686 "in vec4 tes_gs[];\n"
13687 "out vec4 gs_fs;\n"
13688 "\n"
13689 "void main()\n"
13690 "{\n"
13691 " gs_fs = tes_gs[0];\n"
13692 " gl_Position = vec4(-1, -1, 0, 1);\n"
13693 " EmitVertex();\n"
13694 " gs_fs = tes_gs[0];\n"
13695 " gl_Position = vec4(-1, 1, 0, 1);\n"
13696 " EmitVertex();\n"
13697 " gs_fs = tes_gs[0];\n"
13698 " gl_Position = vec4(1, -1, 0, 1);\n"
13699 " EmitVertex();\n"
13700 " gs_fs = tes_gs[0];\n"
13701 " gl_Position = vec4(1, 1, 0, 1);\n"
13702 " EmitVertex();\n"
13703 "}\n"
13704 "\n";
13705 static const GLchar *gs_tested = "#version 430 core\n"
13706 "#extension GL_ARB_enhanced_layouts : require\n"
13707 "\n"
13708 "layout(points) in;\n"
13709 "layout(triangle_strip, max_vertices = 4) out;\n"
13710 "\n"
13711 "DIRECTION BLOCK_DEFINITION"
13712 "\n"
13713 "in vec4 tes_gs[];\n"
13714 "out vec4 gs_fs;\n"
13715 "\n"
13716 "void main()\n"
13717 "{\n"
13718 " vec4 result = tes_gs[0];\n"
13719 "\n"
13720 "VARIABLE_USE"
13721 "\n"
13722 " gs_fs = result;\n"
13723 " gl_Position = vec4(-1, -1, 0, 1);\n"
13724 " EmitVertex();\n"
13725 " gs_fs = result;\n"
13726 " gl_Position = vec4(-1, 1, 0, 1);\n"
13727 " EmitVertex();\n"
13728 " gs_fs = result;\n"
13729 " gl_Position = vec4(1, -1, 0, 1);\n"
13730 " EmitVertex();\n"
13731 " gs_fs = result;\n"
13732 " gl_Position = vec4(1, 1, 0, 1);\n"
13733 " EmitVertex();\n"
13734 "}\n"
13735 "\n";
13736 static const GLchar *tcs = "#version 430 core\n"
13737 "#extension GL_ARB_enhanced_layouts : require\n"
13738 "\n"
13739 "layout(vertices = 1) out;\n"
13740 "\n"
13741 "in vec4 vs_tcs[];\n"
13742 "out vec4 tcs_tes[];\n"
13743 "\n"
13744 "void main()\n"
13745 "{\n"
13746 "\n"
13747 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13748 "\n"
13749 " gl_TessLevelOuter[0] = 1.0;\n"
13750 " gl_TessLevelOuter[1] = 1.0;\n"
13751 " gl_TessLevelOuter[2] = 1.0;\n"
13752 " gl_TessLevelOuter[3] = 1.0;\n"
13753 " gl_TessLevelInner[0] = 1.0;\n"
13754 " gl_TessLevelInner[1] = 1.0;\n"
13755 "}\n"
13756 "\n";
13757 static const GLchar *tcs_tested = "#version 430 core\n"
13758 "#extension GL_ARB_enhanced_layouts : require\n"
13759 "\n"
13760 "layout(vertices = 1) out;\n"
13761 "\n"
13762 "DIRECTION BLOCK_DEFINITION"
13763 "\n"
13764 "in vec4 vs_tcs[];\n"
13765 "out vec4 tcs_tes[];\n"
13766 "\n"
13767 "void main()\n"
13768 "{\n"
13769 " vec4 result = vs_tcs[gl_InvocationID];\n"
13770 "\n"
13771 "VARIABLE_USE"
13772 "\n"
13773 " tcs_tes[gl_InvocationID] = result;\n"
13774 "\n"
13775 " gl_TessLevelOuter[0] = 1.0;\n"
13776 " gl_TessLevelOuter[1] = 1.0;\n"
13777 " gl_TessLevelOuter[2] = 1.0;\n"
13778 " gl_TessLevelOuter[3] = 1.0;\n"
13779 " gl_TessLevelInner[0] = 1.0;\n"
13780 " gl_TessLevelInner[1] = 1.0;\n"
13781 "}\n"
13782 "\n";
13783 static const GLchar *tes = "#version 430 core\n"
13784 "#extension GL_ARB_enhanced_layouts : require\n"
13785 "\n"
13786 "layout(isolines, point_mode) in;\n"
13787 "\n"
13788 "in vec4 tcs_tes[];\n"
13789 "out vec4 tes_gs;\n"
13790 "\n"
13791 "void main()\n"
13792 "{\n"
13793 " tes_gs = tcs_tes[0];\n"
13794 "}\n"
13795 "\n";
13796 static const GLchar *tes_tested = "#version 430 core\n"
13797 "#extension GL_ARB_enhanced_layouts : require\n"
13798 "\n"
13799 "layout(isolines, point_mode) in;\n"
13800 "\n"
13801 "DIRECTION BLOCK_DEFINITION"
13802 "\n"
13803 "in vec4 tcs_tes[];\n"
13804 "out vec4 tes_gs;\n"
13805 "\n"
13806 "void main()\n"
13807 "{\n"
13808 " vec4 result = tcs_tes[0];\n"
13809 "\n"
13810 "VARIABLE_USE"
13811 "\n"
13812 " tes_gs = result;\n"
13813 "}\n"
13814 "\n";
13815 static const GLchar *vs = "#version 430 core\n"
13816 "#extension GL_ARB_enhanced_layouts : require\n"
13817 "\n"
13818 "in vec4 in_vs;\n"
13819 "out vec4 vs_tcs;\n"
13820 "\n"
13821 "void main()\n"
13822 "{\n"
13823 " vs_tcs = in_vs;\n"
13824 "}\n"
13825 "\n";
13826 static const GLchar *vs_tested = "#version 430 core\n"
13827 "#extension GL_ARB_enhanced_layouts : require\n"
13828 "\n"
13829 "DIRECTION BLOCK_DEFINITION"
13830 "\n"
13831 "in vec4 in_vs;\n"
13832 "out vec4 vs_tcs;\n"
13833 "\n"
13834 "void main()\n"
13835 "{\n"
13836 " vec4 result = in_vs;\n"
13837 "\n"
13838 "VARIABLE_USE"
13839 "\n"
13840 " vs_tcs = result;\n"
13841 "}\n"
13842 "\n";
13843
13844 const GLchar *array = "";
13845 const GLchar *direction = "in";
13846 const GLchar *index = "";
13847 std::string source;
13848 testCase &test_case = m_test_cases[test_case_index];
13849 const GLchar *var_use = Utils::Shader::VERTEX == test_case.m_stage ? input_use : "\n";
13850 const GLchar *definition = test_case.m_qualify_all ? block_definition_all : block_definition_one;
13851
13852 if (!test_case.m_is_input)
13853 {
13854 direction = "out";
13855 var_use = output_use;
13856 }
13857
13858 if (test_case.m_stage == stage)
13859 {
13860 size_t position = 0;
13861 size_t temp = 0;
13862
13863 switch (stage)
13864 {
13865 case Utils::Shader::FRAGMENT:
13866 source = fs_tested;
13867 break;
13868 case Utils::Shader::GEOMETRY:
13869 source = gs_tested;
13870 array = test_case.m_is_input ? "[]" : "";
13871 index = test_case.m_is_input ? "[0]" : "";
13872 break;
13873 case Utils::Shader::TESS_CTRL:
13874 source = tcs_tested;
13875 array = "[]";
13876 index = "[gl_InvocationID]";
13877 break;
13878 case Utils::Shader::TESS_EVAL:
13879 source = tes_tested;
13880 array = test_case.m_is_input ? "[]" : "";
13881 index = test_case.m_is_input ? "[0]" : "";
13882 break;
13883 case Utils::Shader::VERTEX:
13884 source = vs_tested;
13885 break;
13886 default:
13887 TCU_FAIL("Invalid enum");
13888 }
13889
13890 Utils::replaceToken("DIRECTION", position, direction, source);
13891 temp = position;
13892 Utils::replaceToken("BLOCK_DEFINITION", position, definition, source);
13893 position = temp;
13894 Utils::replaceToken("ARRAY", position, array, source);
13895 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13896
13897 Utils::replaceAllTokens("INDEX", index, source);
13898 }
13899 else
13900 {
13901 switch (stage)
13902 {
13903 case Utils::Shader::FRAGMENT:
13904 source = fs;
13905 break;
13906 case Utils::Shader::GEOMETRY:
13907 source = gs;
13908 break;
13909 case Utils::Shader::TESS_CTRL:
13910 source = tcs;
13911 break;
13912 case Utils::Shader::TESS_EVAL:
13913 source = tes;
13914 break;
13915 case Utils::Shader::VERTEX:
13916 source = vs;
13917 break;
13918 default:
13919 TCU_FAIL("Invalid enum");
13920 }
13921 }
13922
13923 return source;
13924 }
13925
13926 /** Get description of test case
13927 *
13928 * @param test_case_index Index of test case
13929 *
13930 * @return Test case description
13931 **/
13932 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index)
13933 {
13934 std::stringstream stream;
13935 testCase &test_case = m_test_cases[test_case_index];
13936
13937 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13938
13939 if (true == test_case.m_is_input)
13940 {
13941 stream << "input";
13942 }
13943 else
13944 {
13945 stream << "output";
13946 }
13947
13948 if (true == test_case.m_qualify_all)
13949 {
13950 stream << ", all members qualified";
13951 }
13952 else
13953 {
13954 stream << ", not all members qualified";
13955 }
13956
13957 return stream.str();
13958 }
13959
13960 /** Get number of test cases
13961 *
13962 * @return Number of test cases
13963 **/
13964 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber()
13965 {
13966 return static_cast<GLuint>(m_test_cases.size());
13967 }
13968
13969 /** Selects if "compute" stage is relevant for test
13970 *
13971 * @param ignored
13972 *
13973 * @return false
13974 **/
13975 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13976 {
13977 return false;
13978 }
13979
13980 /** Selects if compilation failure is expected result
13981 *
13982 * @param test_case_index Index of test case
13983 *
13984 * @return false when all members are qualified, true otherwise
13985 **/
13986 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index)
13987 {
13988 return (true != m_test_cases[test_case_index].m_qualify_all);
13989 }
13990
13991 /** Prepare all test cases
13992 *
13993 **/
13994 void VaryingBlockMemberLocationsTest::testInit()
13995 {
13996 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13997 {
13998 if (Utils::Shader::COMPUTE == stage)
13999 {
14000 continue;
14001 }
14002
14003 testCase test_case_in_all = {true, true, (Utils::Shader::STAGES)stage};
14004 testCase test_case_in_one = {true, false, (Utils::Shader::STAGES)stage};
14005 testCase test_case_out_all = {false, true, (Utils::Shader::STAGES)stage};
14006 testCase test_case_out_one = {false, false, (Utils::Shader::STAGES)stage};
14007
14008 if (Utils::Shader::VERTEX != stage)
14009 {
14010 m_test_cases.push_back(test_case_in_all);
14011 m_test_cases.push_back(test_case_in_one);
14012 }
14013
14014 if (Utils::Shader::FRAGMENT != stage)
14015 {
14016 m_test_cases.push_back(test_case_out_all);
14017 m_test_cases.push_back(test_case_out_one);
14018 }
14019 }
14020 }
14021
14022 /** Constructor
14023 *
14024 * @param context Test framework context
14025 **/
14026 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context &context)
14027 : NegativeTestBase(
14028 context, "varying_block_automatic_member_locations",
14029 "Test verifies that compiler assigns subsequent locations to block members, even if this causes errors")
14030 {
14031 }
14032
14033 /** Source for given test case and stage
14034 *
14035 * @param test_case_index Index of test case
14036 * @param stage Shader stage
14037 *
14038 * @return Shader source
14039 **/
14040 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint test_case_index,
14041 Utils::Shader::STAGES stage)
14042 {
14043 static const GLchar *block_definition = "layout (location = 2) DIRECTION DBZ {\n"
14044 " vec4 goku;\n"
14045 " vec4 gohan[4];\n"
14046 " vec4 goten;\n"
14047 #if DEBUG_NEG_REMOVE_ERROR
14048 " /* layout (location = 1) */ vec4 chichi;\n"
14049 #else
14050 " layout (location = 1) vec4 chichi;\n"
14051 #endif /* DEBUG_NEG_REMOVE_ERROR */
14052 " vec4 pan;\n"
14053 "} dbzARRAY;\n";
14054 static const GLchar *input_use = " result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + "
14055 "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + "
14056 "dbzINDEX.pan;\n";
14057 static const GLchar *output_use = " dbzINDEX.goku = result;\n"
14058 " dbzINDEX.gohan[0] = result / 2;\n"
14059 " dbzINDEX.gohan[1] = result / 2.25;\n"
14060 " dbzINDEX.gohan[2] = result / 2.5;\n"
14061 " dbzINDEX.gohan[3] = result / 2.75;\n"
14062 " dbzINDEX.goten = result / 4 - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - "
14063 "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n"
14064 " dbzINDEX.chichi = result / 8 - dbzINDEX.goten;\n"
14065 " dbzINDEX.pan = result / 16 - dbzINDEX.chichi;\n";
14066 static const GLchar *fs = "#version 430 core\n"
14067 "#extension GL_ARB_enhanced_layouts : require\n"
14068 "\n"
14069 "in vec4 gs_fs;\n"
14070 "out vec4 fs_out;\n"
14071 "\n"
14072 "void main()\n"
14073 "{\n"
14074 " fs_out = gs_fs;\n"
14075 "}\n"
14076 "\n";
14077 static const GLchar *fs_tested = "#version 430 core\n"
14078 "#extension GL_ARB_enhanced_layouts : require\n"
14079 "\n"
14080 "BLOCK_DEFINITION"
14081 "\n"
14082 "in vec4 gs_fs;\n"
14083 "out vec4 fs_out;\n"
14084 "\n"
14085 "void main()\n"
14086 "{\n"
14087 " vec4 result = gs_fs;\n"
14088 "\n"
14089 "VARIABLE_USE"
14090 "\n"
14091 " fs_out += result;\n"
14092 "}\n"
14093 "\n";
14094 static const GLchar *gs = "#version 430 core\n"
14095 "#extension GL_ARB_enhanced_layouts : require\n"
14096 "\n"
14097 "layout(points) in;\n"
14098 "layout(triangle_strip, max_vertices = 4) out;\n"
14099 "\n"
14100 "in vec4 tes_gs[];\n"
14101 "out vec4 gs_fs;\n"
14102 "\n"
14103 "void main()\n"
14104 "{\n"
14105 " gs_fs = tes_gs[0];\n"
14106 " gl_Position = vec4(-1, -1, 0, 1);\n"
14107 " EmitVertex();\n"
14108 " gs_fs = tes_gs[0];\n"
14109 " gl_Position = vec4(-1, 1, 0, 1);\n"
14110 " EmitVertex();\n"
14111 " gs_fs = tes_gs[0];\n"
14112 " gl_Position = vec4(1, -1, 0, 1);\n"
14113 " EmitVertex();\n"
14114 " gs_fs = tes_gs[0];\n"
14115 " gl_Position = vec4(1, 1, 0, 1);\n"
14116 " EmitVertex();\n"
14117 "}\n"
14118 "\n";
14119 static const GLchar *gs_tested = "#version 430 core\n"
14120 "#extension GL_ARB_enhanced_layouts : require\n"
14121 "\n"
14122 "layout(points) in;\n"
14123 "layout(triangle_strip, max_vertices = 4) out;\n"
14124 "\n"
14125 "BLOCK_DEFINITION"
14126 "\n"
14127 "in vec4 tes_gs[];\n"
14128 "out vec4 gs_fs;\n"
14129 "\n"
14130 "void main()\n"
14131 "{\n"
14132 " vec4 result = tes_gs[0];\n"
14133 "\n"
14134 "VARIABLE_USE"
14135 "\n"
14136 " gs_fs = result;\n"
14137 " gl_Position = vec4(-1, -1, 0, 1);\n"
14138 " EmitVertex();\n"
14139 " gs_fs = result;\n"
14140 " gl_Position = vec4(-1, 1, 0, 1);\n"
14141 " EmitVertex();\n"
14142 " gs_fs = result;\n"
14143 " gl_Position = vec4(1, -1, 0, 1);\n"
14144 " EmitVertex();\n"
14145 " gs_fs = result;\n"
14146 " gl_Position = vec4(1, 1, 0, 1);\n"
14147 " EmitVertex();\n"
14148 "}\n"
14149 "\n";
14150 static const GLchar *tcs = "#version 430 core\n"
14151 "#extension GL_ARB_enhanced_layouts : require\n"
14152 "\n"
14153 "layout(vertices = 1) out;\n"
14154 "\n"
14155 "in vec4 vs_tcs[];\n"
14156 "out vec4 tcs_tes[];\n"
14157 "\n"
14158 "void main()\n"
14159 "{\n"
14160 "\n"
14161 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14162 "\n"
14163 " gl_TessLevelOuter[0] = 1.0;\n"
14164 " gl_TessLevelOuter[1] = 1.0;\n"
14165 " gl_TessLevelOuter[2] = 1.0;\n"
14166 " gl_TessLevelOuter[3] = 1.0;\n"
14167 " gl_TessLevelInner[0] = 1.0;\n"
14168 " gl_TessLevelInner[1] = 1.0;\n"
14169 "}\n"
14170 "\n";
14171 static const GLchar *tcs_tested = "#version 430 core\n"
14172 "#extension GL_ARB_enhanced_layouts : require\n"
14173 "\n"
14174 "layout(vertices = 1) out;\n"
14175 "\n"
14176 "BLOCK_DEFINITION"
14177 "\n"
14178 "in vec4 vs_tcs[];\n"
14179 "out vec4 tcs_tes[];\n"
14180 "\n"
14181 "void main()\n"
14182 "{\n"
14183 " vec4 result = vs_tcs[gl_InvocationID];\n"
14184 "\n"
14185 "VARIABLE_USE"
14186 "\n"
14187 " tcs_tes[gl_InvocationID] = result;\n"
14188 "\n"
14189 " gl_TessLevelOuter[0] = 1.0;\n"
14190 " gl_TessLevelOuter[1] = 1.0;\n"
14191 " gl_TessLevelOuter[2] = 1.0;\n"
14192 " gl_TessLevelOuter[3] = 1.0;\n"
14193 " gl_TessLevelInner[0] = 1.0;\n"
14194 " gl_TessLevelInner[1] = 1.0;\n"
14195 "}\n"
14196 "\n";
14197 static const GLchar *tes = "#version 430 core\n"
14198 "#extension GL_ARB_enhanced_layouts : require\n"
14199 "\n"
14200 "layout(isolines, point_mode) in;\n"
14201 "\n"
14202 "in vec4 tcs_tes[];\n"
14203 "out vec4 tes_gs;\n"
14204 "\n"
14205 "void main()\n"
14206 "{\n"
14207 " tes_gs = tcs_tes[0];\n"
14208 "}\n"
14209 "\n";
14210 static const GLchar *tes_tested = "#version 430 core\n"
14211 "#extension GL_ARB_enhanced_layouts : require\n"
14212 "\n"
14213 "layout(isolines, point_mode) in;\n"
14214 "\n"
14215 "BLOCK_DEFINITION"
14216 "\n"
14217 "in vec4 tcs_tes[];\n"
14218 "out vec4 tes_gs;\n"
14219 "\n"
14220 "void main()\n"
14221 "{\n"
14222 " vec4 result = tcs_tes[0];\n"
14223 "\n"
14224 "VARIABLE_USE"
14225 "\n"
14226 " tes_gs += result;\n"
14227 "}\n"
14228 "\n";
14229 static const GLchar *vs = "#version 430 core\n"
14230 "#extension GL_ARB_enhanced_layouts : require\n"
14231 "\n"
14232 "in vec4 in_vs;\n"
14233 "out vec4 vs_tcs;\n"
14234 "\n"
14235 "void main()\n"
14236 "{\n"
14237 " vs_tcs = in_vs;\n"
14238 "}\n"
14239 "\n";
14240 static const GLchar *vs_tested = "#version 430 core\n"
14241 "#extension GL_ARB_enhanced_layouts : require\n"
14242 "\n"
14243 "BLOCK_DEFINITION"
14244 "\n"
14245 "in vec4 in_vs;\n"
14246 "out vec4 vs_tcs;\n"
14247 "\n"
14248 "void main()\n"
14249 "{\n"
14250 " vec4 result = in_vs;\n"
14251 "\n"
14252 "VARIABLE_USE"
14253 "\n"
14254 " vs_tcs += result;\n"
14255 "}\n"
14256 "\n";
14257
14258 const GLchar *array = "";
14259 const GLchar *direction = "in";
14260 const GLchar *index = "";
14261 std::string source;
14262 testCase &test_case = m_test_cases[test_case_index];
14263 const GLchar *var_use = Utils::Shader::VERTEX == test_case.m_stage ? input_use : "\n";
14264
14265 if (!test_case.m_is_input)
14266 {
14267 direction = "out";
14268 var_use = output_use;
14269 }
14270
14271 if (test_case.m_stage == stage)
14272 {
14273 size_t position = 0;
14274
14275 switch (stage)
14276 {
14277 case Utils::Shader::FRAGMENT:
14278 source = fs_tested;
14279 break;
14280 case Utils::Shader::GEOMETRY:
14281 source = gs_tested;
14282 array = test_case.m_is_input ? "[]" : "";
14283 index = test_case.m_is_input ? "[0]" : "";
14284 break;
14285 case Utils::Shader::TESS_CTRL:
14286 source = tcs_tested;
14287 array = "[]";
14288 index = "[gl_InvocationID]";
14289 break;
14290 case Utils::Shader::TESS_EVAL:
14291 source = tes_tested;
14292 array = test_case.m_is_input ? "[]" : "";
14293 index = test_case.m_is_input ? "[0]" : "";
14294 break;
14295 case Utils::Shader::VERTEX:
14296 source = vs_tested;
14297 break;
14298 default:
14299 TCU_FAIL("Invalid enum");
14300 }
14301
14302 Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source);
14303 position = 0;
14304 Utils::replaceToken("DIRECTION", position, direction, source);
14305 Utils::replaceToken("ARRAY", position, array, source);
14306 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14307
14308 Utils::replaceAllTokens("INDEX", index, source);
14309 }
14310 else
14311 {
14312 switch (stage)
14313 {
14314 case Utils::Shader::FRAGMENT:
14315 source = fs;
14316 break;
14317 case Utils::Shader::GEOMETRY:
14318 source = gs;
14319 break;
14320 case Utils::Shader::TESS_CTRL:
14321 source = tcs;
14322 break;
14323 case Utils::Shader::TESS_EVAL:
14324 source = tes;
14325 break;
14326 case Utils::Shader::VERTEX:
14327 source = vs;
14328 break;
14329 default:
14330 TCU_FAIL("Invalid enum");
14331 }
14332 }
14333
14334 return source;
14335 }
14336
14337 /** Get description of test case
14338 *
14339 * @param test_case_index Index of test case
14340 *
14341 * @return Test case description
14342 **/
14343 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index)
14344 {
14345 std::stringstream stream;
14346 testCase &test_case = m_test_cases[test_case_index];
14347
14348 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
14349
14350 if (true == test_case.m_is_input)
14351 {
14352 stream << "input";
14353 }
14354 else
14355 {
14356 stream << "output";
14357 }
14358
14359 return stream.str();
14360 }
14361
14362 /** Get number of test cases
14363 *
14364 * @return Number of test cases
14365 **/
14366 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber()
14367 {
14368 return static_cast<GLuint>(m_test_cases.size());
14369 }
14370
14371 /** Selects if "compute" stage is relevant for test
14372 *
14373 * @param ignored
14374 *
14375 * @return false
14376 **/
14377 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
14378 {
14379 return false;
14380 }
14381
14382 /** Prepare all test cases
14383 *
14384 **/
14385 void VaryingBlockAutomaticMemberLocationsTest::testInit()
14386 {
14387 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14388 {
14389 if (Utils::Shader::COMPUTE == stage)
14390 {
14391 continue;
14392 }
14393
14394 testCase test_case_in = {true, (Utils::Shader::STAGES)stage};
14395 testCase test_case_out = {false, (Utils::Shader::STAGES)stage};
14396
14397 if (Utils::Shader::VERTEX != stage)
14398 {
14399 m_test_cases.push_back(test_case_in);
14400 }
14401
14402 if (Utils::Shader::FRAGMENT != stage)
14403 {
14404 m_test_cases.push_back(test_case_out);
14405 }
14406 }
14407 }
14408
14409 /** Constructor
14410 *
14411 * @param context Test framework context
14412 **/
14413 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context &context)
14414 : NegativeTestBase(context, "varying_location_limit",
14415 "Test verifies that compiler reports error when location qualifier exceeds limits")
14416 {
14417 }
14418
14419 /** Source for given test case and stage
14420 *
14421 * @param test_case_index Index of test case
14422 * @param stage Shader stage
14423 *
14424 * @return Shader source
14425 **/
14426 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
14427 {
14428 #if DEBUG_NEG_REMOVE_ERROR
14429 static const GLchar *var_definition = "layout (location = LAST /* + 1 */) FLAT DIRECTION TYPE gokuARRAY;\n";
14430 #else
14431 static const GLchar *var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n";
14432 #endif /* DEBUG_NEG_REMOVE_ERROR */
14433 static const GLchar *input_use = " if (TYPE(0) == gokuINDEX)\n"
14434 " {\n"
14435 " result += vec4(1, 0.5, 0.25, 0.125);\n"
14436 " }\n";
14437 static const GLchar *output_use = " gokuINDEX = TYPE(0);\n"
14438 " if (vec4(0) == result)\n"
14439 " {\n"
14440 " gokuINDEX = TYPE(1);\n"
14441 " }\n";
14442 static const GLchar *fs = "#version 430 core\n"
14443 "#extension GL_ARB_enhanced_layouts : require\n"
14444 "\n"
14445 "in vec4 gs_fs;\n"
14446 "out vec4 fs_out;\n"
14447 "\n"
14448 "void main()\n"
14449 "{\n"
14450 " fs_out = gs_fs;\n"
14451 "}\n"
14452 "\n";
14453 static const GLchar *fs_tested = "#version 430 core\n"
14454 "#extension GL_ARB_enhanced_layouts : require\n"
14455 "\n"
14456 "VAR_DEFINITION"
14457 "\n"
14458 "in vec4 gs_fs;\n"
14459 "out vec4 fs_out;\n"
14460 "\n"
14461 "void main()\n"
14462 "{\n"
14463 " vec4 result = gs_fs;\n"
14464 "\n"
14465 "VARIABLE_USE"
14466 "\n"
14467 " fs_out += result;\n"
14468 "}\n"
14469 "\n";
14470 static const GLchar *gs = "#version 430 core\n"
14471 "#extension GL_ARB_enhanced_layouts : require\n"
14472 "\n"
14473 "layout(points) in;\n"
14474 "layout(triangle_strip, max_vertices = 4) out;\n"
14475 "\n"
14476 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
14477 "in vec4 tes_gs[];\n"
14478 "out vec4 gs_fs;\n"
14479 "\n"
14480 "void main()\n"
14481 "{\n"
14482 " gs_fs = tes_gs[0];\n"
14483 " gl_Position = vec4(-1, -1, 0, 1);\n"
14484 " EmitVertex();\n"
14485 " gs_fs = tes_gs[0];\n"
14486 " gl_Position = vec4(-1, 1, 0, 1);\n"
14487 " EmitVertex();\n"
14488 " gs_fs = tes_gs[0];\n"
14489 " gl_Position = vec4(1, -1, 0, 1);\n"
14490 " EmitVertex();\n"
14491 " gs_fs = tes_gs[0];\n"
14492 " gl_Position = vec4(1, 1, 0, 1);\n"
14493 " EmitVertex();\n"
14494 "}\n"
14495 "\n";
14496 static const GLchar *gs_tested = "#version 430 core\n"
14497 "#extension GL_ARB_enhanced_layouts : require\n"
14498 "\n"
14499 "layout(points) in;\n"
14500 "layout(triangle_strip, max_vertices = 4) out;\n"
14501 "\n"
14502 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
14503 "VAR_DEFINITION"
14504 "\n"
14505 "in vec4 tes_gs[];\n"
14506 "out vec4 gs_fs;\n"
14507 "\n"
14508 "void main()\n"
14509 "{\n"
14510 " vec4 result = tes_gs[0];\n"
14511 "\n"
14512 "VARIABLE_USE"
14513 "\n"
14514 " gs_fs = result;\n"
14515 " gl_Position = vec4(-1, -1, 0, 1);\n"
14516 " EmitVertex();\n"
14517 " gs_fs = result;\n"
14518 " gl_Position = vec4(-1, 1, 0, 1);\n"
14519 " EmitVertex();\n"
14520 " gs_fs = result;\n"
14521 " gl_Position = vec4(1, -1, 0, 1);\n"
14522 " EmitVertex();\n"
14523 " gs_fs = result;\n"
14524 " gl_Position = vec4(1, 1, 0, 1);\n"
14525 " EmitVertex();\n"
14526 "}\n"
14527 "\n";
14528 static const GLchar *tcs = "#version 430 core\n"
14529 "#extension GL_ARB_enhanced_layouts : require\n"
14530 "\n"
14531 "layout(vertices = 1) out;\n"
14532 "\n"
14533 "in vec4 vs_tcs[];\n"
14534 "out vec4 tcs_tes[];\n"
14535 "\n"
14536 "void main()\n"
14537 "{\n"
14538 "\n"
14539 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14540 "\n"
14541 " gl_TessLevelOuter[0] = 1.0;\n"
14542 " gl_TessLevelOuter[1] = 1.0;\n"
14543 " gl_TessLevelOuter[2] = 1.0;\n"
14544 " gl_TessLevelOuter[3] = 1.0;\n"
14545 " gl_TessLevelInner[0] = 1.0;\n"
14546 " gl_TessLevelInner[1] = 1.0;\n"
14547 "}\n"
14548 "\n";
14549 static const GLchar *tcs_tested = "#version 430 core\n"
14550 "#extension GL_ARB_enhanced_layouts : require\n"
14551 "\n"
14552 "layout(vertices = 1) out;\n"
14553 "\n"
14554 "VAR_DEFINITION"
14555 "\n"
14556 "in vec4 vs_tcs[];\n"
14557 "out vec4 tcs_tes[];\n"
14558 "\n"
14559 "void main()\n"
14560 "{\n"
14561 " vec4 result = vs_tcs[gl_InvocationID];\n"
14562 "\n"
14563 "VARIABLE_USE"
14564 "\n"
14565 " tcs_tes[gl_InvocationID] = result;\n"
14566 "\n"
14567 " gl_TessLevelOuter[0] = 1.0;\n"
14568 " gl_TessLevelOuter[1] = 1.0;\n"
14569 " gl_TessLevelOuter[2] = 1.0;\n"
14570 " gl_TessLevelOuter[3] = 1.0;\n"
14571 " gl_TessLevelInner[0] = 1.0;\n"
14572 " gl_TessLevelInner[1] = 1.0;\n"
14573 "}\n"
14574 "\n";
14575 static const GLchar *tes = "#version 430 core\n"
14576 "#extension GL_ARB_enhanced_layouts : require\n"
14577 "\n"
14578 "layout(isolines, point_mode) in;\n"
14579 "\n"
14580 "in vec4 tcs_tes[];\n"
14581 "out vec4 tes_gs;\n"
14582 "\n"
14583 "void main()\n"
14584 "{\n"
14585 " tes_gs = tcs_tes[0];\n"
14586 "}\n"
14587 "\n";
14588 static const GLchar *tes_tested = "#version 430 core\n"
14589 "#extension GL_ARB_enhanced_layouts : require\n"
14590 "\n"
14591 "layout(isolines, point_mode) in;\n"
14592 "\n"
14593 "VAR_DEFINITION"
14594 "\n"
14595 "in vec4 tcs_tes[];\n"
14596 "out vec4 tes_gs;\n"
14597 "\n"
14598 "void main()\n"
14599 "{\n"
14600 " vec4 result = tcs_tes[0];\n"
14601 "\n"
14602 "VARIABLE_USE"
14603 "\n"
14604 " tes_gs += result;\n"
14605 "}\n"
14606 "\n";
14607 static const GLchar *vs = "#version 430 core\n"
14608 "#extension GL_ARB_enhanced_layouts : require\n"
14609 "\n"
14610 "in vec4 in_vs;\n"
14611 "out vec4 vs_tcs;\n"
14612 "\n"
14613 "void main()\n"
14614 "{\n"
14615 " vs_tcs = in_vs;\n"
14616 "}\n"
14617 "\n";
14618 static const GLchar *vs_tested = "#version 430 core\n"
14619 "#extension GL_ARB_enhanced_layouts : require\n"
14620 "\n"
14621 "VAR_DEFINITION"
14622 "\n"
14623 "in vec4 in_vs;\n"
14624 "out vec4 vs_tcs;\n"
14625 "\n"
14626 "void main()\n"
14627 "{\n"
14628 " vec4 result = in_vs;\n"
14629 "\n"
14630 "VARIABLE_USE"
14631 "\n"
14632 " vs_tcs += result;\n"
14633 "}\n"
14634 "\n";
14635
14636 std::string source;
14637 testCase &test_case = m_test_cases[test_case_index];
14638 size_t position = 0;
14639 const GLchar *per_vertex = !isSeparable(test_case_index) ? "" :
14640 "out gl_PerVertex {\n"
14641 "vec4 gl_Position;\n"
14642 "};\n"
14643 "\n";
14644
14645 if (test_case.m_stage == stage)
14646 {
14647 const GLchar *array = "";
14648 GLchar buffer[16];
14649 const GLchar *direction = "in ";
14650 const GLchar *flat = "";
14651 const GLchar *index = "";
14652 GLuint last = getLastInputLocation(stage, test_case.m_type, 0, true);
14653 const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
14654 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
14655 const GLchar *var_use = input_use;
14656
14657 if (false == test_case.m_is_input)
14658 {
14659 direction = "out";
14660 last = getLastOutputLocation(stage, test_case.m_type, 0, true);
14661 storage = Utils::Variable::VARYING_OUTPUT;
14662 var_use = output_use;
14663 }
14664
14665 if (isFlatRequired(stage, test_case.m_type, storage))
14666 {
14667 flat = "flat";
14668 }
14669
14670 sprintf(buffer, "%d", last);
14671
14672 switch (stage)
14673 {
14674 case Utils::Shader::FRAGMENT:
14675 source = fs_tested;
14676 break;
14677 case Utils::Shader::GEOMETRY:
14678 source = gs_tested;
14679 array = test_case.m_is_input ? "[]" : "";
14680 index = test_case.m_is_input ? "[0]" : "";
14681 Utils::replaceToken("PERVERTEX", position, per_vertex, source);
14682 break;
14683 case Utils::Shader::TESS_CTRL:
14684 source = tcs_tested;
14685 array = "[]";
14686 index = "[gl_InvocationID]";
14687 break;
14688 case Utils::Shader::TESS_EVAL:
14689 source = tes_tested;
14690 array = test_case.m_is_input ? "[]" : "";
14691 index = test_case.m_is_input ? "[0]" : "";
14692 break;
14693 case Utils::Shader::VERTEX:
14694 source = vs_tested;
14695 break;
14696 default:
14697 TCU_FAIL("Invalid enum");
14698 }
14699
14700 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
14701 position = 0;
14702 Utils::replaceToken("LAST", position, buffer, source);
14703 Utils::replaceToken("FLAT", position, flat, source);
14704 Utils::replaceToken("DIRECTION", position, direction, source);
14705 Utils::replaceToken("ARRAY", position, array, source);
14706 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14707
14708 Utils::replaceAllTokens("TYPE", type_name, source);
14709 Utils::replaceAllTokens("INDEX", index, source);
14710 }
14711 else
14712 {
14713 switch (stage)
14714 {
14715 case Utils::Shader::FRAGMENT:
14716 source = fs;
14717 break;
14718 case Utils::Shader::GEOMETRY:
14719 source = gs;
14720 Utils::replaceToken("PERVERTEX", position, per_vertex, source);
14721 break;
14722 case Utils::Shader::TESS_CTRL:
14723 source = tcs;
14724 break;
14725 case Utils::Shader::TESS_EVAL:
14726 source = tes;
14727 break;
14728 case Utils::Shader::VERTEX:
14729 source = vs;
14730 break;
14731 default:
14732 TCU_FAIL("Invalid enum");
14733 }
14734 }
14735
14736 return source;
14737 }
14738
14739 /** Get description of test case
14740 *
14741 * @param test_case_index Index of test case
14742 *
14743 * @return Test case description
14744 **/
14745 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index)
14746 {
14747 std::stringstream stream;
14748 testCase &test_case = m_test_cases[test_case_index];
14749
14750 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
14751 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
14752
14753 if (true == test_case.m_is_input)
14754 {
14755 stream << "input";
14756 }
14757 else
14758 {
14759 stream << "output";
14760 }
14761
14762 return stream.str();
14763 }
14764
14765 /** Get number of test cases
14766 *
14767 * @return Number of test cases
14768 **/
14769 GLuint VaryingLocationLimitTest::getTestCaseNumber()
14770 {
14771 return static_cast<GLuint>(m_test_cases.size());
14772 }
14773
14774 /** Selects if "compute" stage is relevant for test
14775 *
14776 * @param ignored
14777 *
14778 * @return false
14779 **/
14780 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */)
14781 {
14782 return false;
14783 }
14784
14785 /** Selects if the test case should use a separable program
14786 *
14787 * @param test_case_index Id of test case
14788 *
14789 * @return whether the test should use separable programs or not
14790 **/
14791 bool VaryingLocationLimitTest::isSeparable(const GLuint test_case_index)
14792 {
14793 const testCase &test_case = m_test_cases[test_case_index];
14794
14795 return test_case.m_is_input && test_case.m_stage != Utils::Shader::VERTEX;
14796 }
14797
14798 /** Prepare all test cases
14799 *
14800 **/
14801 void VaryingLocationLimitTest::testInit()
14802 {
14803 const GLuint n_types = getTypesNumber();
14804
14805 for (GLuint i = 0; i < n_types; ++i)
14806 {
14807 const Utils::Type &type = getType(i);
14808
14809 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14810 {
14811 if (Utils::Shader::COMPUTE == stage)
14812 {
14813 continue;
14814 }
14815
14816 testCase test_case_in = {true, type, (Utils::Shader::STAGES)stage};
14817 testCase test_case_out = {false, type, (Utils::Shader::STAGES)stage};
14818
14819 m_test_cases.push_back(test_case_in);
14820
14821 if (Utils::Shader::FRAGMENT != stage)
14822 {
14823 m_test_cases.push_back(test_case_out);
14824 }
14825 }
14826 }
14827 }
14828
14829 /** Constructor
14830 *
14831 * @param context Test framework context
14832 **/
14833 VaryingComponentsTest::VaryingComponentsTest(deqp::Context &context)
14834 : VaryingLocationsTest(context, "varying_components",
14835 "Test verifies that input and output components are respected")
14836 {
14837 }
14838
14839 /** Constructor
14840 *
14841 * @param context Test framework context
14842 * @param test_name Name of test
14843 * @param test_description Description of test
14844 **/
14845 VaryingComponentsTest::VaryingComponentsTest(deqp::Context &context, const glw::GLchar *test_name,
14846 const glw::GLchar *test_description)
14847 : VaryingLocationsTest(context, test_name, test_description)
14848 {
14849 }
14850
14851 /** Get interface of program
14852 *
14853 * @param test_case_index Test case
14854 * @param program_interface Interface of program
14855 * @param varying_passthrough Collection of connections between in and out variables
14856 **/
14857 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface &program_interface,
14858 Utils::VaryingPassthrough &varying_passthrough)
14859 {
14860 GLuint array_length = getArrayLength();
14861 const testCase &test_case = m_test_cases[test_case_index];
14862 const Utils::Type vector_type = Utils::Type::GetType(test_case.m_type, 1, 4);
14863 Utils::ShaderInterface si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
14864
14865 /* Zero means no array, however we still need at least 1 slot of data */
14866 if (0 == array_length)
14867 {
14868 array_length += 1;
14869 }
14870
14871 /* Generate data */
14872 const std::vector<GLubyte> &data = vector_type.GenerateDataPacked();
14873 const size_t data_size = data.size();
14874
14875 /* Prepare data for variables */
14876 m_data.resize(array_length * data_size);
14877
14878 GLubyte *dst = &m_data[0];
14879 const GLubyte *src = &data[0];
14880
14881 for (GLuint i = 0; i < array_length; ++i)
14882 {
14883 memcpy(dst + data_size * i, src, data_size);
14884 }
14885
14886 /* Prepare interface for each stage */
14887 prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough);
14888 prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough);
14889 prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough);
14890 prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough);
14891 prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough);
14892 }
14893
14894 /** Get type name
14895 *
14896 * @param test_case_index Index of test case
14897 *
14898 * @return Name of type test in test_case_index
14899 **/
14900 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index)
14901 {
14902 std::string name;
14903
14904 const testCase &test_case = m_test_cases[test_case_index];
14905
14906 name = "Type: ";
14907
14908 switch (test_case.m_type)
14909 {
14910 case Utils::Type::Double:
14911 name.append(Utils::Type::_double.GetGLSLTypeName());
14912 break;
14913 case Utils::Type::Float:
14914 name.append(Utils::Type::_float.GetGLSLTypeName());
14915 break;
14916 case Utils::Type::Int:
14917 name.append(Utils::Type::_int.GetGLSLTypeName());
14918 break;
14919 case Utils::Type::Uint:
14920 name.append(Utils::Type::uint.GetGLSLTypeName());
14921 break;
14922 }
14923
14924 name.append(", layout: ");
14925
14926 switch (test_case.m_layout)
14927 {
14928 case G64VEC2:
14929 name.append("G64VEC2");
14930 break;
14931 case G64SCALAR_G64SCALAR:
14932 name.append("G64SCALAR_G64SCALAR");
14933 break;
14934 case GVEC4:
14935 name.append("GVEC4");
14936 break;
14937 case SCALAR_GVEC3:
14938 name.append("SCALAR_GVEC3");
14939 break;
14940 case GVEC3_SCALAR:
14941 name.append("GVEC3_SCALAR");
14942 break;
14943 case GVEC2_GVEC2:
14944 name.append("GVEC2_GVEC2");
14945 break;
14946 case GVEC2_SCALAR_SCALAR:
14947 name.append("GVEC2_SCALAR_SCALAR");
14948 break;
14949 case SCALAR_GVEC2_SCALAR:
14950 name.append("SCALAR_GVEC2_SCALAR");
14951 break;
14952 case SCALAR_SCALAR_GVEC2:
14953 name.append("SCALAR_SCALAR_GVEC2");
14954 break;
14955 case SCALAR_SCALAR_SCALAR_SCALAR:
14956 name.append("SCALAR_SCALAR_SCALAR_SCALAR");
14957 break;
14958 }
14959
14960 return name;
14961 }
14962
14963 /** Returns number of types to test
14964 *
14965 * @return Number of types
14966 **/
14967 glw::GLuint VaryingComponentsTest::getTestCaseNumber()
14968 {
14969 return static_cast<GLuint>(m_test_cases.size());
14970 }
14971
14972 /* Prepare test cases */
14973 void VaryingComponentsTest::testInit()
14974 {
14975 m_test_cases.push_back(testCase(G64VEC2, Utils::Type::Double));
14976 m_test_cases.push_back(testCase(G64SCALAR_G64SCALAR, Utils::Type::Double));
14977
14978 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float));
14979 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float));
14980 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float));
14981 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float));
14982 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float));
14983 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float));
14984 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float));
14985 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float));
14986
14987 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int));
14988 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int));
14989 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int));
14990 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int));
14991 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int));
14992 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int));
14993 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int));
14994 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int));
14995
14996 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint));
14997 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint));
14998 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint));
14999 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint));
15000 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint));
15001 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint));
15002 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint));
15003 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint));
15004 }
15005
15006 /** Inform that test use components
15007 *
15008 * @param ignored
15009 *
15010 * @return true
15011 **/
15012 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */)
15013 {
15014 return true;
15015 }
15016
15017 /** Get length of arrays that should be used during test
15018 *
15019 * @return 0u - no array at all
15020 **/
15021 GLuint VaryingComponentsTest::getArrayLength()
15022 {
15023 return 0;
15024 }
15025
15026 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location)
15027 {
15028 std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location);
15029
15030 globals.append("const uint comp_x = 0u;\n"
15031 "const uint comp_y = 1u;\n"
15032 "const uint comp_z = 2u;\n"
15033 "const uint comp_w = 3u;\n");
15034
15035 return globals;
15036 }
15037
15038 /**
15039 *
15040 **/
15041 std::string VaryingComponentsTest::prepareName(const glw::GLchar *name, glw::GLint location, glw::GLint component,
15042 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15043 {
15044 GLchar buffer[16];
15045 std::string result = "PREFIXNAME_lLOCATION_cCOMPONENT";
15046 size_t position = 0;
15047 const GLchar *prefix = Utils::ProgramInterface::GetStagePrefix(stage, storage);
15048
15049 Utils::replaceToken("PREFIX", position, prefix, result);
15050 Utils::replaceToken("NAME", position, name, result);
15051
15052 sprintf(buffer, "%d", location);
15053 Utils::replaceToken("LOCATION", position, buffer, result);
15054
15055 sprintf(buffer, "%d", component);
15056 Utils::replaceToken("COMPONENT", position, buffer, result);
15057
15058 return result;
15059 }
15060
15061 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar *location, const glw::GLchar *component,
15062 const glw::GLchar *interpolation)
15063 {
15064 size_t position = 0;
15065 std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION";
15066
15067 Utils::replaceToken("LOCATION", position, location, qualifiers);
15068 Utils::replaceToken("COMPONENT", position, component, qualifiers);
15069 Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers);
15070
15071 return qualifiers;
15072 }
15073
15074 /**
15075 *
15076 **/
15077 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type &vector_type,
15078 Utils::ProgramInterface &program_interface, const testCase &test_case,
15079 Utils::VaryingPassthrough &varying_passthrough)
15080 {
15081 const GLuint array_length = getArrayLength();
15082 const Utils::Type &basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */);
15083 descriptor desc_in[8];
15084 descriptor desc_out[8];
15085 const GLuint first_in_loc = 0;
15086 const GLuint first_out_loc = 0;
15087 const GLchar *interpolation = "";
15088 const GLuint last_in_loc = getLastInputLocation(stage, vector_type, array_length, false);
15089 GLuint last_out_loc = 0;
15090 GLuint n_desc = 0;
15091 Utils::ShaderInterface &si = program_interface.GetShaderInterface(stage);
15092
15093 /* Select interpolation */
15094 if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage))
15095 {
15096 interpolation = " flat";
15097 }
15098
15099 if (Utils::Shader::FRAGMENT != stage)
15100 {
15101 last_out_loc = getLastOutputLocation(stage, vector_type, array_length, false);
15102 }
15103
15104 switch (test_case.m_layout)
15105 {
15106 case G64VEC2:
15107 n_desc = 2;
15108 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "g64vec2");
15109 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "g64vec2");
15110
15111 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "g64vec2");
15112 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "g64vec2");
15113 break;
15114
15115 case G64SCALAR_G64SCALAR:
15116 n_desc = 4;
15117 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "g64scalar");
15118 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "g64scalar");
15119 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "g64scalar");
15120 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "g64scalar");
15121
15122 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "g64scalar");
15123 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "g64scalar");
15124 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "g64scalar");
15125 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "g64scalar");
15126 break;
15127 case GVEC4:
15128 n_desc = 2;
15129 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4");
15130 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4");
15131
15132 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4");
15133 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4");
15134 break;
15135 case SCALAR_GVEC3:
15136 n_desc = 4;
15137 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15138 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15139 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3");
15140 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3");
15141
15142 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15143 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15144 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3");
15145 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3");
15146 break;
15147 case GVEC3_SCALAR:
15148 n_desc = 4;
15149 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3");
15150 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3");
15151 desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15152 desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15153
15154 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3");
15155 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3");
15156 desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15157 desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15158 break;
15159 case GVEC2_GVEC2:
15160 n_desc = 4;
15161 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15162 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15163 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15164 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15165
15166 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
15167 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15168 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15169 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15170 break;
15171 case GVEC2_SCALAR_SCALAR:
15172 n_desc = 6;
15173 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15174 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15175 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15176 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15177 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15178 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15179
15180 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
15181 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15182 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15183 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15184 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15185 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15186 break;
15187 case SCALAR_GVEC2_SCALAR:
15188 n_desc = 6;
15189 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15190 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15191 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2");
15192 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2");
15193 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15194 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15195
15196 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15197 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15198 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2");
15199 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2");
15200 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15201 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15202 break;
15203 case SCALAR_SCALAR_GVEC2:
15204 n_desc = 6;
15205 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15206 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15207 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15208 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15209 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15210 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15211
15212 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15213 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15214 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15215 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15216 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15217 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15218 break;
15219 case SCALAR_SCALAR_SCALAR_SCALAR:
15220 n_desc = 8;
15221 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15222 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15223 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15224 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15225 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15226 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15227 desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15228 desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15229
15230 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15231 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15232 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15233 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15234 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15235 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15236 desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15237 desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15238 break;
15239 }
15240
15241 for (GLuint i = 0; i < n_desc; ++i)
15242 {
15243 const descriptor &in_desc = desc_in[i];
15244
15245 Utils::Variable *in =
15246 prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT);
15247
15248 if (Utils::Shader::FRAGMENT != stage)
15249 {
15250 const descriptor &out_desc = desc_out[i];
15251
15252 Utils::Variable *out =
15253 prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT);
15254
15255 varying_passthrough.Add(stage, in, out);
15256 }
15257 }
15258
15259 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
15260 }
15261
15262 /**
15263 *
15264 **/
15265 Utils::Variable *VaryingComponentsTest::prepareVarying(const Utils::Type &basic_type, const descriptor &desc,
15266 const GLchar *interpolation, Utils::ShaderInterface &si,
15267 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15268 {
15269 const GLuint array_length = getArrayLength();
15270 const GLuint component_size = Utils::Type::_float.GetSize();
15271 const std::string &name = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage);
15272 const GLuint offset = desc.m_component * component_size;
15273 const std::string &qual = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation);
15274 const GLuint size = desc.m_n_rows * basic_type.GetSize();
15275 const Utils::Type &type = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows);
15276 Utils::Variable *var = 0;
15277
15278 if (Utils::Variable::VARYING_INPUT == storage)
15279 {
15280 var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15281 desc.m_location /* expected_location */, type, /* built_in_type */
15282 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15283 offset /* offset */, (GLvoid *)&m_data[offset] /* data */, size /* data_size */);
15284 }
15285 else
15286 {
15287 var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15288 desc.m_location /* expected_location */, type, /* built_in_type */
15289 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15290 offset /* offset */, (GLvoid *)&m_data[offset] /* data */, size /* data_size */);
15291 }
15292
15293 return var;
15294 }
15295
15296 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar *component_str,
15297 glw::GLint location, const glw::GLchar *location_str, glw::GLuint n_rows,
15298 const glw::GLchar *name)
15299 {
15300 m_component = component;
15301 m_component_str = component_str;
15302 m_location = location;
15303 m_location_str = location_str;
15304 m_n_rows = n_rows;
15305 m_name = name;
15306 }
15307
15308 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type)
15309 : m_layout(layout)
15310 , m_type(type)
15311 {
15312 }
15313
15314 /** Constructor
15315 *
15316 * @param context Test framework context
15317 **/
15318 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context &context)
15319 : VaryingComponentsTest(context, "varying_array_components",
15320 "Test verifies that input and output components are respected for arrays")
15321 {
15322 }
15323
15324 /** Get length of arrays that should be used during test
15325 *
15326 * @return 4u
15327 **/
15328 GLuint VaryingArrayComponentsTest::getArrayLength()
15329 {
15330 return 4u;
15331 }
15332
15333 /** Constructor
15334 *
15335 * @param context Test framework context
15336 **/
15337 VaryingInvalidValueComponentTest::VaryingInvalidValueComponentTest(deqp::Context &context)
15338 : NegativeTestBase(context, "varying_invalid_value_component",
15339 "Test verifies that compiler reports error when "
15340 "using an invalid value in the component "
15341 "qualification for a specific type")
15342 {
15343 }
15344
15345 /** Source for given test case and stage
15346 *
15347 * @param test_case_index Index of test case
15348 * @param stage Shader stage
15349 *
15350 * @return Shader source
15351 **/
15352 std::string VaryingInvalidValueComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15353 {
15354 #if DEBUG_NEG_REMOVE_ERROR
15355 static const GLchar *var_definition_arr =
15356 "layout (location = 1 /*, component = COMPONENT */) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15357 static const GLchar *var_definition_one =
15358 "layout (location = 1 /*, component = COMPONENT */) FLAT DIRECTION TYPE gokuARRAY;\n";
15359 #else
15360 static const GLchar *var_definition_arr =
15361 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15362 static const GLchar *var_definition_one =
15363 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
15364 #endif /* DEBUG_NEG_REMOVE_ERROR */
15365 static const GLchar *input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
15366 " {\n"
15367 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15368 " }\n";
15369 static const GLchar *input_use_one = " if (TYPE(0) == gokuINDEX)\n"
15370 " {\n"
15371 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15372 " }\n";
15373 static const GLchar *output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
15374 " if (vec4(0) == result)\n"
15375 " {\n"
15376 " gokuINDEX[0] = TYPE(1);\n"
15377 " }\n";
15378 static const GLchar *output_use_one = " gokuINDEX = TYPE(0);\n"
15379 " if (vec4(0) == result)\n"
15380 " {\n"
15381 " gokuINDEX = TYPE(1);\n"
15382 " }\n";
15383 static const GLchar *fs = "#version 430 core\n"
15384 "#extension GL_ARB_enhanced_layouts : require\n"
15385 "\n"
15386 "in vec4 gs_fs;\n"
15387 "out vec4 fs_out;\n"
15388 "\n"
15389 "void main()\n"
15390 "{\n"
15391 " fs_out = gs_fs;\n"
15392 "}\n"
15393 "\n";
15394 static const GLchar *fs_tested = "#version 430 core\n"
15395 "#extension GL_ARB_enhanced_layouts : require\n"
15396 "\n"
15397 "VAR_DEFINITION"
15398 "\n"
15399 "in vec4 gs_fs;\n"
15400 "out vec4 fs_out;\n"
15401 "\n"
15402 "void main()\n"
15403 "{\n"
15404 " vec4 result = gs_fs;\n"
15405 "\n"
15406 "VARIABLE_USE"
15407 "\n"
15408 " fs_out += result;\n"
15409 "}\n"
15410 "\n";
15411 static const GLchar *gs = "#version 430 core\n"
15412 "#extension GL_ARB_enhanced_layouts : require\n"
15413 "\n"
15414 "layout(points) in;\n"
15415 "layout(triangle_strip, max_vertices = 4) out;\n"
15416 "\n"
15417 "in vec4 tes_gs[];\n"
15418 "out vec4 gs_fs;\n"
15419 "\n"
15420 "void main()\n"
15421 "{\n"
15422 " gs_fs = tes_gs[0];\n"
15423 " gl_Position = vec4(-1, -1, 0, 1);\n"
15424 " EmitVertex();\n"
15425 " gs_fs = tes_gs[0];\n"
15426 " gl_Position = vec4(-1, 1, 0, 1);\n"
15427 " EmitVertex();\n"
15428 " gs_fs = tes_gs[0];\n"
15429 " gl_Position = vec4(1, -1, 0, 1);\n"
15430 " EmitVertex();\n"
15431 " gs_fs = tes_gs[0];\n"
15432 " gl_Position = vec4(1, 1, 0, 1);\n"
15433 " EmitVertex();\n"
15434 "}\n"
15435 "\n";
15436 static const GLchar *gs_tested = "#version 430 core\n"
15437 "#extension GL_ARB_enhanced_layouts : require\n"
15438 "\n"
15439 "layout(points) in;\n"
15440 "layout(triangle_strip, max_vertices = 4) out;\n"
15441 "\n"
15442 "VAR_DEFINITION"
15443 "\n"
15444 "in vec4 tes_gs[];\n"
15445 "out vec4 gs_fs;\n"
15446 "\n"
15447 "void main()\n"
15448 "{\n"
15449 " vec4 result = tes_gs[0];\n"
15450 "\n"
15451 "VARIABLE_USE"
15452 "\n"
15453 " gs_fs = result;\n"
15454 " gl_Position = vec4(-1, -1, 0, 1);\n"
15455 " EmitVertex();\n"
15456 " gs_fs = result;\n"
15457 " gl_Position = vec4(-1, 1, 0, 1);\n"
15458 " EmitVertex();\n"
15459 " gs_fs = result;\n"
15460 " gl_Position = vec4(1, -1, 0, 1);\n"
15461 " EmitVertex();\n"
15462 " gs_fs = result;\n"
15463 " gl_Position = vec4(1, 1, 0, 1);\n"
15464 " EmitVertex();\n"
15465 "}\n"
15466 "\n";
15467 static const GLchar *tcs = "#version 430 core\n"
15468 "#extension GL_ARB_enhanced_layouts : require\n"
15469 "\n"
15470 "layout(vertices = 1) out;\n"
15471 "\n"
15472 "in vec4 vs_tcs[];\n"
15473 "out vec4 tcs_tes[];\n"
15474 "\n"
15475 "void main()\n"
15476 "{\n"
15477 "\n"
15478 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15479 "\n"
15480 " gl_TessLevelOuter[0] = 1.0;\n"
15481 " gl_TessLevelOuter[1] = 1.0;\n"
15482 " gl_TessLevelOuter[2] = 1.0;\n"
15483 " gl_TessLevelOuter[3] = 1.0;\n"
15484 " gl_TessLevelInner[0] = 1.0;\n"
15485 " gl_TessLevelInner[1] = 1.0;\n"
15486 "}\n"
15487 "\n";
15488 static const GLchar *tcs_tested = "#version 430 core\n"
15489 "#extension GL_ARB_enhanced_layouts : require\n"
15490 "\n"
15491 "layout(vertices = 1) out;\n"
15492 "\n"
15493 "VAR_DEFINITION"
15494 "\n"
15495 "in vec4 vs_tcs[];\n"
15496 "out vec4 tcs_tes[];\n"
15497 "\n"
15498 "void main()\n"
15499 "{\n"
15500 " vec4 result = vs_tcs[gl_InvocationID];\n"
15501 "\n"
15502 "VARIABLE_USE"
15503 "\n"
15504 " tcs_tes[gl_InvocationID] = result;\n"
15505 "\n"
15506 " gl_TessLevelOuter[0] = 1.0;\n"
15507 " gl_TessLevelOuter[1] = 1.0;\n"
15508 " gl_TessLevelOuter[2] = 1.0;\n"
15509 " gl_TessLevelOuter[3] = 1.0;\n"
15510 " gl_TessLevelInner[0] = 1.0;\n"
15511 " gl_TessLevelInner[1] = 1.0;\n"
15512 "}\n"
15513 "\n";
15514 static const GLchar *tes = "#version 430 core\n"
15515 "#extension GL_ARB_enhanced_layouts : require\n"
15516 "\n"
15517 "layout(isolines, point_mode) in;\n"
15518 "\n"
15519 "in vec4 tcs_tes[];\n"
15520 "out vec4 tes_gs;\n"
15521 "\n"
15522 "void main()\n"
15523 "{\n"
15524 " tes_gs = tcs_tes[0];\n"
15525 "}\n"
15526 "\n";
15527 static const GLchar *tes_tested = "#version 430 core\n"
15528 "#extension GL_ARB_enhanced_layouts : require\n"
15529 "\n"
15530 "layout(isolines, point_mode) in;\n"
15531 "\n"
15532 "VAR_DEFINITION"
15533 "\n"
15534 "in vec4 tcs_tes[];\n"
15535 "out vec4 tes_gs;\n"
15536 "\n"
15537 "void main()\n"
15538 "{\n"
15539 " vec4 result = tcs_tes[0];\n"
15540 "\n"
15541 "VARIABLE_USE"
15542 "\n"
15543 " tes_gs += result;\n"
15544 "}\n"
15545 "\n";
15546 static const GLchar *vs = "#version 430 core\n"
15547 "#extension GL_ARB_enhanced_layouts : require\n"
15548 "\n"
15549 "in vec4 in_vs;\n"
15550 "out vec4 vs_tcs;\n"
15551 "\n"
15552 "void main()\n"
15553 "{\n"
15554 " vs_tcs = in_vs;\n"
15555 "}\n"
15556 "\n";
15557 static const GLchar *vs_tested = "#version 430 core\n"
15558 "#extension GL_ARB_enhanced_layouts : require\n"
15559 "\n"
15560 "VAR_DEFINITION"
15561 "\n"
15562 "in vec4 in_vs;\n"
15563 "out vec4 vs_tcs;\n"
15564 "\n"
15565 "void main()\n"
15566 "{\n"
15567 " vec4 result = in_vs;\n"
15568 "\n"
15569 "VARIABLE_USE"
15570 "\n"
15571 " vs_tcs += result;\n"
15572 "}\n"
15573 "\n";
15574
15575 std::string source;
15576 testCase &test_case = m_test_cases[test_case_index];
15577
15578 if (test_case.m_stage == stage)
15579 {
15580 const GLchar *array = "";
15581 GLchar buffer[16];
15582 const GLchar *var_definition = 0;
15583 const GLchar *direction = "in";
15584 const GLchar *index = "";
15585 size_t position = 0;
15586 const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
15587 const GLchar *var_use = 0;
15588 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
15589 const GLchar *flat = "";
15590
15591 if (false == test_case.m_is_input)
15592 {
15593 direction = "out";
15594 storage = Utils::Variable::VARYING_OUTPUT;
15595
15596 if (false == test_case.m_is_array)
15597 {
15598 var_definition = var_definition_one;
15599 var_use = output_use_one;
15600 }
15601 else
15602 {
15603 var_definition = var_definition_arr;
15604 var_use = output_use_arr;
15605 }
15606 }
15607 else
15608 {
15609 if (false == test_case.m_is_array)
15610 {
15611 var_definition = var_definition_one;
15612 var_use = Utils::Shader::VERTEX == stage ? input_use_one : "\n";
15613 }
15614 else
15615 {
15616 var_definition = var_definition_arr;
15617 var_use = Utils::Shader::VERTEX == stage ? input_use_arr : "\n";
15618 }
15619 }
15620
15621 if (isFlatRequired(stage, test_case.m_type, storage, true))
15622 {
15623 flat = "flat";
15624 }
15625
15626 sprintf(buffer, "%d", test_case.m_component);
15627
15628 switch (stage)
15629 {
15630 case Utils::Shader::FRAGMENT:
15631 source = fs_tested;
15632 break;
15633 case Utils::Shader::GEOMETRY:
15634 source = gs_tested;
15635 array = test_case.m_is_input ? "[]" : "";
15636 index = test_case.m_is_input ? "[0]" : "";
15637 break;
15638 case Utils::Shader::TESS_CTRL:
15639 source = tcs_tested;
15640 array = "[]";
15641 index = "[gl_InvocationID]";
15642 break;
15643 case Utils::Shader::TESS_EVAL:
15644 source = tes_tested;
15645 array = test_case.m_is_input ? "[]" : "";
15646 index = test_case.m_is_input ? "[0]" : "";
15647 break;
15648 case Utils::Shader::VERTEX:
15649 source = vs_tested;
15650 break;
15651 default:
15652 TCU_FAIL("Invalid enum");
15653 }
15654
15655 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15656 position = 0;
15657 Utils::replaceToken("COMPONENT", position, buffer, source);
15658 Utils::replaceToken("FLAT", position, flat, source);
15659 Utils::replaceToken("DIRECTION", position, direction, source);
15660 Utils::replaceToken("ARRAY", position, array, source);
15661 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15662
15663 Utils::replaceAllTokens("TYPE", type_name, source);
15664 Utils::replaceAllTokens("INDEX", index, source);
15665 }
15666 else
15667 {
15668 switch (stage)
15669 {
15670 case Utils::Shader::FRAGMENT:
15671 source = fs;
15672 break;
15673 case Utils::Shader::GEOMETRY:
15674 source = gs;
15675 break;
15676 case Utils::Shader::TESS_CTRL:
15677 source = tcs;
15678 break;
15679 case Utils::Shader::TESS_EVAL:
15680 source = tes;
15681 break;
15682 case Utils::Shader::VERTEX:
15683 source = vs;
15684 break;
15685 default:
15686 TCU_FAIL("Invalid enum");
15687 }
15688 }
15689
15690 return source;
15691 }
15692
15693 /** Get description of test case
15694 *
15695 * @param test_case_index Index of test case
15696 *
15697 * @return Test case description
15698 **/
15699 std::string VaryingInvalidValueComponentTest::getTestCaseName(GLuint test_case_index)
15700 {
15701 std::stringstream stream;
15702 testCase &test_case = m_test_cases[test_case_index];
15703
15704 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15705 << " type: " << test_case.m_type.GetGLSLTypeName();
15706
15707 if (true == test_case.m_is_array)
15708 {
15709 stream << "[1]";
15710 }
15711
15712 stream << ", direction: ";
15713
15714 if (true == test_case.m_is_input)
15715 {
15716 stream << "input";
15717 }
15718 else
15719 {
15720 stream << "output";
15721 }
15722
15723 stream << ", component: " << test_case.m_component;
15724
15725 return stream.str();
15726 }
15727
15728 /** Get number of test cases
15729 *
15730 * @return Number of test cases
15731 **/
15732 GLuint VaryingInvalidValueComponentTest::getTestCaseNumber()
15733 {
15734 return static_cast<GLuint>(m_test_cases.size());
15735 }
15736
15737 /** Selects if "compute" stage is relevant for test
15738 *
15739 * @param ignored
15740 *
15741 * @return false
15742 **/
15743 bool VaryingInvalidValueComponentTest::isComputeRelevant(GLuint /* test_case_index */)
15744 {
15745 return false;
15746 }
15747
15748 /** Prepare all test cases
15749 *
15750 **/
15751 void VaryingInvalidValueComponentTest::testInit()
15752 {
15753 const GLuint n_types = getTypesNumber();
15754
15755 for (GLuint i = 0; i < n_types; ++i)
15756 {
15757 const Utils::Type &type = getType(i);
15758 const std::vector<GLuint> &valid_components = type.GetValidComponents();
15759
15760 if (valid_components.empty())
15761 {
15762 continue;
15763 }
15764
15765 std::vector<GLuint> every_component(4, 0);
15766 every_component[1] = 1;
15767 every_component[2] = 2;
15768 every_component[3] = 3;
15769 std::vector<GLuint> invalid_components;
15770
15771 std::set_symmetric_difference(every_component.begin(), every_component.end(), valid_components.begin(),
15772 valid_components.end(), back_inserter(invalid_components));
15773
15774 for (std::vector<GLuint>::const_iterator it_invalid_components = invalid_components.begin();
15775 it_invalid_components != invalid_components.end(); ++it_invalid_components)
15776 {
15777 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15778 {
15779 if (Utils::Shader::COMPUTE == stage)
15780 {
15781 continue;
15782 }
15783
15784 testCase test_case_in_arr = {*it_invalid_components, true, true, (Utils::Shader::STAGES)stage, type};
15785 testCase test_case_in_one = {*it_invalid_components, true, false, (Utils::Shader::STAGES)stage, type};
15786 testCase test_case_out_arr = {*it_invalid_components, false, true, (Utils::Shader::STAGES)stage, type};
15787 testCase test_case_out_one = {*it_invalid_components, false, false, (Utils::Shader::STAGES)stage, type};
15788
15789 m_test_cases.push_back(test_case_in_arr);
15790 m_test_cases.push_back(test_case_in_one);
15791
15792 if (Utils::Shader::FRAGMENT != stage)
15793 {
15794 m_test_cases.push_back(test_case_out_arr);
15795 m_test_cases.push_back(test_case_out_one);
15796 }
15797 }
15798 }
15799 }
15800 }
15801
15802 /** Constructor
15803 *
15804 * @param context Test framework context
15805 **/
15806 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context &context)
15807 : NegativeTestBase(context, "varying_exceeding_components",
15808 "Test verifies that compiler reports error when component qualifier exceeds limits")
15809 {
15810 }
15811
15812 /** Source for given test case and stage
15813 *
15814 * @param test_case_index Index of test case
15815 * @param stage Shader stage
15816 *
15817 * @return Shader source
15818 **/
15819 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15820 {
15821 #if DEBUG_NEG_REMOVE_ERROR
15822 static const GLchar *var_definition_arr =
15823 "layout (location = 1 /*, component = 4 */) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15824 static const GLchar *var_definition_one =
15825 "layout (location = 1 /*, component = 4 */) FLAT DIRECTION TYPE gokuARRAY;\n";
15826 #else
15827 static const GLchar *var_definition_arr =
15828 "layout (location = 1, component = 4) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15829 static const GLchar *var_definition_one = "layout (location = 1, component = 4) FLAT DIRECTION TYPE gokuARRAY;\n";
15830 #endif /* DEBUG_NEG_REMOVE_ERROR */
15831 static const GLchar *input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
15832 " {\n"
15833 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15834 " }\n";
15835 static const GLchar *input_use_one = " if (TYPE(0) == gokuINDEX)\n"
15836 " {\n"
15837 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15838 " }\n";
15839 static const GLchar *output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
15840 " if (vec4(0) == result)\n"
15841 " {\n"
15842 " gokuINDEX[0] = TYPE(1);\n"
15843 " }\n";
15844 static const GLchar *output_use_one = " gokuINDEX = TYPE(0);\n"
15845 " if (vec4(0) == result)\n"
15846 " {\n"
15847 " gokuINDEX = TYPE(1);\n"
15848 " }\n";
15849 static const GLchar *fs = "#version 430 core\n"
15850 "#extension GL_ARB_enhanced_layouts : require\n"
15851 "\n"
15852 "in vec4 gs_fs;\n"
15853 "out vec4 fs_out;\n"
15854 "\n"
15855 "void main()\n"
15856 "{\n"
15857 " fs_out = gs_fs;\n"
15858 "}\n"
15859 "\n";
15860 static const GLchar *fs_tested = "#version 430 core\n"
15861 "#extension GL_ARB_enhanced_layouts : require\n"
15862 "\n"
15863 "VAR_DEFINITION"
15864 "\n"
15865 "in vec4 gs_fs;\n"
15866 "out vec4 fs_out;\n"
15867 "\n"
15868 "void main()\n"
15869 "{\n"
15870 " vec4 result = gs_fs;\n"
15871 "\n"
15872 "VARIABLE_USE"
15873 "\n"
15874 " fs_out += result;\n"
15875 "}\n"
15876 "\n";
15877 static const GLchar *gs = "#version 430 core\n"
15878 "#extension GL_ARB_enhanced_layouts : require\n"
15879 "\n"
15880 "layout(points) in;\n"
15881 "layout(triangle_strip, max_vertices = 4) out;\n"
15882 "\n"
15883 "in vec4 tes_gs[];\n"
15884 "out vec4 gs_fs;\n"
15885 "\n"
15886 "void main()\n"
15887 "{\n"
15888 " gs_fs = tes_gs[0];\n"
15889 " gl_Position = vec4(-1, -1, 0, 1);\n"
15890 " EmitVertex();\n"
15891 " gs_fs = tes_gs[0];\n"
15892 " gl_Position = vec4(-1, 1, 0, 1);\n"
15893 " EmitVertex();\n"
15894 " gs_fs = tes_gs[0];\n"
15895 " gl_Position = vec4(1, -1, 0, 1);\n"
15896 " EmitVertex();\n"
15897 " gs_fs = tes_gs[0];\n"
15898 " gl_Position = vec4(1, 1, 0, 1);\n"
15899 " EmitVertex();\n"
15900 "}\n"
15901 "\n";
15902 static const GLchar *gs_tested = "#version 430 core\n"
15903 "#extension GL_ARB_enhanced_layouts : require\n"
15904 "\n"
15905 "layout(points) in;\n"
15906 "layout(triangle_strip, max_vertices = 4) out;\n"
15907 "\n"
15908 "VAR_DEFINITION"
15909 "\n"
15910 "in vec4 tes_gs[];\n"
15911 "out vec4 gs_fs;\n"
15912 "\n"
15913 "void main()\n"
15914 "{\n"
15915 " vec4 result = tes_gs[0];\n"
15916 "\n"
15917 "VARIABLE_USE"
15918 "\n"
15919 " gs_fs = result;\n"
15920 " gl_Position = vec4(-1, -1, 0, 1);\n"
15921 " EmitVertex();\n"
15922 " gs_fs = result;\n"
15923 " gl_Position = vec4(-1, 1, 0, 1);\n"
15924 " EmitVertex();\n"
15925 " gs_fs = result;\n"
15926 " gl_Position = vec4(1, -1, 0, 1);\n"
15927 " EmitVertex();\n"
15928 " gs_fs = result;\n"
15929 " gl_Position = vec4(1, 1, 0, 1);\n"
15930 " EmitVertex();\n"
15931 "}\n"
15932 "\n";
15933 static const GLchar *tcs = "#version 430 core\n"
15934 "#extension GL_ARB_enhanced_layouts : require\n"
15935 "\n"
15936 "layout(vertices = 1) out;\n"
15937 "\n"
15938 "in vec4 vs_tcs[];\n"
15939 "out vec4 tcs_tes[];\n"
15940 "\n"
15941 "void main()\n"
15942 "{\n"
15943 "\n"
15944 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15945 "\n"
15946 " gl_TessLevelOuter[0] = 1.0;\n"
15947 " gl_TessLevelOuter[1] = 1.0;\n"
15948 " gl_TessLevelOuter[2] = 1.0;\n"
15949 " gl_TessLevelOuter[3] = 1.0;\n"
15950 " gl_TessLevelInner[0] = 1.0;\n"
15951 " gl_TessLevelInner[1] = 1.0;\n"
15952 "}\n"
15953 "\n";
15954 static const GLchar *tcs_tested = "#version 430 core\n"
15955 "#extension GL_ARB_enhanced_layouts : require\n"
15956 "\n"
15957 "layout(vertices = 1) out;\n"
15958 "\n"
15959 "VAR_DEFINITION"
15960 "\n"
15961 "in vec4 vs_tcs[];\n"
15962 "out vec4 tcs_tes[];\n"
15963 "\n"
15964 "void main()\n"
15965 "{\n"
15966 " vec4 result = vs_tcs[gl_InvocationID];\n"
15967 "\n"
15968 "VARIABLE_USE"
15969 "\n"
15970 " tcs_tes[gl_InvocationID] = result;\n"
15971 "\n"
15972 " gl_TessLevelOuter[0] = 1.0;\n"
15973 " gl_TessLevelOuter[1] = 1.0;\n"
15974 " gl_TessLevelOuter[2] = 1.0;\n"
15975 " gl_TessLevelOuter[3] = 1.0;\n"
15976 " gl_TessLevelInner[0] = 1.0;\n"
15977 " gl_TessLevelInner[1] = 1.0;\n"
15978 "}\n"
15979 "\n";
15980 static const GLchar *tes = "#version 430 core\n"
15981 "#extension GL_ARB_enhanced_layouts : require\n"
15982 "\n"
15983 "layout(isolines, point_mode) in;\n"
15984 "\n"
15985 "in vec4 tcs_tes[];\n"
15986 "out vec4 tes_gs;\n"
15987 "\n"
15988 "void main()\n"
15989 "{\n"
15990 " tes_gs = tcs_tes[0];\n"
15991 "}\n"
15992 "\n";
15993 static const GLchar *tes_tested = "#version 430 core\n"
15994 "#extension GL_ARB_enhanced_layouts : require\n"
15995 "\n"
15996 "layout(isolines, point_mode) in;\n"
15997 "\n"
15998 "VAR_DEFINITION"
15999 "\n"
16000 "in vec4 tcs_tes[];\n"
16001 "out vec4 tes_gs;\n"
16002 "\n"
16003 "void main()\n"
16004 "{\n"
16005 " vec4 result = tcs_tes[0];\n"
16006 "\n"
16007 "VARIABLE_USE"
16008 "\n"
16009 " tes_gs += result;\n"
16010 "}\n"
16011 "\n";
16012 static const GLchar *vs = "#version 430 core\n"
16013 "#extension GL_ARB_enhanced_layouts : require\n"
16014 "\n"
16015 "in vec4 in_vs;\n"
16016 "out vec4 vs_tcs;\n"
16017 "\n"
16018 "void main()\n"
16019 "{\n"
16020 " vs_tcs = in_vs;\n"
16021 "}\n"
16022 "\n";
16023 static const GLchar *vs_tested = "#version 430 core\n"
16024 "#extension GL_ARB_enhanced_layouts : require\n"
16025 "\n"
16026 "VAR_DEFINITION"
16027 "\n"
16028 "in vec4 in_vs;\n"
16029 "out vec4 vs_tcs;\n"
16030 "\n"
16031 "void main()\n"
16032 "{\n"
16033 " vec4 result = in_vs;\n"
16034 "\n"
16035 "VARIABLE_USE"
16036 "\n"
16037 " vs_tcs += result;\n"
16038 "}\n"
16039 "\n";
16040
16041 std::string source;
16042 testCase &test_case = m_test_cases[test_case_index];
16043
16044 if (test_case.m_stage == stage)
16045 {
16046 const GLchar *array = "";
16047 const GLchar *var_definition = 0;
16048 const GLchar *direction = "in";
16049 const GLchar *index = "";
16050 size_t position = 0;
16051 const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
16052 const GLchar *var_use = 0;
16053 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
16054 const GLchar *flat = "";
16055
16056 if (false == test_case.m_is_input)
16057 {
16058 direction = "out";
16059 storage = Utils::Variable::VARYING_OUTPUT;
16060
16061 if (false == test_case.m_is_array)
16062 {
16063 var_definition = var_definition_one;
16064 var_use = output_use_one;
16065 }
16066 else
16067 {
16068 var_definition = var_definition_arr;
16069 var_use = output_use_arr;
16070 }
16071 }
16072 else
16073 {
16074 if (false == test_case.m_is_array)
16075 {
16076 var_definition = var_definition_one;
16077 var_use = Utils::Shader::VERTEX == stage ? input_use_one : "\n";
16078 }
16079 else
16080 {
16081 var_definition = var_definition_arr;
16082 var_use = Utils::Shader::VERTEX == stage ? input_use_arr : "\n";
16083 }
16084 }
16085
16086 if (isFlatRequired(stage, test_case.m_type, storage, true))
16087 {
16088 flat = "flat";
16089 }
16090
16091 switch (stage)
16092 {
16093 case Utils::Shader::FRAGMENT:
16094 source = fs_tested;
16095 break;
16096 case Utils::Shader::GEOMETRY:
16097 source = gs_tested;
16098 array = test_case.m_is_input ? "[]" : "";
16099 index = test_case.m_is_input ? "[0]" : "";
16100 break;
16101 case Utils::Shader::TESS_CTRL:
16102 source = tcs_tested;
16103 array = "[]";
16104 index = "[gl_InvocationID]";
16105 break;
16106 case Utils::Shader::TESS_EVAL:
16107 source = tes_tested;
16108 array = test_case.m_is_input ? "[]" : "";
16109 index = test_case.m_is_input ? "[0]" : "";
16110 break;
16111 case Utils::Shader::VERTEX:
16112 source = vs_tested;
16113 break;
16114 default:
16115 TCU_FAIL("Invalid enum");
16116 }
16117
16118 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16119 position = 0;
16120 Utils::replaceToken("FLAT", position, flat, source);
16121 Utils::replaceToken("DIRECTION", position, direction, source);
16122 Utils::replaceToken("ARRAY", position, array, source);
16123 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16124
16125 Utils::replaceAllTokens("TYPE", type_name, source);
16126 Utils::replaceAllTokens("INDEX", index, source);
16127 }
16128 else
16129 {
16130 switch (stage)
16131 {
16132 case Utils::Shader::FRAGMENT:
16133 source = fs;
16134 break;
16135 case Utils::Shader::GEOMETRY:
16136 source = gs;
16137 break;
16138 case Utils::Shader::TESS_CTRL:
16139 source = tcs;
16140 break;
16141 case Utils::Shader::TESS_EVAL:
16142 source = tes;
16143 break;
16144 case Utils::Shader::VERTEX:
16145 source = vs;
16146 break;
16147 default:
16148 TCU_FAIL("Invalid enum");
16149 }
16150 }
16151
16152 return source;
16153 }
16154
16155 /** Get description of test case
16156 *
16157 * @param test_case_index Index of test case
16158 *
16159 * @return Test case description
16160 **/
16161 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index)
16162 {
16163 std::stringstream stream;
16164 testCase &test_case = m_test_cases[test_case_index];
16165
16166 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16167 << " type: " << test_case.m_type.GetGLSLTypeName();
16168
16169 if (true == test_case.m_is_array)
16170 {
16171 stream << "[1]";
16172 }
16173
16174 stream << ", direction: ";
16175
16176 if (true == test_case.m_is_input)
16177 {
16178 stream << "input";
16179 }
16180 else
16181 {
16182 stream << "output";
16183 }
16184
16185 return stream.str();
16186 }
16187
16188 /** Get number of test cases
16189 *
16190 * @return Number of test cases
16191 **/
16192 GLuint VaryingExceedingComponentsTest::getTestCaseNumber()
16193 {
16194 return static_cast<GLuint>(m_test_cases.size());
16195 }
16196
16197 /** Selects if "compute" stage is relevant for test
16198 *
16199 * @param ignored
16200 *
16201 * @return false
16202 **/
16203 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */)
16204 {
16205 return false;
16206 }
16207
16208 /** Prepare all test cases
16209 *
16210 **/
16211 void VaryingExceedingComponentsTest::testInit()
16212 {
16213 const GLuint n_types = getTypesNumber();
16214
16215 for (GLuint i = 0; i < n_types; ++i)
16216 {
16217 const Utils::Type &type = getType(i);
16218 const std::vector<GLuint> &valid_components = type.GetValidComponents();
16219
16220 if (valid_components.empty())
16221 {
16222 continue;
16223 }
16224
16225 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16226 {
16227 if (Utils::Shader::COMPUTE == stage)
16228 {
16229 continue;
16230 }
16231
16232 testCase test_case_in_arr = {true, true, (Utils::Shader::STAGES)stage, type};
16233 testCase test_case_in_one = {true, false, (Utils::Shader::STAGES)stage, type};
16234 testCase test_case_out_arr = {false, true, (Utils::Shader::STAGES)stage, type};
16235 testCase test_case_out_one = {false, false, (Utils::Shader::STAGES)stage, type};
16236
16237 m_test_cases.push_back(test_case_in_arr);
16238 m_test_cases.push_back(test_case_in_one);
16239
16240 if (Utils::Shader::FRAGMENT != stage)
16241 {
16242 m_test_cases.push_back(test_case_out_arr);
16243 m_test_cases.push_back(test_case_out_one);
16244 }
16245 }
16246 }
16247 }
16248
16249 /** Constructor
16250 *
16251 * @param context Test framework context
16252 **/
16253 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context &context)
16254 : NegativeTestBase(context, "varying_component_without_location",
16255 "Test verifies that compiler reports error when component qualifier is used without location")
16256 {
16257 }
16258
16259 /** Source for given test case and stage
16260 *
16261 * @param test_case_index Index of test case
16262 * @param stage Shader stage
16263 *
16264 * @return Shader source
16265 **/
16266 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16267 {
16268 #if DEBUG_NEG_REMOVE_ERROR
16269 static const GLchar *var_definition = "/* layout (component = COMPONENT) */ FLAT DIRECTION TYPE gokuARRAY;\n";
16270 #else
16271 static const GLchar *var_definition = "layout (component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
16272 #endif /* DEBUG_NEG_REMOVE_ERROR */
16273 static const GLchar *input_use = " if (TYPE(0) == gokuINDEX)\n"
16274 " {\n"
16275 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16276 " }\n";
16277 static const GLchar *output_use = " gokuINDEX = TYPE(0);\n"
16278 " if (vec4(0) == result)\n"
16279 " {\n"
16280 " gokuINDEX = TYPE(1);\n"
16281 " }\n";
16282 static const GLchar *fs = "#version 430 core\n"
16283 "#extension GL_ARB_enhanced_layouts : require\n"
16284 "\n"
16285 "in vec4 gs_fs;\n"
16286 "out vec4 fs_out;\n"
16287 "\n"
16288 "void main()\n"
16289 "{\n"
16290 " fs_out = gs_fs;\n"
16291 "}\n"
16292 "\n";
16293 static const GLchar *fs_tested = "#version 430 core\n"
16294 "#extension GL_ARB_enhanced_layouts : require\n"
16295 "\n"
16296 "VAR_DEFINITION"
16297 "\n"
16298 "in vec4 gs_fs;\n"
16299 "out vec4 fs_out;\n"
16300 "\n"
16301 "void main()\n"
16302 "{\n"
16303 " vec4 result = gs_fs;\n"
16304 "\n"
16305 "VARIABLE_USE"
16306 "\n"
16307 " fs_out = result;\n"
16308 "}\n"
16309 "\n";
16310 static const GLchar *gs = "#version 430 core\n"
16311 "#extension GL_ARB_enhanced_layouts : require\n"
16312 "\n"
16313 "layout(points) in;\n"
16314 "layout(triangle_strip, max_vertices = 4) out;\n"
16315 "\n"
16316 "in vec4 tes_gs[];\n"
16317 "out vec4 gs_fs;\n"
16318 "\n"
16319 "void main()\n"
16320 "{\n"
16321 " gs_fs = tes_gs[0];\n"
16322 " gl_Position = vec4(-1, -1, 0, 1);\n"
16323 " EmitVertex();\n"
16324 " gs_fs = tes_gs[0];\n"
16325 " gl_Position = vec4(-1, 1, 0, 1);\n"
16326 " EmitVertex();\n"
16327 " gs_fs = tes_gs[0];\n"
16328 " gl_Position = vec4(1, -1, 0, 1);\n"
16329 " EmitVertex();\n"
16330 " gs_fs = tes_gs[0];\n"
16331 " gl_Position = vec4(1, 1, 0, 1);\n"
16332 " EmitVertex();\n"
16333 "}\n"
16334 "\n";
16335 static const GLchar *gs_tested = "#version 430 core\n"
16336 "#extension GL_ARB_enhanced_layouts : require\n"
16337 "\n"
16338 "layout(points) in;\n"
16339 "layout(triangle_strip, max_vertices = 4) out;\n"
16340 "\n"
16341 "VAR_DEFINITION"
16342 "\n"
16343 "in vec4 tes_gs[];\n"
16344 "out vec4 gs_fs;\n"
16345 "\n"
16346 "void main()\n"
16347 "{\n"
16348 " vec4 result = tes_gs[0];\n"
16349 "\n"
16350 "VARIABLE_USE"
16351 "\n"
16352 " gs_fs = result;\n"
16353 " gl_Position = vec4(-1, -1, 0, 1);\n"
16354 " EmitVertex();\n"
16355 " gs_fs = result;\n"
16356 " gl_Position = vec4(-1, 1, 0, 1);\n"
16357 " EmitVertex();\n"
16358 " gs_fs = result;\n"
16359 " gl_Position = vec4(1, -1, 0, 1);\n"
16360 " EmitVertex();\n"
16361 " gs_fs = result;\n"
16362 " gl_Position = vec4(1, 1, 0, 1);\n"
16363 " EmitVertex();\n"
16364 "}\n"
16365 "\n";
16366 static const GLchar *tcs = "#version 430 core\n"
16367 "#extension GL_ARB_enhanced_layouts : require\n"
16368 "\n"
16369 "layout(vertices = 1) out;\n"
16370 "\n"
16371 "in vec4 vs_tcs[];\n"
16372 "out vec4 tcs_tes[];\n"
16373 "\n"
16374 "void main()\n"
16375 "{\n"
16376 "\n"
16377 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16378 "\n"
16379 " gl_TessLevelOuter[0] = 1.0;\n"
16380 " gl_TessLevelOuter[1] = 1.0;\n"
16381 " gl_TessLevelOuter[2] = 1.0;\n"
16382 " gl_TessLevelOuter[3] = 1.0;\n"
16383 " gl_TessLevelInner[0] = 1.0;\n"
16384 " gl_TessLevelInner[1] = 1.0;\n"
16385 "}\n"
16386 "\n";
16387 static const GLchar *tcs_tested = "#version 430 core\n"
16388 "#extension GL_ARB_enhanced_layouts : require\n"
16389 "\n"
16390 "layout(vertices = 1) out;\n"
16391 "\n"
16392 "VAR_DEFINITION"
16393 "\n"
16394 "in vec4 vs_tcs[];\n"
16395 "out vec4 tcs_tes[];\n"
16396 "\n"
16397 "void main()\n"
16398 "{\n"
16399 " vec4 result = vs_tcs[gl_InvocationID];\n"
16400 "\n"
16401 "VARIABLE_USE"
16402 "\n"
16403 " tcs_tes[gl_InvocationID] = result;\n"
16404 "\n"
16405 " gl_TessLevelOuter[0] = 1.0;\n"
16406 " gl_TessLevelOuter[1] = 1.0;\n"
16407 " gl_TessLevelOuter[2] = 1.0;\n"
16408 " gl_TessLevelOuter[3] = 1.0;\n"
16409 " gl_TessLevelInner[0] = 1.0;\n"
16410 " gl_TessLevelInner[1] = 1.0;\n"
16411 "}\n"
16412 "\n";
16413 static const GLchar *tes = "#version 430 core\n"
16414 "#extension GL_ARB_enhanced_layouts : require\n"
16415 "\n"
16416 "layout(isolines, point_mode) in;\n"
16417 "\n"
16418 "in vec4 tcs_tes[];\n"
16419 "out vec4 tes_gs;\n"
16420 "\n"
16421 "void main()\n"
16422 "{\n"
16423 " tes_gs = tcs_tes[0];\n"
16424 "}\n"
16425 "\n";
16426 static const GLchar *tes_tested = "#version 430 core\n"
16427 "#extension GL_ARB_enhanced_layouts : require\n"
16428 "\n"
16429 "layout(isolines, point_mode) in;\n"
16430 "\n"
16431 "VAR_DEFINITION"
16432 "\n"
16433 "in vec4 tcs_tes[];\n"
16434 "out vec4 tes_gs;\n"
16435 "\n"
16436 "void main()\n"
16437 "{\n"
16438 " vec4 result = tcs_tes[0];\n"
16439 "\n"
16440 "VARIABLE_USE"
16441 "\n"
16442 " tes_gs = result;\n"
16443 "}\n"
16444 "\n";
16445 static const GLchar *vs = "#version 430 core\n"
16446 "#extension GL_ARB_enhanced_layouts : require\n"
16447 "\n"
16448 "in vec4 in_vs;\n"
16449 "out vec4 vs_tcs;\n"
16450 "\n"
16451 "void main()\n"
16452 "{\n"
16453 " vs_tcs = in_vs;\n"
16454 "}\n"
16455 "\n";
16456 static const GLchar *vs_tested = "#version 430 core\n"
16457 "#extension GL_ARB_enhanced_layouts : require\n"
16458 "\n"
16459 "VAR_DEFINITION"
16460 "\n"
16461 "in vec4 in_vs;\n"
16462 "out vec4 vs_tcs;\n"
16463 "\n"
16464 "void main()\n"
16465 "{\n"
16466 " vec4 result = in_vs;\n"
16467 "\n"
16468 "VARIABLE_USE"
16469 "\n"
16470 " vs_tcs = result;\n"
16471 "}\n"
16472 "\n";
16473
16474 std::string source;
16475 testCase &test_case = m_test_cases[test_case_index];
16476
16477 if (test_case.m_stage == stage)
16478 {
16479 const GLchar *array = "";
16480 GLchar buffer[16];
16481 const GLchar *direction = "in";
16482 const GLchar *index = "";
16483 size_t position = 0;
16484 const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
16485 const GLchar *var_use = Utils::Shader::VERTEX == stage ? input_use : "\n";
16486 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
16487 const GLchar *flat = "";
16488
16489 if (false == test_case.m_is_input)
16490 {
16491 direction = "out";
16492 storage = Utils::Variable::VARYING_OUTPUT;
16493 var_use = output_use;
16494 }
16495
16496 if (isFlatRequired(stage, test_case.m_type, storage, true))
16497 {
16498 flat = "flat";
16499 }
16500
16501 sprintf(buffer, "%d", test_case.m_component);
16502
16503 switch (stage)
16504 {
16505 case Utils::Shader::FRAGMENT:
16506 source = fs_tested;
16507 break;
16508 case Utils::Shader::GEOMETRY:
16509 source = gs_tested;
16510 array = test_case.m_is_input ? "[]" : "";
16511 index = test_case.m_is_input ? "[0]" : "";
16512 break;
16513 case Utils::Shader::TESS_CTRL:
16514 source = tcs_tested;
16515 array = "[]";
16516 index = "[gl_InvocationID]";
16517 break;
16518 case Utils::Shader::TESS_EVAL:
16519 source = tes_tested;
16520 array = test_case.m_is_input ? "[]" : "";
16521 index = test_case.m_is_input ? "[0]" : "";
16522 break;
16523 case Utils::Shader::VERTEX:
16524 source = vs_tested;
16525 break;
16526 default:
16527 TCU_FAIL("Invalid enum");
16528 }
16529
16530 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16531 position = 0;
16532 Utils::replaceToken("COMPONENT", position, buffer, source);
16533 Utils::replaceToken("FLAT", position, flat, source);
16534 Utils::replaceToken("DIRECTION", position, direction, source);
16535 Utils::replaceToken("ARRAY", position, array, source);
16536 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16537
16538 Utils::replaceAllTokens("TYPE", type_name, source);
16539 Utils::replaceAllTokens("INDEX", index, source);
16540 }
16541 else
16542 {
16543 switch (stage)
16544 {
16545 case Utils::Shader::FRAGMENT:
16546 source = fs;
16547 break;
16548 case Utils::Shader::GEOMETRY:
16549 source = gs;
16550 break;
16551 case Utils::Shader::TESS_CTRL:
16552 source = tcs;
16553 break;
16554 case Utils::Shader::TESS_EVAL:
16555 source = tes;
16556 break;
16557 case Utils::Shader::VERTEX:
16558 source = vs;
16559 break;
16560 default:
16561 TCU_FAIL("Invalid enum");
16562 }
16563 }
16564
16565 return source;
16566 }
16567
16568 /** Get description of test case
16569 *
16570 * @param test_case_index Index of test case
16571 *
16572 * @return Test case description
16573 **/
16574 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index)
16575 {
16576 std::stringstream stream;
16577 testCase &test_case = m_test_cases[test_case_index];
16578
16579 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16580 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
16581
16582 if (true == test_case.m_is_input)
16583 {
16584 stream << "input";
16585 }
16586 else
16587 {
16588 stream << "output";
16589 }
16590
16591 stream << ", component: " << test_case.m_component;
16592
16593 return stream.str();
16594 }
16595
16596 /** Get number of test cases
16597 *
16598 * @return Number of test cases
16599 **/
16600 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber()
16601 {
16602 return static_cast<GLuint>(m_test_cases.size());
16603 }
16604
16605 /** Selects if "compute" stage is relevant for test
16606 *
16607 * @param ignored
16608 *
16609 * @return false
16610 **/
16611 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */)
16612 {
16613 return false;
16614 }
16615
16616 /** Prepare all test cases
16617 *
16618 **/
16619 void VaryingComponentWithoutLocationTest::testInit()
16620 {
16621 const GLuint n_types = getTypesNumber();
16622
16623 for (GLuint i = 0; i < n_types; ++i)
16624 {
16625 const Utils::Type &type = getType(i);
16626 const std::vector<GLuint> &valid_components = type.GetValidComponents();
16627
16628 if (valid_components.empty())
16629 {
16630 continue;
16631 }
16632
16633 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16634 {
16635 if (Utils::Shader::COMPUTE == stage)
16636 {
16637 continue;
16638 }
16639
16640 testCase test_case_in = {valid_components.back(), true, (Utils::Shader::STAGES)stage, type};
16641 testCase test_case_out = {valid_components.back(), false, (Utils::Shader::STAGES)stage, type};
16642
16643 m_test_cases.push_back(test_case_in);
16644
16645 if (Utils::Shader::FRAGMENT != stage)
16646 {
16647 m_test_cases.push_back(test_case_out);
16648 }
16649 }
16650 }
16651 }
16652
16653 /** Constructor
16654 *
16655 * @param context Test framework context
16656 **/
16657 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context &context)
16658 : NegativeTestBase(context, "varying_component_of_invalid_type",
16659 "Test verifies that compiler reports error when component qualifier is used for invalid type")
16660 {
16661 }
16662
16663 /** Source for given test case and stage
16664 *
16665 * @param test_case_index Index of test case
16666 * @param stage Shader stage
16667 *
16668 * @return Shader source
16669 **/
16670 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16671 {
16672 static const GLchar *block_definition_arr = "layout (location = 1COMPONENT) DIRECTION Goku {\n"
16673 " FLAT TYPE member;\n"
16674 "} gokuARRAY[1];\n";
16675 static const GLchar *block_definition_one = "layout (location = 1COMPONENT) DIRECTION Goku {\n"
16676 " FLAT TYPE member;\n"
16677 "} gokuARRAY;\n";
16678 static const GLchar *matrix_dvec3_dvec4_definition_arr =
16679 "layout (location = 1COMPONENT) FLAT DIRECTION TYPE gokuARRAY[1];\n";
16680 static const GLchar *matrix_dvec3_dvec4_definition_one =
16681 "layout (location = 1COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
16682 static const GLchar *struct_definition_arr = "struct Goku {\n"
16683 " TYPE member;\n"
16684 "};\n"
16685 "\n"
16686 "layout (location = 1COMPONENT) FLAT DIRECTION Goku gokuARRAY[1];\n";
16687 static const GLchar *struct_definition_one = "struct Goku {\n"
16688 " TYPE member;\n"
16689 "};\n"
16690 "\n"
16691 "layout (location = 1COMPONENT) FLAT DIRECTION Goku gokuARRAY;\n";
16692 static const GLchar *matrix_dvec3_dvec4_input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
16693 " {\n"
16694 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16695 " }\n";
16696 static const GLchar *matrix_dvec3_dvec4_input_use_one = " if (TYPE(0) == gokuINDEX)\n"
16697 " {\n"
16698 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16699 " }\n";
16700 static const GLchar *matrix_dvec3_dvec4_output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
16701 " if (vec4(0) == result)\n"
16702 " {\n"
16703 " gokuINDEX[0] = TYPE(1);\n"
16704 " }\n";
16705 static const GLchar *matrix_dvec3_dvec4_output_use_one = " gokuINDEX = TYPE(0);\n"
16706 " if (vec4(0) == result)\n"
16707 " {\n"
16708 " gokuINDEX = TYPE(1);\n"
16709 " }\n";
16710 static const GLchar *member_input_use_arr = " if (TYPE(0) == gokuINDEX[0].member)\n"
16711 " {\n"
16712 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16713 " }\n";
16714 static const GLchar *member_input_use_one = " if (TYPE(0) == gokuINDEX.member)\n"
16715 " {\n"
16716 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16717 " }\n";
16718 static const GLchar *member_output_use_arr = " gokuINDEX[0].member = TYPE(0);\n"
16719 " if (vec4(0) == result)\n"
16720 " {\n"
16721 " gokuINDEX[0].member = TYPE(1);\n"
16722 " }\n";
16723 static const GLchar *member_output_use_one = " gokuINDEX.member = TYPE(0);\n"
16724 " if (vec4(0) == result)\n"
16725 " {\n"
16726 " gokuINDEX.member = TYPE(1);\n"
16727 " }\n";
16728 static const GLchar *fs = "#version 430 core\n"
16729 "#extension GL_ARB_enhanced_layouts : require\n"
16730 "\n"
16731 "in vec4 gs_fs;\n"
16732 "out vec4 fs_out;\n"
16733 "\n"
16734 "void main()\n"
16735 "{\n"
16736 " fs_out = gs_fs;\n"
16737 "}\n"
16738 "\n";
16739 static const GLchar *fs_tested = "#version 430 core\n"
16740 "#extension GL_ARB_enhanced_layouts : require\n"
16741 "\n"
16742 "VAR_DEFINITION"
16743 "\n"
16744 "in vec4 gs_fs;\n"
16745 "out vec4 fs_out;\n"
16746 "\n"
16747 "void main()\n"
16748 "{\n"
16749 " vec4 result = gs_fs;\n"
16750 "\n"
16751 "VARIABLE_USE"
16752 "\n"
16753 " fs_out += result;\n"
16754 "}\n"
16755 "\n";
16756 static const GLchar *gs = "#version 430 core\n"
16757 "#extension GL_ARB_enhanced_layouts : require\n"
16758 "\n"
16759 "layout(points) in;\n"
16760 "layout(triangle_strip, max_vertices = 4) out;\n"
16761 "\n"
16762 "in vec4 tes_gs[];\n"
16763 "out vec4 gs_fs;\n"
16764 "\n"
16765 "void main()\n"
16766 "{\n"
16767 " gs_fs = tes_gs[0];\n"
16768 " gl_Position = vec4(-1, -1, 0, 1);\n"
16769 " EmitVertex();\n"
16770 " gs_fs = tes_gs[0];\n"
16771 " gl_Position = vec4(-1, 1, 0, 1);\n"
16772 " EmitVertex();\n"
16773 " gs_fs = tes_gs[0];\n"
16774 " gl_Position = vec4(1, -1, 0, 1);\n"
16775 " EmitVertex();\n"
16776 " gs_fs = tes_gs[0];\n"
16777 " gl_Position = vec4(1, 1, 0, 1);\n"
16778 " EmitVertex();\n"
16779 "}\n"
16780 "\n";
16781 static const GLchar *gs_tested = "#version 430 core\n"
16782 "#extension GL_ARB_enhanced_layouts : require\n"
16783 "\n"
16784 "layout(points) in;\n"
16785 "layout(triangle_strip, max_vertices = 4) out;\n"
16786 "\n"
16787 "VAR_DEFINITION"
16788 "\n"
16789 "in vec4 tes_gs[];\n"
16790 "out vec4 gs_fs;\n"
16791 "\n"
16792 "void main()\n"
16793 "{\n"
16794 " vec4 result = tes_gs[0];\n"
16795 "\n"
16796 "VARIABLE_USE"
16797 "\n"
16798 " gs_fs = result;\n"
16799 " gl_Position = vec4(-1, -1, 0, 1);\n"
16800 " EmitVertex();\n"
16801 " gs_fs = result;\n"
16802 " gl_Position = vec4(-1, 1, 0, 1);\n"
16803 " EmitVertex();\n"
16804 " gs_fs = result;\n"
16805 " gl_Position = vec4(1, -1, 0, 1);\n"
16806 " EmitVertex();\n"
16807 " gs_fs = result;\n"
16808 " gl_Position = vec4(1, 1, 0, 1);\n"
16809 " EmitVertex();\n"
16810 "}\n"
16811 "\n";
16812 static const GLchar *tcs = "#version 430 core\n"
16813 "#extension GL_ARB_enhanced_layouts : require\n"
16814 "\n"
16815 "layout(vertices = 1) out;\n"
16816 "\n"
16817 "in vec4 vs_tcs[];\n"
16818 "out vec4 tcs_tes[];\n"
16819 "\n"
16820 "void main()\n"
16821 "{\n"
16822 "\n"
16823 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16824 "\n"
16825 " gl_TessLevelOuter[0] = 1.0;\n"
16826 " gl_TessLevelOuter[1] = 1.0;\n"
16827 " gl_TessLevelOuter[2] = 1.0;\n"
16828 " gl_TessLevelOuter[3] = 1.0;\n"
16829 " gl_TessLevelInner[0] = 1.0;\n"
16830 " gl_TessLevelInner[1] = 1.0;\n"
16831 "}\n"
16832 "\n";
16833 static const GLchar *tcs_tested = "#version 430 core\n"
16834 "#extension GL_ARB_enhanced_layouts : require\n"
16835 "\n"
16836 "layout(vertices = 1) out;\n"
16837 "\n"
16838 "VAR_DEFINITION"
16839 "\n"
16840 "in vec4 vs_tcs[];\n"
16841 "out vec4 tcs_tes[];\n"
16842 "\n"
16843 "void main()\n"
16844 "{\n"
16845 " vec4 result = vs_tcs[gl_InvocationID];\n"
16846 "\n"
16847 "VARIABLE_USE"
16848 "\n"
16849 " tcs_tes[gl_InvocationID] = result;\n"
16850 "\n"
16851 " gl_TessLevelOuter[0] = 1.0;\n"
16852 " gl_TessLevelOuter[1] = 1.0;\n"
16853 " gl_TessLevelOuter[2] = 1.0;\n"
16854 " gl_TessLevelOuter[3] = 1.0;\n"
16855 " gl_TessLevelInner[0] = 1.0;\n"
16856 " gl_TessLevelInner[1] = 1.0;\n"
16857 "}\n"
16858 "\n";
16859 static const GLchar *tes = "#version 430 core\n"
16860 "#extension GL_ARB_enhanced_layouts : require\n"
16861 "\n"
16862 "layout(isolines, point_mode) in;\n"
16863 "\n"
16864 "in vec4 tcs_tes[];\n"
16865 "out vec4 tes_gs;\n"
16866 "\n"
16867 "void main()\n"
16868 "{\n"
16869 " tes_gs = tcs_tes[0];\n"
16870 "}\n"
16871 "\n";
16872 static const GLchar *tes_tested = "#version 430 core\n"
16873 "#extension GL_ARB_enhanced_layouts : require\n"
16874 "\n"
16875 "layout(isolines, point_mode) in;\n"
16876 "\n"
16877 "VAR_DEFINITION"
16878 "\n"
16879 "in vec4 tcs_tes[];\n"
16880 "out vec4 tes_gs;\n"
16881 "\n"
16882 "void main()\n"
16883 "{\n"
16884 " vec4 result = tcs_tes[0];\n"
16885 "\n"
16886 "VARIABLE_USE"
16887 "\n"
16888 " tes_gs += result;\n"
16889 "}\n"
16890 "\n";
16891 static const GLchar *vs = "#version 430 core\n"
16892 "#extension GL_ARB_enhanced_layouts : require\n"
16893 "\n"
16894 "in vec4 in_vs;\n"
16895 "out vec4 vs_tcs;\n"
16896 "\n"
16897 "void main()\n"
16898 "{\n"
16899 " vs_tcs = in_vs;\n"
16900 "}\n"
16901 "\n";
16902 static const GLchar *vs_tested = "#version 430 core\n"
16903 "#extension GL_ARB_enhanced_layouts : require\n"
16904 "\n"
16905 "VAR_DEFINITION"
16906 "\n"
16907 "in vec4 in_vs;\n"
16908 "out vec4 vs_tcs;\n"
16909 "\n"
16910 "void main()\n"
16911 "{\n"
16912 " vec4 result = in_vs;\n"
16913 "\n"
16914 "VARIABLE_USE"
16915 "\n"
16916 " vs_tcs += result;\n"
16917 "}\n"
16918 "\n";
16919
16920 std::string source;
16921 testCase &test_case = m_test_cases[test_case_index];
16922
16923 if (test_case.m_stage == stage)
16924 {
16925 const GLchar *array = "";
16926 GLchar buffer[32];
16927 const GLchar *var_definition = 0;
16928 const GLchar *direction = "in ";
16929 const GLchar *index = "";
16930 size_t position = 0;
16931 const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
16932 const GLchar *var_use = 0;
16933 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
16934 const GLchar *flat = "";
16935
16936 if (false == test_case.m_is_input)
16937 {
16938 direction = "out";
16939 storage = Utils::Variable::VARYING_OUTPUT;
16940
16941 if (false == test_case.m_is_array)
16942 {
16943 switch (test_case.m_case)
16944 {
16945 case BLOCK:
16946 var_definition = block_definition_one;
16947 var_use = member_output_use_one;
16948 break;
16949 case MATRIX:
16950 case DVEC3_DVEC4:
16951 var_definition = matrix_dvec3_dvec4_definition_one;
16952 var_use = matrix_dvec3_dvec4_output_use_one;
16953 break;
16954 case STRUCT:
16955 var_definition = struct_definition_one;
16956 var_use = member_output_use_one;
16957 break;
16958 default:
16959 TCU_FAIL("Invalid enum");
16960 }
16961 }
16962 else
16963 {
16964 switch (test_case.m_case)
16965 {
16966 case BLOCK:
16967 var_definition = block_definition_arr;
16968 var_use = member_output_use_arr;
16969 break;
16970 case MATRIX:
16971 case DVEC3_DVEC4:
16972 var_definition = matrix_dvec3_dvec4_definition_arr;
16973 var_use = matrix_dvec3_dvec4_output_use_arr;
16974 break;
16975 case STRUCT:
16976 var_definition = struct_definition_arr;
16977 var_use = member_output_use_arr;
16978 break;
16979 default:
16980 TCU_FAIL("Invalid enum");
16981 }
16982 }
16983 }
16984 else
16985 {
16986 if (false == test_case.m_is_array)
16987 {
16988 switch (test_case.m_case)
16989 {
16990 case BLOCK:
16991 var_definition = block_definition_one;
16992 var_use = Utils::Shader::VERTEX == stage ? member_input_use_one : "\n";
16993 break;
16994 case MATRIX:
16995 case DVEC3_DVEC4:
16996 var_definition = matrix_dvec3_dvec4_definition_one;
16997 var_use = Utils::Shader::VERTEX == stage ? matrix_dvec3_dvec4_input_use_one : "\n";
16998 break;
16999 case STRUCT:
17000 var_definition = struct_definition_one;
17001 var_use = Utils::Shader::VERTEX == stage ? member_input_use_one : "\n";
17002 break;
17003 default:
17004 TCU_FAIL("Invalid enum");
17005 }
17006 }
17007 else
17008 {
17009 switch (test_case.m_case)
17010 {
17011 case BLOCK:
17012 var_definition = block_definition_arr;
17013 var_use = Utils::Shader::VERTEX == stage ? member_input_use_arr : "\n";
17014 break;
17015 case MATRIX:
17016 case DVEC3_DVEC4:
17017 var_definition = matrix_dvec3_dvec4_definition_arr;
17018 var_use = Utils::Shader::VERTEX == stage ? matrix_dvec3_dvec4_input_use_arr : "\n";
17019 break;
17020 case STRUCT:
17021 var_definition = struct_definition_arr;
17022 var_use = Utils::Shader::VERTEX == stage ? member_input_use_arr : "\n";
17023 break;
17024 default:
17025 TCU_FAIL("Invalid enum");
17026 }
17027 }
17028 }
17029
17030 if (isFlatRequired(stage, test_case.m_type, storage))
17031 {
17032 flat = "flat";
17033 }
17034
17035 #if DEBUG_NEG_REMOVE_ERROR
17036 sprintf(buffer, " /* , component = %d */", test_case.m_component);
17037 #else
17038 sprintf(buffer, ", component = %d", test_case.m_component);
17039 #endif /* DEBUG_NEG_REMOVE_ERROR */
17040
17041 switch (stage)
17042 {
17043 case Utils::Shader::FRAGMENT:
17044 source = fs_tested;
17045 break;
17046 case Utils::Shader::GEOMETRY:
17047 source = gs_tested;
17048 array = test_case.m_is_input ? "[]" : "";
17049 index = test_case.m_is_input ? "[0]" : "";
17050 break;
17051 case Utils::Shader::TESS_CTRL:
17052 source = tcs_tested;
17053 array = "[]";
17054 index = "[gl_InvocationID]";
17055 break;
17056 case Utils::Shader::TESS_EVAL:
17057 source = tes_tested;
17058 array = test_case.m_is_input ? "[]" : "";
17059 index = test_case.m_is_input ? "[0]" : "";
17060 break;
17061 case Utils::Shader::VERTEX:
17062 source = vs_tested;
17063 break;
17064 default:
17065 TCU_FAIL("Invalid enum");
17066 }
17067
17068 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17069 position = 0;
17070 Utils::replaceToken("COMPONENT", position, buffer, source);
17071 Utils::replaceToken("DIRECTION", position, direction, source);
17072 Utils::replaceToken("ARRAY", position, array, source);
17073 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17074
17075 Utils::replaceAllTokens("FLAT", flat, source);
17076 Utils::replaceAllTokens("TYPE", type_name, source);
17077 Utils::replaceAllTokens("INDEX", index, source);
17078 }
17079 else
17080 {
17081 switch (stage)
17082 {
17083 case Utils::Shader::FRAGMENT:
17084 source = fs;
17085 break;
17086 case Utils::Shader::GEOMETRY:
17087 source = gs;
17088 break;
17089 case Utils::Shader::TESS_CTRL:
17090 source = tcs;
17091 break;
17092 case Utils::Shader::TESS_EVAL:
17093 source = tes;
17094 break;
17095 case Utils::Shader::VERTEX:
17096 source = vs;
17097 break;
17098 default:
17099 TCU_FAIL("Invalid enum");
17100 }
17101 }
17102
17103 return source;
17104 }
17105
17106 /** Get description of test case
17107 *
17108 * @param test_case_index Index of test case
17109 *
17110 * @return Test case description
17111 **/
17112 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index)
17113 {
17114 std::stringstream stream;
17115 testCase &test_case = m_test_cases[test_case_index];
17116
17117 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17118 << " type: " << test_case.m_type.GetGLSLTypeName();
17119
17120 if (true == test_case.m_is_array)
17121 {
17122 stream << "[1]";
17123 }
17124
17125 stream << ", direction: ";
17126
17127 if (true == test_case.m_is_input)
17128 {
17129 stream << "input";
17130 }
17131 else
17132 {
17133 stream << "output";
17134 }
17135
17136 stream << ", component: " << test_case.m_component;
17137
17138 return stream.str();
17139 }
17140
17141 /** Get number of test cases
17142 *
17143 * @return Number of test cases
17144 **/
17145 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber()
17146 {
17147 return static_cast<GLuint>(m_test_cases.size());
17148 }
17149
17150 /** Selects if "compute" stage is relevant for test
17151 *
17152 * @param ignored
17153 *
17154 * @return false
17155 **/
17156 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */)
17157 {
17158 return false;
17159 }
17160
17161 /** Prepare all test cases
17162 *
17163 **/
17164 void VaryingComponentOfInvalidTypeTest::testInit()
17165 {
17166 const GLuint n_types = getTypesNumber();
17167
17168 for (GLuint i = 0; i < n_types; ++i)
17169 {
17170 const Utils::Type &type = getType(i);
17171 const std::vector<GLuint> &valid_components = type.GetValidComponents();
17172
17173 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17174 {
17175 if (Utils::Shader::COMPUTE == stage)
17176 {
17177 continue;
17178 }
17179
17180 /* matrices */
17181 if (1 != type.m_n_columns)
17182 {
17183 testCase test_case_in_arr = {MATRIX, 0, true, true, (Utils::Shader::STAGES)stage, type};
17184 testCase test_case_in_one = {MATRIX, 0, false, true, (Utils::Shader::STAGES)stage, type};
17185 testCase test_case_out_arr = {MATRIX, 0, true, false, (Utils::Shader::STAGES)stage, type};
17186 testCase test_case_out_one = {MATRIX, 0, false, false, (Utils::Shader::STAGES)stage, type};
17187
17188 m_test_cases.push_back(test_case_in_arr);
17189 m_test_cases.push_back(test_case_in_one);
17190
17191 if (Utils::Shader::FRAGMENT != stage)
17192 {
17193 m_test_cases.push_back(test_case_out_arr);
17194 m_test_cases.push_back(test_case_out_one);
17195 }
17196 }
17197 else if (Utils::Type::Double == type.m_basic_type && 2 < type.m_n_rows) /* dvec3 and dvec4 */
17198 {
17199 testCase test_case_in_arr = {DVEC3_DVEC4, 0, true, true, (Utils::Shader::STAGES)stage, type};
17200 testCase test_case_in_one = {DVEC3_DVEC4, 0, false, true, (Utils::Shader::STAGES)stage, type};
17201 testCase test_case_out_arr = {DVEC3_DVEC4, 0, true, false, (Utils::Shader::STAGES)stage, type};
17202 testCase test_case_out_one = {DVEC3_DVEC4, 0, false, false, (Utils::Shader::STAGES)stage, type};
17203
17204 m_test_cases.push_back(test_case_in_arr);
17205 m_test_cases.push_back(test_case_in_one);
17206
17207 if (Utils::Shader::FRAGMENT != stage)
17208 {
17209 m_test_cases.push_back(test_case_out_arr);
17210 m_test_cases.push_back(test_case_out_one);
17211 }
17212 }
17213 else
17214 {
17215 if (valid_components.empty())
17216 {
17217 TCU_FAIL("Unhandled type");
17218 }
17219
17220 for (GLuint c = BLOCK; c < MAX_CASES; ++c)
17221 {
17222 testCase test_case_in_arr = {(CASES)c, valid_components.back(), true,
17223 true, (Utils::Shader::STAGES)stage, type};
17224 testCase test_case_in_one = {(CASES)c, valid_components.back(), false,
17225 true, (Utils::Shader::STAGES)stage, type};
17226 testCase test_case_out_arr = {(CASES)c, valid_components.back(), true,
17227 false, (Utils::Shader::STAGES)stage, type};
17228 testCase test_case_out_one = {(CASES)c, valid_components.back(), false,
17229 false, (Utils::Shader::STAGES)stage, type};
17230
17231 if (Utils::Shader::VERTEX != stage)
17232 {
17233 m_test_cases.push_back(test_case_in_arr);
17234 m_test_cases.push_back(test_case_in_one);
17235 }
17236
17237 if (Utils::Shader::FRAGMENT != stage)
17238 {
17239 m_test_cases.push_back(test_case_out_arr);
17240 m_test_cases.push_back(test_case_out_one);
17241 }
17242 }
17243 }
17244 }
17245 }
17246 }
17247
17248 /** Constructor
17249 *
17250 * @param context Test framework context
17251 **/
17252 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context &context)
17253 : NegativeTestBase(context, "input_component_aliasing",
17254 "Test verifies that compiler reports component aliasing as error")
17255 {
17256 }
17257
17258 /** Source for given test case and stage
17259 *
17260 * @param test_case_index Index of test case
17261 * @param stage Shader stage
17262 *
17263 * @return Shader source
17264 **/
17265 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
17266 {
17267 static const GLchar *var_definition =
17268 "layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n"
17269 #if DEBUG_NEG_REMOVE_ERROR
17270 "/* layout (location = 1, component = COMPONENT) */ FLAT in TYPE gotenARRAY;\n";
17271 #else
17272 "layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n";
17273 #endif /* DEBUG_NEG_REMOVE_ERROR */
17274 static const GLchar *test_one = " if (TYPE(0) == gohanINDEX)\n"
17275 " {\n"
17276 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17277 " }\n";
17278 static const GLchar *fs = "#version 430 core\n"
17279 "#extension GL_ARB_enhanced_layouts : require\n"
17280 "\n"
17281 "in vec4 gs_fs;\n"
17282 "out vec4 fs_out;\n"
17283 "\n"
17284 "void main()\n"
17285 "{\n"
17286 " fs_out = gs_fs;\n"
17287 "}\n"
17288 "\n";
17289 static const GLchar *fs_tested = "#version 430 core\n"
17290 "#extension GL_ARB_enhanced_layouts : require\n"
17291 "\n"
17292 "VAR_DEFINITION"
17293 "\n"
17294 "in vec4 gs_fs;\n"
17295 "out vec4 fs_out;\n"
17296 "\n"
17297 "void main()\n"
17298 "{\n"
17299 " vec4 result = gs_fs;\n"
17300 "\n"
17301 "VARIABLE_USE"
17302 "\n"
17303 " fs_out += result;\n"
17304 "}\n"
17305 "\n";
17306 static const GLchar *gs = "#version 430 core\n"
17307 "#extension GL_ARB_enhanced_layouts : require\n"
17308 "\n"
17309 "layout(points) in;\n"
17310 "layout(triangle_strip, max_vertices = 4) out;\n"
17311 "\n"
17312 "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan;\n"
17313 "\n"
17314 "in vec4 tes_gs[];\n"
17315 "out vec4 gs_fs;\n"
17316 "\n"
17317 "void main()\n"
17318 "{\n"
17319 " gohan = TYPE(1);\n"
17320 "\n"
17321 " gs_fs = tes_gs[0];\n"
17322 " gl_Position = vec4(-1, -1, 0, 1);\n"
17323 " EmitVertex();\n"
17324 " gs_fs = tes_gs[0];\n"
17325 " gl_Position = vec4(-1, 1, 0, 1);\n"
17326 " EmitVertex();\n"
17327 " gs_fs = tes_gs[0];\n"
17328 " gl_Position = vec4(1, -1, 0, 1);\n"
17329 " EmitVertex();\n"
17330 " gs_fs = tes_gs[0];\n"
17331 " gl_Position = vec4(1, 1, 0, 1);\n"
17332 " EmitVertex();\n"
17333 "}\n"
17334 "\n";
17335 static const GLchar *gs_tested = "#version 430 core\n"
17336 "#extension GL_ARB_enhanced_layouts : require\n"
17337 "\n"
17338 "layout(points) in;\n"
17339 "layout(triangle_strip, max_vertices = 4) out;\n"
17340 "\n"
17341 "VAR_DEFINITION"
17342 "\n"
17343 "in vec4 tes_gs[];\n"
17344 "out vec4 gs_fs;\n"
17345 "\n"
17346 "void main()\n"
17347 "{\n"
17348 " vec4 result = tes_gs[0];\n"
17349 "\n"
17350 "VARIABLE_USE"
17351 "\n"
17352 " gs_fs = result;\n"
17353 " gl_Position = vec4(-1, -1, 0, 1);\n"
17354 " EmitVertex();\n"
17355 " gs_fs = result;\n"
17356 " gl_Position = vec4(-1, 1, 0, 1);\n"
17357 " EmitVertex();\n"
17358 " gs_fs = result;\n"
17359 " gl_Position = vec4(1, -1, 0, 1);\n"
17360 " EmitVertex();\n"
17361 " gs_fs = result;\n"
17362 " gl_Position = vec4(1, 1, 0, 1);\n"
17363 " EmitVertex();\n"
17364 "}\n"
17365 "\n";
17366 static const GLchar *tcs = "#version 430 core\n"
17367 "#extension GL_ARB_enhanced_layouts : require\n"
17368 "\n"
17369 "layout(vertices = 1) out;\n"
17370 "\n"
17371 "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan[];\n"
17372 "\n"
17373 "in vec4 vs_tcs[];\n"
17374 "out vec4 tcs_tes[];\n"
17375 "\n"
17376 "void main()\n"
17377 "{\n"
17378 " gohan[gl_InvocationID] = TYPE(1);\n"
17379 "\n"
17380 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17381 "\n"
17382 " gl_TessLevelOuter[0] = 1.0;\n"
17383 " gl_TessLevelOuter[1] = 1.0;\n"
17384 " gl_TessLevelOuter[2] = 1.0;\n"
17385 " gl_TessLevelOuter[3] = 1.0;\n"
17386 " gl_TessLevelInner[0] = 1.0;\n"
17387 " gl_TessLevelInner[1] = 1.0;\n"
17388 "}\n"
17389 "\n";
17390 static const GLchar *tcs_tested = "#version 430 core\n"
17391 "#extension GL_ARB_enhanced_layouts : require\n"
17392 "\n"
17393 "layout(vertices = 1) out;\n"
17394 "\n"
17395 "VAR_DEFINITION"
17396 "\n"
17397 "in vec4 vs_tcs[];\n"
17398 "out vec4 tcs_tes[];\n"
17399 "\n"
17400 "void main()\n"
17401 "{\n"
17402 " vec4 result = vs_tcs[gl_InvocationID];\n"
17403 "\n"
17404 "VARIABLE_USE"
17405 "\n"
17406 " tcs_tes[gl_InvocationID] = result;\n"
17407 "\n"
17408 " gl_TessLevelOuter[0] = 1.0;\n"
17409 " gl_TessLevelOuter[1] = 1.0;\n"
17410 " gl_TessLevelOuter[2] = 1.0;\n"
17411 " gl_TessLevelOuter[3] = 1.0;\n"
17412 " gl_TessLevelInner[0] = 1.0;\n"
17413 " gl_TessLevelInner[1] = 1.0;\n"
17414 "}\n"
17415 "\n";
17416 static const GLchar *tes = "#version 430 core\n"
17417 "#extension GL_ARB_enhanced_layouts : require\n"
17418 "\n"
17419 "layout(isolines, point_mode) in;\n"
17420 "\n"
17421 "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan;\n"
17422 "\n"
17423 "in vec4 tcs_tes[];\n"
17424 "out vec4 tes_gs;\n"
17425 "\n"
17426 "void main()\n"
17427 "{\n"
17428 " gohan = TYPE(1);\n"
17429 "\n"
17430 " tes_gs = tcs_tes[0];\n"
17431 "}\n"
17432 "\n";
17433 static const GLchar *tes_tested = "#version 430 core\n"
17434 "#extension GL_ARB_enhanced_layouts : require\n"
17435 "\n"
17436 "layout(isolines, point_mode) in;\n"
17437 "\n"
17438 "VAR_DEFINITION"
17439 "\n"
17440 "in vec4 tcs_tes[];\n"
17441 "out vec4 tes_gs;\n"
17442 "\n"
17443 "void main()\n"
17444 "{\n"
17445 " vec4 result = tcs_tes[0];\n"
17446 "\n"
17447 "VARIABLE_USE"
17448 "\n"
17449 " tes_gs += result;\n"
17450 "}\n"
17451 "\n";
17452 static const GLchar *vs = "#version 430 core\n"
17453 "#extension GL_ARB_enhanced_layouts : require\n"
17454 "\n"
17455 "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan;\n"
17456 "\n"
17457 "in vec4 in_vs;\n"
17458 "out vec4 vs_tcs;\n"
17459 "\n"
17460 "void main()\n"
17461 "{\n"
17462 " gohan = TYPE(1);\n"
17463 "\n"
17464 " vs_tcs = in_vs;\n"
17465 "}\n"
17466 "\n";
17467 static const GLchar *vs_tested = "#version 430 core\n"
17468 "#extension GL_ARB_enhanced_layouts : require\n"
17469 "\n"
17470 "VAR_DEFINITION"
17471 "\n"
17472 "in vec4 in_vs;\n"
17473 "out vec4 vs_tcs;\n"
17474 "\n"
17475 "void main()\n"
17476 "{\n"
17477 " vec4 result = in_vs;\n"
17478 "\n"
17479 "VARIABLE_USE"
17480 "\n"
17481 " vs_tcs += result;\n"
17482 "}\n"
17483 "\n";
17484
17485 std::string source;
17486 testCase &test_case = m_test_cases[test_case_index];
17487 GLchar buffer_gohan[16];
17488 const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
17489
17490 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17491
17492 if (test_case.m_stage == stage)
17493 {
17494 const GLchar *array = "";
17495 GLchar buffer_goten[16];
17496 const GLchar *flat = "";
17497 const GLchar *index = "";
17498 size_t position = 0;
17499 const GLchar *var_use = test_one;
17500
17501 if (isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT, true))
17502 {
17503 flat = "flat";
17504 }
17505
17506 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17507
17508 switch (stage)
17509 {
17510 case Utils::Shader::FRAGMENT:
17511 source = fs_tested;
17512 break;
17513 case Utils::Shader::GEOMETRY:
17514 source = gs_tested;
17515 array = "[]";
17516 index = "[0]";
17517 break;
17518 case Utils::Shader::TESS_CTRL:
17519 source = tcs_tested;
17520 array = "[]";
17521 index = "[gl_InvocationID]";
17522 break;
17523 case Utils::Shader::TESS_EVAL:
17524 source = tes_tested;
17525 array = "[]";
17526 index = "[0]";
17527 break;
17528 case Utils::Shader::VERTEX:
17529 source = vs_tested;
17530 break;
17531 default:
17532 TCU_FAIL("Invalid enum");
17533 }
17534
17535 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17536 position = 0;
17537 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17538 Utils::replaceToken("ARRAY", position, array, source);
17539 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17540 Utils::replaceToken("ARRAY", position, array, source);
17541 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17542
17543 Utils::replaceAllTokens("FLAT", flat, source);
17544 Utils::replaceAllTokens("TYPE", type_name, source);
17545 Utils::replaceAllTokens("INDEX", index, source);
17546 }
17547 else
17548 {
17549 const GLchar *flat = "";
17550
17551 if (isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_OUTPUT, true))
17552 {
17553 flat = "flat";
17554 }
17555
17556 switch (stage)
17557 {
17558 case Utils::Shader::FRAGMENT:
17559 source = fs;
17560 break;
17561 case Utils::Shader::GEOMETRY:
17562 source = gs;
17563 break;
17564 case Utils::Shader::TESS_CTRL:
17565 source = tcs;
17566 break;
17567 case Utils::Shader::TESS_EVAL:
17568 source = tes;
17569 break;
17570 case Utils::Shader::VERTEX:
17571 source = vs;
17572 break;
17573 default:
17574 TCU_FAIL("Invalid enum");
17575 }
17576
17577 Utils::replaceAllTokens("FLAT", flat, source);
17578 Utils::replaceAllTokens("COMPONENT", buffer_gohan, source);
17579 Utils::replaceAllTokens("TYPE", type_name, source);
17580 }
17581
17582 return source;
17583 }
17584
17585 /** Get description of test case
17586 *
17587 * @param test_case_index Index of test case
17588 *
17589 * @return Test case description
17590 **/
17591 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17592 {
17593 std::stringstream stream;
17594 testCase &test_case = m_test_cases[test_case_index];
17595
17596 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17597 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17598 << " & " << test_case.m_component_goten;
17599
17600 return stream.str();
17601 }
17602
17603 /** Get number of test cases
17604 *
17605 * @return Number of test cases
17606 **/
17607 GLuint InputComponentAliasingTest::getTestCaseNumber()
17608 {
17609 return static_cast<GLuint>(m_test_cases.size());
17610 }
17611
17612 /** Selects if "compute" stage is relevant for test
17613 *
17614 * @param ignored
17615 *
17616 * @return false
17617 **/
17618 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
17619 {
17620 return false;
17621 }
17622
17623 /** Selects if compilation failure is expected result
17624 *
17625 * @param test_case_index Index of test case
17626 *
17627 * @return false for VS that use only single variable, true otherwise
17628 **/
17629 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index)
17630 {
17631 testCase &test_case = m_test_cases[test_case_index];
17632
17633 return (Utils::Shader::VERTEX != test_case.m_stage);
17634 }
17635
17636 /** Prepare all test cases
17637 *
17638 **/
17639 void InputComponentAliasingTest::testInit()
17640 {
17641 const GLuint n_types = getTypesNumber();
17642
17643 for (GLuint i = 0; i < n_types; ++i)
17644 {
17645 const Utils::Type &type = getType(i);
17646 const std::vector<GLuint> &valid_components = type.GetValidComponents();
17647
17648 if (valid_components.empty())
17649 {
17650 continue;
17651 }
17652
17653 for (std::vector<GLuint>::const_iterator it_gohan = valid_components.begin();
17654 it_gohan != valid_components.end(); ++it_gohan)
17655 {
17656 const GLuint max_component = *it_gohan + type.GetNumComponents();
17657 for (std::vector<GLuint>::const_iterator it_goten = it_gohan;
17658 it_goten != valid_components.end() && max_component > *it_goten; ++it_goten)
17659 {
17660 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17661 {
17662 /* Skip compute shader */
17663 if (Utils::Shader::COMPUTE == stage)
17664 {
17665 continue;
17666 }
17667
17668 testCase test_case = {*it_gohan, *it_goten, (Utils::Shader::STAGES)stage, type};
17669
17670 m_test_cases.push_back(test_case);
17671 }
17672 }
17673 }
17674 }
17675 }
17676
17677 /** Constructor
17678 *
17679 * @param context Test framework context
17680 **/
17681 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context &context)
17682 : NegativeTestBase(context, "output_component_aliasing",
17683 "Test verifies that compiler reports component aliasing as error")
17684 {
17685 }
17686
17687 /** Source for given test case and stage
17688 *
17689 * @param test_case_index Index of test case
17690 * @param stage Shader stage
17691 *
17692 * @return Shader source
17693 **/
17694 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
17695 {
17696 static const GLchar *var_definition =
17697 "layout (location = 1, component = COMPONENT) FLAT out TYPE gohanARRAY;\n"
17698 #if DEBUG_NEG_REMOVE_ERROR
17699 "/* layout (location = 1, component = COMPONENT) */ FLAT out TYPE gotenARRAY;\n";
17700 #else
17701 "layout (location = 1, component = COMPONENT) FLAT out TYPE gotenARRAY;\n";
17702 #endif /* DEBUG_NEG_REMOVE_ERROR */
17703 static const GLchar *l_test = " gohanINDEX = TYPE(1);\n"
17704 " gotenINDEX = TYPE(0);\n";
17705 static const GLchar *fs = "#version 430 core\n"
17706 "#extension GL_ARB_enhanced_layouts : require\n"
17707 "\n"
17708 "in vec4 gs_fs;\n"
17709 "out vec4 fs_out;\n"
17710 "\n"
17711 "void main()\n"
17712 "{\n"
17713 " fs_out = gs_fs;\n"
17714 "}\n"
17715 "\n";
17716 static const GLchar *fs_tested = "#version 430 core\n"
17717 "#extension GL_ARB_enhanced_layouts : require\n"
17718 "\n"
17719 "VAR_DEFINITION"
17720 "\n"
17721 "in vec4 gs_fs;\n"
17722 "out vec4 fs_out;\n"
17723 "\n"
17724 "void main()\n"
17725 "{\n"
17726 " vec4 result = gs_fs;\n"
17727 "\n"
17728 "VARIABLE_USE"
17729 "\n"
17730 " fs_out += result;\n"
17731 "}\n"
17732 "\n";
17733 static const GLchar *gs = "#version 430 core\n"
17734 "#extension GL_ARB_enhanced_layouts : require\n"
17735 "\n"
17736 "layout(points) in;\n"
17737 "layout(triangle_strip, max_vertices = 4) out;\n"
17738 "\n"
17739 "in vec4 tes_gs[];\n"
17740 "out vec4 gs_fs;\n"
17741 "\n"
17742 "void main()\n"
17743 "{\n"
17744 " gs_fs = tes_gs[0];\n"
17745 " gl_Position = vec4(-1, -1, 0, 1);\n"
17746 " EmitVertex();\n"
17747 " gs_fs = tes_gs[0];\n"
17748 " gl_Position = vec4(-1, 1, 0, 1);\n"
17749 " EmitVertex();\n"
17750 " gs_fs = tes_gs[0];\n"
17751 " gl_Position = vec4(1, -1, 0, 1);\n"
17752 " EmitVertex();\n"
17753 " gs_fs = tes_gs[0];\n"
17754 " gl_Position = vec4(1, 1, 0, 1);\n"
17755 " EmitVertex();\n"
17756 "}\n"
17757 "\n";
17758 static const GLchar *gs_tested = "#version 430 core\n"
17759 "#extension GL_ARB_enhanced_layouts : require\n"
17760 "\n"
17761 "layout(points) in;\n"
17762 "layout(triangle_strip, max_vertices = 4) out;\n"
17763 "\n"
17764 "VAR_DEFINITION"
17765 "\n"
17766 "in vec4 tes_gs[];\n"
17767 "out vec4 gs_fs;\n"
17768 "\n"
17769 "void main()\n"
17770 "{\n"
17771 " vec4 result = tes_gs[0];\n"
17772 "\n"
17773 "VARIABLE_USE"
17774 "\n"
17775 " gs_fs = result;\n"
17776 " gl_Position = vec4(-1, -1, 0, 1);\n"
17777 " EmitVertex();\n"
17778 " gs_fs = result;\n"
17779 " gl_Position = vec4(-1, 1, 0, 1);\n"
17780 " EmitVertex();\n"
17781 " gs_fs = result;\n"
17782 " gl_Position = vec4(1, -1, 0, 1);\n"
17783 " EmitVertex();\n"
17784 " gs_fs = result;\n"
17785 " gl_Position = vec4(1, 1, 0, 1);\n"
17786 " EmitVertex();\n"
17787 "}\n"
17788 "\n";
17789 static const GLchar *tcs = "#version 430 core\n"
17790 "#extension GL_ARB_enhanced_layouts : require\n"
17791 "\n"
17792 "layout(vertices = 1) out;\n"
17793 "\n"
17794 "in vec4 vs_tcs[];\n"
17795 "out vec4 tcs_tes[];\n"
17796 "\n"
17797 "void main()\n"
17798 "{\n"
17799 "\n"
17800 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17801 "\n"
17802 " gl_TessLevelOuter[0] = 1.0;\n"
17803 " gl_TessLevelOuter[1] = 1.0;\n"
17804 " gl_TessLevelOuter[2] = 1.0;\n"
17805 " gl_TessLevelOuter[3] = 1.0;\n"
17806 " gl_TessLevelInner[0] = 1.0;\n"
17807 " gl_TessLevelInner[1] = 1.0;\n"
17808 "}\n"
17809 "\n";
17810 static const GLchar *tcs_tested = "#version 430 core\n"
17811 "#extension GL_ARB_enhanced_layouts : require\n"
17812 "\n"
17813 "layout(vertices = 1) out;\n"
17814 "\n"
17815 "VAR_DEFINITION"
17816 "\n"
17817 "in vec4 vs_tcs[];\n"
17818 "out vec4 tcs_tes[];\n"
17819 "\n"
17820 "void main()\n"
17821 "{\n"
17822 " vec4 result = vs_tcs[gl_InvocationID];\n"
17823 "\n"
17824 "VARIABLE_USE"
17825 "\n"
17826 " tcs_tes[gl_InvocationID] = result;\n"
17827 "\n"
17828 " gl_TessLevelOuter[0] = 1.0;\n"
17829 " gl_TessLevelOuter[1] = 1.0;\n"
17830 " gl_TessLevelOuter[2] = 1.0;\n"
17831 " gl_TessLevelOuter[3] = 1.0;\n"
17832 " gl_TessLevelInner[0] = 1.0;\n"
17833 " gl_TessLevelInner[1] = 1.0;\n"
17834 "}\n"
17835 "\n";
17836 static const GLchar *tes = "#version 430 core\n"
17837 "#extension GL_ARB_enhanced_layouts : require\n"
17838 "\n"
17839 "layout(isolines, point_mode) in;\n"
17840 "\n"
17841 "in vec4 tcs_tes[];\n"
17842 "out vec4 tes_gs;\n"
17843 "\n"
17844 "void main()\n"
17845 "{\n"
17846 " tes_gs = tcs_tes[0];\n"
17847 "}\n"
17848 "\n";
17849 static const GLchar *tes_tested = "#version 430 core\n"
17850 "#extension GL_ARB_enhanced_layouts : require\n"
17851 "\n"
17852 "layout(isolines, point_mode) in;\n"
17853 "\n"
17854 "VAR_DEFINITION"
17855 "\n"
17856 "in vec4 tcs_tes[];\n"
17857 "out vec4 tes_gs;\n"
17858 "\n"
17859 "void main()\n"
17860 "{\n"
17861 " vec4 result = tcs_tes[0];\n"
17862 "\n"
17863 "VARIABLE_USE"
17864 "\n"
17865 " tes_gs += result;\n"
17866 "}\n"
17867 "\n";
17868 static const GLchar *vs = "#version 430 core\n"
17869 "#extension GL_ARB_enhanced_layouts : require\n"
17870 "\n"
17871 "in vec4 in_vs;\n"
17872 "out vec4 vs_tcs;\n"
17873 "\n"
17874 "void main()\n"
17875 "{\n"
17876 " vs_tcs = in_vs;\n"
17877 "}\n"
17878 "\n";
17879 static const GLchar *vs_tested = "#version 430 core\n"
17880 "#extension GL_ARB_enhanced_layouts : require\n"
17881 "\n"
17882 "VAR_DEFINITION"
17883 "\n"
17884 "in vec4 in_vs;\n"
17885 "out vec4 vs_tcs;\n"
17886 "\n"
17887 "void main()\n"
17888 "{\n"
17889 " vec4 result = in_vs;\n"
17890 "\n"
17891 "VARIABLE_USE"
17892 "\n"
17893 " vs_tcs += result;\n"
17894 "}\n"
17895 "\n";
17896
17897 std::string source;
17898 testCase &test_case = m_test_cases[test_case_index];
17899
17900 if (test_case.m_stage == stage)
17901 {
17902 const GLchar *array = "";
17903 GLchar buffer_gohan[16];
17904 GLchar buffer_goten[16];
17905 const GLchar *flat = "";
17906 const GLchar *index = "";
17907 size_t position = 0;
17908 const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
17909
17910 if (isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_OUTPUT))
17911 {
17912 flat = "flat";
17913 }
17914
17915 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17916 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17917
17918 switch (stage)
17919 {
17920 case Utils::Shader::FRAGMENT:
17921 source = fs_tested;
17922 break;
17923 case Utils::Shader::GEOMETRY:
17924 source = gs_tested;
17925 break;
17926 case Utils::Shader::TESS_CTRL:
17927 source = tcs_tested;
17928 array = "[]";
17929 index = "[gl_InvocationID]";
17930 break;
17931 case Utils::Shader::TESS_EVAL:
17932 source = tes_tested;
17933 break;
17934 case Utils::Shader::VERTEX:
17935 source = vs_tested;
17936 break;
17937 default:
17938 TCU_FAIL("Invalid enum");
17939 }
17940
17941 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17942 position = 0;
17943 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17944 Utils::replaceToken("FLAT", position, flat, source);
17945 Utils::replaceToken("ARRAY", position, array, source);
17946 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17947 Utils::replaceToken("FLAT", position, flat, source);
17948 Utils::replaceToken("ARRAY", position, array, source);
17949 Utils::replaceToken("VARIABLE_USE", position, l_test, source);
17950
17951 Utils::replaceAllTokens("TYPE", type_name, source);
17952 Utils::replaceAllTokens("INDEX", index, source);
17953 }
17954 else
17955 {
17956 switch (stage)
17957 {
17958 case Utils::Shader::FRAGMENT:
17959 source = fs;
17960 break;
17961 case Utils::Shader::GEOMETRY:
17962 source = gs;
17963 break;
17964 case Utils::Shader::TESS_CTRL:
17965 source = tcs;
17966 break;
17967 case Utils::Shader::TESS_EVAL:
17968 source = tes;
17969 break;
17970 case Utils::Shader::VERTEX:
17971 source = vs;
17972 break;
17973 default:
17974 TCU_FAIL("Invalid enum");
17975 }
17976 }
17977
17978 return source;
17979 }
17980
17981 /** Get description of test case
17982 *
17983 * @param test_case_index Index of test case
17984 *
17985 * @return Test case description
17986 **/
17987 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17988 {
17989 std::stringstream stream;
17990 testCase &test_case = m_test_cases[test_case_index];
17991
17992 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17993 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17994 << " & " << test_case.m_component_goten;
17995
17996 return stream.str();
17997 }
17998
17999 /** Get number of test cases
18000 *
18001 * @return Number of test cases
18002 **/
18003 GLuint OutputComponentAliasingTest::getTestCaseNumber()
18004 {
18005 return static_cast<GLuint>(m_test_cases.size());
18006 }
18007
18008 /** Selects if "compute" stage is relevant for test
18009 *
18010 * @param ignored
18011 *
18012 * @return false
18013 **/
18014 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
18015 {
18016 return false;
18017 }
18018
18019 /** Prepare all test cases
18020 *
18021 **/
18022 void OutputComponentAliasingTest::testInit()
18023 {
18024 const GLuint n_types = getTypesNumber();
18025
18026 for (GLuint i = 0; i < n_types; ++i)
18027 {
18028 const Utils::Type &type = getType(i);
18029 const std::vector<GLuint> &valid_components = type.GetValidComponents();
18030
18031 if (valid_components.empty())
18032 {
18033 continue;
18034 }
18035
18036 for (std::vector<GLuint>::const_iterator it_gohan = valid_components.begin();
18037 it_gohan != valid_components.end(); ++it_gohan)
18038 {
18039 const GLuint max_component = *it_gohan + type.GetNumComponents();
18040 for (std::vector<GLuint>::const_iterator it_goten = it_gohan;
18041 it_goten != valid_components.end() && max_component > *it_goten; ++it_goten)
18042 {
18043 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18044 {
18045 /* Skip compute shader */
18046 if (Utils::Shader::COMPUTE == stage)
18047 {
18048 continue;
18049 }
18050
18051 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type))
18052 {
18053 continue;
18054 }
18055
18056 testCase test_case = {*it_gohan, *it_goten, (Utils::Shader::STAGES)stage, type};
18057
18058 m_test_cases.push_back(test_case);
18059 }
18060 }
18061 }
18062 }
18063 }
18064
18065 /** Constructor
18066 *
18067 * @param context Test framework context
18068 **/
18069 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context &context)
18070 : NegativeTestBase(context, "varying_location_aliasing_with_mixed_types",
18071 "Test verifies that compiler reports error when float/int types are mixed at one location")
18072 {
18073 }
18074
18075 /** Source for given test case and stage
18076 *
18077 * @param test_case_index Index of test case
18078 * @param stage Shader stage
18079 *
18080 * @return Shader source
18081 **/
18082 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint test_case_index,
18083 Utils::Shader::STAGES stage)
18084 {
18085 static const GLchar *var_definition =
18086 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n"
18087 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n";
18088 static const GLchar *input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
18089 " (TYPE(1) == gotenINDEX) )\n"
18090 " {\n"
18091 " result += vec4(1, 0.5, 0.25, 0.125);\n"
18092 " }\n";
18093 static const GLchar *output_use = " gohanINDEX = TYPE(0);\n"
18094 " gotenINDEX = TYPE(1);\n"
18095 " if (vec4(0) == result)\n"
18096 " {\n"
18097 " gohanINDEX = TYPE(1);\n"
18098 " gotenINDEX = TYPE(0);\n"
18099 " }\n";
18100 static const GLchar *fs = "#version 430 core\n"
18101 "#extension GL_ARB_enhanced_layouts : require\n"
18102 "\n"
18103 "in vec4 gs_fs;\n"
18104 "out vec4 fs_out;\n"
18105 "\n"
18106 "void main()\n"
18107 "{\n"
18108 " fs_out = gs_fs;\n"
18109 "}\n"
18110 "\n";
18111 static const GLchar *fs_tested = "#version 430 core\n"
18112 "#extension GL_ARB_enhanced_layouts : require\n"
18113 "\n"
18114 "VAR_DEFINITION"
18115 "\n"
18116 "in vec4 gs_fs;\n"
18117 "out vec4 fs_out;\n"
18118 "\n"
18119 "void main()\n"
18120 "{\n"
18121 " vec4 result = gs_fs;\n"
18122 "\n"
18123 "VARIABLE_USE"
18124 "\n"
18125 " fs_out += result;\n"
18126 "}\n"
18127 "\n";
18128 static const GLchar *gs = "#version 430 core\n"
18129 "#extension GL_ARB_enhanced_layouts : require\n"
18130 "\n"
18131 "layout(points) in;\n"
18132 "layout(triangle_strip, max_vertices = 4) out;\n"
18133 "\n"
18134 "in vec4 tes_gs[];\n"
18135 "out vec4 gs_fs;\n"
18136 "\n"
18137 "void main()\n"
18138 "{\n"
18139 " gs_fs = tes_gs[0];\n"
18140 " gl_Position = vec4(-1, -1, 0, 1);\n"
18141 " EmitVertex();\n"
18142 " gs_fs = tes_gs[0];\n"
18143 " gl_Position = vec4(-1, 1, 0, 1);\n"
18144 " EmitVertex();\n"
18145 " gs_fs = tes_gs[0];\n"
18146 " gl_Position = vec4(1, -1, 0, 1);\n"
18147 " EmitVertex();\n"
18148 " gs_fs = tes_gs[0];\n"
18149 " gl_Position = vec4(1, 1, 0, 1);\n"
18150 " EmitVertex();\n"
18151 "}\n"
18152 "\n";
18153 static const GLchar *gs_tested = "#version 430 core\n"
18154 "#extension GL_ARB_enhanced_layouts : require\n"
18155 "\n"
18156 "layout(points) in;\n"
18157 "layout(triangle_strip, max_vertices = 4) out;\n"
18158 "\n"
18159 "VAR_DEFINITION"
18160 "\n"
18161 "in vec4 tes_gs[];\n"
18162 "out vec4 gs_fs;\n"
18163 "\n"
18164 "void main()\n"
18165 "{\n"
18166 " vec4 result = tes_gs[0];\n"
18167 "\n"
18168 "VARIABLE_USE"
18169 "\n"
18170 " gs_fs = result;\n"
18171 " gl_Position = vec4(-1, -1, 0, 1);\n"
18172 " EmitVertex();\n"
18173 " gs_fs = result;\n"
18174 " gl_Position = vec4(-1, 1, 0, 1);\n"
18175 " EmitVertex();\n"
18176 " gs_fs = result;\n"
18177 " gl_Position = vec4(1, -1, 0, 1);\n"
18178 " EmitVertex();\n"
18179 " gs_fs = result;\n"
18180 " gl_Position = vec4(1, 1, 0, 1);\n"
18181 " EmitVertex();\n"
18182 "}\n"
18183 "\n";
18184 static const GLchar *tcs = "#version 430 core\n"
18185 "#extension GL_ARB_enhanced_layouts : require\n"
18186 "\n"
18187 "layout(vertices = 1) out;\n"
18188 "\n"
18189 "in vec4 vs_tcs[];\n"
18190 "out vec4 tcs_tes[];\n"
18191 "\n"
18192 "void main()\n"
18193 "{\n"
18194 "\n"
18195 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18196 "\n"
18197 " gl_TessLevelOuter[0] = 1.0;\n"
18198 " gl_TessLevelOuter[1] = 1.0;\n"
18199 " gl_TessLevelOuter[2] = 1.0;\n"
18200 " gl_TessLevelOuter[3] = 1.0;\n"
18201 " gl_TessLevelInner[0] = 1.0;\n"
18202 " gl_TessLevelInner[1] = 1.0;\n"
18203 "}\n"
18204 "\n";
18205 static const GLchar *tcs_tested = "#version 430 core\n"
18206 "#extension GL_ARB_enhanced_layouts : require\n"
18207 "\n"
18208 "layout(vertices = 1) out;\n"
18209 "\n"
18210 "VAR_DEFINITION"
18211 "\n"
18212 "in vec4 vs_tcs[];\n"
18213 "out vec4 tcs_tes[];\n"
18214 "\n"
18215 "void main()\n"
18216 "{\n"
18217 " vec4 result = vs_tcs[gl_InvocationID];\n"
18218 "\n"
18219 "VARIABLE_USE"
18220 "\n"
18221 " tcs_tes[gl_InvocationID] = result;\n"
18222 "\n"
18223 " gl_TessLevelOuter[0] = 1.0;\n"
18224 " gl_TessLevelOuter[1] = 1.0;\n"
18225 " gl_TessLevelOuter[2] = 1.0;\n"
18226 " gl_TessLevelOuter[3] = 1.0;\n"
18227 " gl_TessLevelInner[0] = 1.0;\n"
18228 " gl_TessLevelInner[1] = 1.0;\n"
18229 "}\n"
18230 "\n";
18231 static const GLchar *tes = "#version 430 core\n"
18232 "#extension GL_ARB_enhanced_layouts : require\n"
18233 "\n"
18234 "layout(isolines, point_mode) in;\n"
18235 "\n"
18236 "in vec4 tcs_tes[];\n"
18237 "out vec4 tes_gs;\n"
18238 "\n"
18239 "void main()\n"
18240 "{\n"
18241 " tes_gs = tcs_tes[0];\n"
18242 "}\n"
18243 "\n";
18244 static const GLchar *tes_tested = "#version 430 core\n"
18245 "#extension GL_ARB_enhanced_layouts : require\n"
18246 "\n"
18247 "layout(isolines, point_mode) in;\n"
18248 "\n"
18249 "VAR_DEFINITION"
18250 "\n"
18251 "in vec4 tcs_tes[];\n"
18252 "out vec4 tes_gs;\n"
18253 "\n"
18254 "void main()\n"
18255 "{\n"
18256 " vec4 result = tcs_tes[0];\n"
18257 "\n"
18258 "VARIABLE_USE"
18259 "\n"
18260 " tes_gs += result;\n"
18261 "}\n"
18262 "\n";
18263 static const GLchar *vs = "#version 430 core\n"
18264 "#extension GL_ARB_enhanced_layouts : require\n"
18265 "\n"
18266 "in vec4 in_vs;\n"
18267 "out vec4 vs_tcs;\n"
18268 "\n"
18269 "void main()\n"
18270 "{\n"
18271 " vs_tcs = in_vs;\n"
18272 "}\n"
18273 "\n";
18274 static const GLchar *vs_tested = "#version 430 core\n"
18275 "#extension GL_ARB_enhanced_layouts : require\n"
18276 "\n"
18277 "VAR_DEFINITION"
18278 "\n"
18279 "in vec4 in_vs;\n"
18280 "out vec4 vs_tcs;\n"
18281 "\n"
18282 "void main()\n"
18283 "{\n"
18284 " vec4 result = in_vs;\n"
18285 "\n"
18286 "VARIABLE_USE"
18287 "\n"
18288 " vs_tcs += result;\n"
18289 "}\n"
18290 "\n";
18291
18292 std::string source;
18293 testCase &test_case = m_test_cases[test_case_index];
18294
18295 if (test_case.m_stage == stage)
18296 {
18297 const GLchar *array = "";
18298 GLchar buffer_gohan[16];
18299 GLchar buffer_goten[16];
18300 const GLchar *direction = "in ";
18301 const GLchar *flat_gohan = "";
18302 const GLchar *flat_goten = "";
18303 const GLchar *index = "";
18304 size_t position = 0;
18305 size_t temp;
18306 const GLchar *type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18307 const GLchar *type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18308 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
18309 const GLchar *var_use = Utils::Shader::VERTEX == stage ? input_use : "\n";
18310
18311 if (false == test_case.m_is_input)
18312 {
18313 direction = "out";
18314 storage = Utils::Variable::VARYING_OUTPUT;
18315 var_use = output_use;
18316 }
18317
18318 /* If the interpolation qualifier would be different, the test
18319 * would fail and we are testing here mixed types, not mixed
18320 * interpolation qualifiers.
18321 */
18322 if (isFlatRequired(stage, test_case.m_type_gohan, storage) ||
18323 isFlatRequired(stage, test_case.m_type_goten, storage))
18324 {
18325 flat_gohan = "flat";
18326 flat_goten = "flat";
18327 }
18328
18329 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18330 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18331
18332 #if DEBUG_NEG_REMOVE_ERROR
18333 type_goten_name = Utils::Type::GetType(test_case.m_type_gohan.m_basic_type, 1, 1).GetGLSLTypeName();
18334 if (Utils::Type::Double == test_case.m_type_gohan.m_basic_type)
18335 {
18336 sprintf(buffer_goten, "%d", 0 == test_case.m_component_gohan ? 2 : 0);
18337 }
18338 #endif /* DEBUG_NEG_REMOVE_ERROR */
18339
18340 switch (stage)
18341 {
18342 case Utils::Shader::FRAGMENT:
18343 source = fs_tested;
18344 break;
18345 case Utils::Shader::GEOMETRY:
18346 source = gs_tested;
18347 array = test_case.m_is_input ? "[]" : "";
18348 index = test_case.m_is_input ? "[0]" : "";
18349 break;
18350 case Utils::Shader::TESS_CTRL:
18351 source = tcs_tested;
18352 array = "[]";
18353 index = "[gl_InvocationID]";
18354 break;
18355 case Utils::Shader::TESS_EVAL:
18356 source = tes_tested;
18357 array = test_case.m_is_input ? "[]" : "";
18358 index = test_case.m_is_input ? "[0]" : "";
18359 break;
18360 case Utils::Shader::VERTEX:
18361 source = vs_tested;
18362 break;
18363 default:
18364 TCU_FAIL("Invalid enum");
18365 }
18366
18367 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18368 position = 0;
18369 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18370 Utils::replaceToken("FLAT", position, flat_gohan, source);
18371 Utils::replaceToken("DIRECTION", position, direction, source);
18372 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18373 Utils::replaceToken("ARRAY", position, array, source);
18374 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18375 Utils::replaceToken("FLAT", position, flat_goten, source);
18376 Utils::replaceToken("DIRECTION", position, direction, source);
18377 Utils::replaceToken("TYPE", position, type_goten_name, source);
18378 Utils::replaceToken("ARRAY", position, array, source);
18379
18380 temp = position;
18381 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18382 position = temp;
18383 if (!test_case.m_is_input)
18384 {
18385 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18386 Utils::replaceToken("TYPE", position, type_goten_name, source);
18387 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18388 Utils::replaceToken("TYPE", position, type_goten_name, source);
18389 }
18390 else if (Utils::Shader::VERTEX == stage)
18391 {
18392 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18393 Utils::replaceToken("TYPE", position, type_goten_name, source);
18394 }
18395
18396 Utils::replaceAllTokens("INDEX", index, source);
18397 }
18398 else
18399 {
18400 switch (stage)
18401 {
18402 case Utils::Shader::FRAGMENT:
18403 source = fs;
18404 break;
18405 case Utils::Shader::GEOMETRY:
18406 source = gs;
18407 break;
18408 case Utils::Shader::TESS_CTRL:
18409 source = tcs;
18410 break;
18411 case Utils::Shader::TESS_EVAL:
18412 source = tes;
18413 break;
18414 case Utils::Shader::VERTEX:
18415 source = vs;
18416 break;
18417 default:
18418 TCU_FAIL("Invalid enum");
18419 }
18420 }
18421
18422 return source;
18423 }
18424
18425 /** Get description of test case
18426 *
18427 * @param test_case_index Index of test case
18428 *
18429 * @return Test case description
18430 **/
18431 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index)
18432 {
18433 std::stringstream stream;
18434 testCase &test_case = m_test_cases[test_case_index];
18435
18436 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18437 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18438 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18439
18440 if (true == test_case.m_is_input)
18441 {
18442 stream << "input";
18443 }
18444 else
18445 {
18446 stream << "output";
18447 }
18448
18449 return stream.str();
18450 }
18451
18452 /** Get number of test cases
18453 *
18454 * @return Number of test cases
18455 **/
18456 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber()
18457 {
18458 return static_cast<GLuint>(m_test_cases.size());
18459 }
18460
18461 /** Selects if "compute" stage is relevant for test
18462 *
18463 * @param ignored
18464 *
18465 * @return false
18466 **/
18467 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */)
18468 {
18469 return false;
18470 }
18471
18472 /** Prepare all test cases
18473 *
18474 **/
18475 void VaryingLocationAliasingWithMixedTypesTest::testInit()
18476 {
18477 const GLuint n_types = getTypesNumber();
18478
18479 for (GLuint i = 0; i < n_types; ++i)
18480 {
18481 const Utils::Type &type_gohan = getType(i);
18482 const std::vector<GLuint> &valid_components_gohan = type_gohan.GetValidComponents();
18483
18484 if (valid_components_gohan.empty())
18485 {
18486 continue;
18487 }
18488
18489 for (GLuint j = 0; j < n_types; ++j)
18490 {
18491 const Utils::Type &type_goten = getType(j);
18492 const std::vector<GLuint> &valid_components_goten = type_goten.GetValidComponents();
18493
18494 if (valid_components_goten.empty())
18495 {
18496 continue;
18497 }
18498
18499 /* Skip valid combinations */
18500 if (Utils::Type::CanTypesShareLocation(type_gohan.m_basic_type, type_goten.m_basic_type))
18501 {
18502 continue;
18503 }
18504
18505 for (std::vector<GLuint>::const_iterator it_gohan = valid_components_gohan.begin();
18506 it_gohan != valid_components_gohan.end(); ++it_gohan)
18507 {
18508 const GLuint min_component = *it_gohan + type_gohan.GetNumComponents();
18509 for (std::vector<GLuint>::const_iterator it_goten = valid_components_goten.begin();
18510 it_goten != valid_components_goten.end(); ++it_goten)
18511 {
18512
18513 if (min_component > *it_goten)
18514 {
18515 continue;
18516 }
18517
18518 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18519 {
18520 /* Skip compute shader */
18521 if (Utils::Shader::COMPUTE == stage)
18522 {
18523 continue;
18524 }
18525
18526 if (Utils::Shader::VERTEX != stage)
18527 {
18528 testCase test_case_in = {*it_gohan, *it_goten, true, (Utils::Shader::STAGES)stage,
18529 type_gohan, type_goten};
18530
18531 m_test_cases.push_back(test_case_in);
18532 }
18533
18534 /* Skip double outputs in fragment shader */
18535 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
18536 (Utils::Type::Double != type_goten.m_basic_type)))
18537 {
18538 testCase test_case_out = {*it_gohan, *it_goten, false, (Utils::Shader::STAGES)stage,
18539 type_gohan, type_goten};
18540
18541 m_test_cases.push_back(test_case_out);
18542 }
18543 }
18544 }
18545 }
18546 }
18547 }
18548 }
18549
18550 /** Constructor
18551 *
18552 * @param context Test framework context
18553 **/
18554 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest(
18555 deqp::Context &context)
18556 : NegativeTestBase(
18557 context, "varying_location_aliasing_with_mixed_interpolation",
18558 "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location")
18559 {
18560 }
18561
18562 /** Source for given test case and stage
18563 *
18564 * @param test_case_index Index of test case
18565 * @param stage Shader stage
18566 *
18567 * @return Shader source
18568 **/
18569 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint test_case_index,
18570 Utils::Shader::STAGES stage)
18571 {
18572 static const GLchar *var_definition =
18573 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
18574 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
18575 static const GLchar *input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
18576 " (TYPE(1) == gotenINDEX) )\n"
18577 " {\n"
18578 " result += vec4(1, 0.5, 0.25, 0.125);\n"
18579 " }\n";
18580 static const GLchar *output_use = " gohanINDEX = TYPE(0);\n"
18581 " gotenINDEX = TYPE(1);\n"
18582 " if (vec4(0) == result)\n"
18583 " {\n"
18584 " gohanINDEX = TYPE(1);\n"
18585 " gotenINDEX = TYPE(0);\n"
18586 " }\n";
18587 static const GLchar *fs = "#version 430 core\n"
18588 "#extension GL_ARB_enhanced_layouts : require\n"
18589 "\n"
18590 "in vec4 gs_fs;\n"
18591 "out vec4 fs_out;\n"
18592 "\n"
18593 "void main()\n"
18594 "{\n"
18595 " fs_out = gs_fs;\n"
18596 "}\n"
18597 "\n";
18598 static const GLchar *fs_tested = "#version 430 core\n"
18599 "#extension GL_ARB_enhanced_layouts : require\n"
18600 "\n"
18601 "VAR_DEFINITION"
18602 "\n"
18603 "in vec4 gs_fs;\n"
18604 "out vec4 fs_out;\n"
18605 "\n"
18606 "void main()\n"
18607 "{\n"
18608 " vec4 result = gs_fs;\n"
18609 "\n"
18610 "VARIABLE_USE"
18611 "\n"
18612 " fs_out = result;\n"
18613 "}\n"
18614 "\n";
18615 static const GLchar *gs = "#version 430 core\n"
18616 "#extension GL_ARB_enhanced_layouts : require\n"
18617 "\n"
18618 "layout(points) in;\n"
18619 "layout(triangle_strip, max_vertices = 4) out;\n"
18620 "\n"
18621 "in vec4 tes_gs[];\n"
18622 "out vec4 gs_fs;\n"
18623 "\n"
18624 "void main()\n"
18625 "{\n"
18626 " gs_fs = tes_gs[0];\n"
18627 " gl_Position = vec4(-1, -1, 0, 1);\n"
18628 " EmitVertex();\n"
18629 " gs_fs = tes_gs[0];\n"
18630 " gl_Position = vec4(-1, 1, 0, 1);\n"
18631 " EmitVertex();\n"
18632 " gs_fs = tes_gs[0];\n"
18633 " gl_Position = vec4(1, -1, 0, 1);\n"
18634 " EmitVertex();\n"
18635 " gs_fs = tes_gs[0];\n"
18636 " gl_Position = vec4(1, 1, 0, 1);\n"
18637 " EmitVertex();\n"
18638 "}\n"
18639 "\n";
18640 static const GLchar *gs_tested = "#version 430 core\n"
18641 "#extension GL_ARB_enhanced_layouts : require\n"
18642 "\n"
18643 "layout(points) in;\n"
18644 "layout(triangle_strip, max_vertices = 4) out;\n"
18645 "\n"
18646 "VAR_DEFINITION"
18647 "\n"
18648 "in vec4 tes_gs[];\n"
18649 "out vec4 gs_fs;\n"
18650 "\n"
18651 "void main()\n"
18652 "{\n"
18653 " vec4 result = tes_gs[0];\n"
18654 "\n"
18655 "VARIABLE_USE"
18656 "\n"
18657 " gs_fs = result;\n"
18658 " gl_Position = vec4(-1, -1, 0, 1);\n"
18659 " EmitVertex();\n"
18660 " gs_fs = result;\n"
18661 " gl_Position = vec4(-1, 1, 0, 1);\n"
18662 " EmitVertex();\n"
18663 " gs_fs = result;\n"
18664 " gl_Position = vec4(1, -1, 0, 1);\n"
18665 " EmitVertex();\n"
18666 " gs_fs = result;\n"
18667 " gl_Position = vec4(1, 1, 0, 1);\n"
18668 " EmitVertex();\n"
18669 "}\n"
18670 "\n";
18671 static const GLchar *tcs = "#version 430 core\n"
18672 "#extension GL_ARB_enhanced_layouts : require\n"
18673 "\n"
18674 "layout(vertices = 1) out;\n"
18675 "\n"
18676 "in vec4 vs_tcs[];\n"
18677 "out vec4 tcs_tes[];\n"
18678 "\n"
18679 "void main()\n"
18680 "{\n"
18681 "\n"
18682 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18683 "\n"
18684 " gl_TessLevelOuter[0] = 1.0;\n"
18685 " gl_TessLevelOuter[1] = 1.0;\n"
18686 " gl_TessLevelOuter[2] = 1.0;\n"
18687 " gl_TessLevelOuter[3] = 1.0;\n"
18688 " gl_TessLevelInner[0] = 1.0;\n"
18689 " gl_TessLevelInner[1] = 1.0;\n"
18690 "}\n"
18691 "\n";
18692 static const GLchar *tcs_tested = "#version 430 core\n"
18693 "#extension GL_ARB_enhanced_layouts : require\n"
18694 "\n"
18695 "layout(vertices = 1) out;\n"
18696 "\n"
18697 "VAR_DEFINITION"
18698 "\n"
18699 "in vec4 vs_tcs[];\n"
18700 "out vec4 tcs_tes[];\n"
18701 "\n"
18702 "void main()\n"
18703 "{\n"
18704 " vec4 result = vs_tcs[gl_InvocationID];\n"
18705 "\n"
18706 "VARIABLE_USE"
18707 "\n"
18708 " tcs_tes[gl_InvocationID] = result;\n"
18709 "\n"
18710 " gl_TessLevelOuter[0] = 1.0;\n"
18711 " gl_TessLevelOuter[1] = 1.0;\n"
18712 " gl_TessLevelOuter[2] = 1.0;\n"
18713 " gl_TessLevelOuter[3] = 1.0;\n"
18714 " gl_TessLevelInner[0] = 1.0;\n"
18715 " gl_TessLevelInner[1] = 1.0;\n"
18716 "}\n"
18717 "\n";
18718 static const GLchar *tes = "#version 430 core\n"
18719 "#extension GL_ARB_enhanced_layouts : require\n"
18720 "\n"
18721 "layout(isolines, point_mode) in;\n"
18722 "\n"
18723 "in vec4 tcs_tes[];\n"
18724 "out vec4 tes_gs;\n"
18725 "\n"
18726 "void main()\n"
18727 "{\n"
18728 " tes_gs = tcs_tes[0];\n"
18729 "}\n"
18730 "\n";
18731 static const GLchar *tes_tested = "#version 430 core\n"
18732 "#extension GL_ARB_enhanced_layouts : require\n"
18733 "\n"
18734 "layout(isolines, point_mode) in;\n"
18735 "\n"
18736 "VAR_DEFINITION"
18737 "\n"
18738 "in vec4 tcs_tes[];\n"
18739 "out vec4 tes_gs;\n"
18740 "\n"
18741 "void main()\n"
18742 "{\n"
18743 " vec4 result = tcs_tes[0];\n"
18744 "\n"
18745 "VARIABLE_USE"
18746 "\n"
18747 " tes_gs += result;\n"
18748 "}\n"
18749 "\n";
18750 static const GLchar *vs = "#version 430 core\n"
18751 "#extension GL_ARB_enhanced_layouts : require\n"
18752 "\n"
18753 "in vec4 in_vs;\n"
18754 "out vec4 vs_tcs;\n"
18755 "\n"
18756 "void main()\n"
18757 "{\n"
18758 " vs_tcs = in_vs;\n"
18759 "}\n"
18760 "\n";
18761 static const GLchar *vs_tested = "#version 430 core\n"
18762 "#extension GL_ARB_enhanced_layouts : require\n"
18763 "\n"
18764 "VAR_DEFINITION"
18765 "\n"
18766 "in vec4 in_vs;\n"
18767 "out vec4 vs_tcs;\n"
18768 "\n"
18769 "void main()\n"
18770 "{\n"
18771 " vec4 result = in_vs;\n"
18772 "\n"
18773 "VARIABLE_USE"
18774 "\n"
18775 " vs_tcs += result;\n"
18776 "}\n"
18777 "\n";
18778
18779 std::string source;
18780 testCase &test_case = m_test_cases[test_case_index];
18781
18782 if (test_case.m_stage == stage)
18783 {
18784 const GLchar *array = "";
18785 GLchar buffer_gohan[16];
18786 GLchar buffer_goten[16];
18787 const GLchar *direction = "in ";
18788 const GLchar *index = "";
18789 const GLchar *int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan);
18790 const GLchar *int_goten = getInterpolationQualifier(test_case.m_interpolation_goten);
18791 #if DEBUG_NEG_REMOVE_ERROR
18792 if (FLAT == test_case.m_interpolation_goten)
18793 {
18794 int_gohan = int_goten;
18795 }
18796 else
18797 {
18798 int_goten = int_gohan;
18799 }
18800 #endif /* DEBUG_NEG_REMOVE_ERROR */
18801 size_t position = 0;
18802 size_t temp;
18803 const GLchar *type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18804 const GLchar *type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18805 const GLchar *var_use = Utils::Shader::VERTEX == stage ? input_use : "\n";
18806
18807 if (false == test_case.m_is_input)
18808 {
18809 direction = "out";
18810
18811 var_use = output_use;
18812 }
18813
18814 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18815 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18816
18817 switch (stage)
18818 {
18819 case Utils::Shader::FRAGMENT:
18820 source = fs_tested;
18821 break;
18822 case Utils::Shader::GEOMETRY:
18823 source = gs_tested;
18824 array = test_case.m_is_input ? "[]" : "";
18825 index = test_case.m_is_input ? "[0]" : "";
18826 break;
18827 case Utils::Shader::TESS_CTRL:
18828 source = tcs_tested;
18829 array = "[]";
18830 index = "[gl_InvocationID]";
18831 break;
18832 case Utils::Shader::TESS_EVAL:
18833 source = tes_tested;
18834 array = test_case.m_is_input ? "[]" : "";
18835 index = test_case.m_is_input ? "[0]" : "";
18836 break;
18837 case Utils::Shader::VERTEX:
18838 source = vs_tested;
18839 break;
18840 default:
18841 TCU_FAIL("Invalid enum");
18842 }
18843
18844 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18845 position = 0;
18846 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18847 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18848 Utils::replaceToken("DIRECTION", position, direction, source);
18849 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18850 Utils::replaceToken("ARRAY", position, array, source);
18851 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18852 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18853 Utils::replaceToken("DIRECTION", position, direction, source);
18854 Utils::replaceToken("TYPE", position, type_goten_name, source);
18855 Utils::replaceToken("ARRAY", position, array, source);
18856
18857 temp = position;
18858 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18859 position = temp;
18860 if (!test_case.m_is_input)
18861 {
18862 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18863 Utils::replaceToken("TYPE", position, type_goten_name, source);
18864 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18865 Utils::replaceToken("TYPE", position, type_goten_name, source);
18866 }
18867 else if (Utils::Shader::VERTEX == stage)
18868 {
18869 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18870 Utils::replaceToken("TYPE", position, type_goten_name, source);
18871 }
18872
18873 Utils::replaceAllTokens("INDEX", index, source);
18874 }
18875 else
18876 {
18877 switch (stage)
18878 {
18879 case Utils::Shader::FRAGMENT:
18880 source = fs;
18881 break;
18882 case Utils::Shader::GEOMETRY:
18883 source = gs;
18884 break;
18885 case Utils::Shader::TESS_CTRL:
18886 source = tcs;
18887 break;
18888 case Utils::Shader::TESS_EVAL:
18889 source = tes;
18890 break;
18891 case Utils::Shader::VERTEX:
18892 source = vs;
18893 break;
18894 default:
18895 TCU_FAIL("Invalid enum");
18896 }
18897 }
18898
18899 return source;
18900 }
18901
18902 /** Get description of test case
18903 *
18904 * @param test_case_index Index of test case
18905 *
18906 * @return Test case description
18907 **/
18908 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index)
18909 {
18910 std::stringstream stream;
18911 testCase &test_case = m_test_cases[test_case_index];
18912
18913 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18914 << getInterpolationQualifier(test_case.m_interpolation_gohan) << " "
18915 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18916 << getInterpolationQualifier(test_case.m_interpolation_goten) << " "
18917 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18918
18919 if (true == test_case.m_is_input)
18920 {
18921 stream << "input";
18922 }
18923 else
18924 {
18925 stream << "output";
18926 }
18927
18928 return stream.str();
18929 }
18930
18931 /** Get number of test cases
18932 *
18933 * @return Number of test cases
18934 **/
18935 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber()
18936 {
18937 return static_cast<GLuint>(m_test_cases.size());
18938 }
18939
18940 /** Selects if "compute" stage is relevant for test
18941 *
18942 * @param ignored
18943 *
18944 * @return false
18945 **/
18946 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */)
18947 {
18948 return false;
18949 }
18950
18951 /** Prepare all test cases
18952 *
18953 **/
18954 void VaryingLocationAliasingWithMixedInterpolationTest::testInit()
18955 {
18956 const GLuint n_types = getTypesNumber();
18957
18958 for (GLuint i = 0; i < n_types; ++i)
18959 {
18960 const Utils::Type &type_gohan = getType(i);
18961 const std::vector<GLuint> &valid_components_gohan = type_gohan.GetValidComponents();
18962
18963 if (valid_components_gohan.empty())
18964 {
18965 continue;
18966 }
18967
18968 const GLuint gohan = valid_components_gohan.front();
18969
18970 for (GLuint j = 0; j < n_types; ++j)
18971 {
18972 const Utils::Type &type_goten = getType(j);
18973 const std::vector<GLuint> &valid_components_goten = type_goten.GetValidComponents();
18974
18975 if (valid_components_goten.empty())
18976 {
18977 continue;
18978 }
18979
18980 /* Just get the highest valid component for goten and
18981 * check if we can use it.
18982 */
18983 const GLuint min_component = gohan + type_gohan.GetNumComponents();
18984 const GLuint goten = valid_components_goten.back();
18985
18986 if (min_component > goten)
18987 {
18988 continue;
18989 }
18990
18991 /* Skip invalid combinations */
18992 if (!Utils::Type::CanTypesShareLocation(type_gohan.m_basic_type, type_goten.m_basic_type))
18993 {
18994 continue;
18995 }
18996
18997 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18998 {
18999 /* Skip compute shader */
19000 if (Utils::Shader::COMPUTE == stage)
19001 {
19002 continue;
19003 }
19004
19005 for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan)
19006 {
19007 for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten)
19008 {
19009 /* Skip when both are the same */
19010 if (int_gohan == int_goten)
19011 {
19012 continue;
19013 }
19014
19015 /* Skip inputs in: vertex shader and whenever
19016 * flat is mandatory and is not the chosen
19017 * one.
19018 */
19019 bool skip_inputs = Utils::Shader::VERTEX == stage;
19020 skip_inputs |=
19021 (FLAT != int_gohan && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_gohan,
19022 Utils::Variable::VARYING_INPUT));
19023 skip_inputs |=
19024 (FLAT != int_goten && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_goten,
19025 Utils::Variable::VARYING_INPUT));
19026
19027 if (!skip_inputs)
19028 {
19029 testCase test_case_in = {gohan,
19030 goten,
19031 static_cast<INTERPOLATIONS>(int_gohan),
19032 static_cast<INTERPOLATIONS>(int_goten),
19033 true,
19034 static_cast<Utils::Shader::STAGES>(stage),
19035 type_gohan,
19036 type_goten};
19037 m_test_cases.push_back(test_case_in);
19038 }
19039
19040 /* Skip outputs in fragment shader and
19041 * whenever flat is mandatory and is not the
19042 * chosen one.
19043 */
19044 bool skip_outputs = Utils::Shader::FRAGMENT == stage;
19045 skip_outputs |=
19046 (FLAT != int_gohan && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_gohan,
19047 Utils::Variable::VARYING_OUTPUT));
19048 skip_outputs |=
19049 (FLAT != int_goten && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_goten,
19050 Utils::Variable::VARYING_OUTPUT));
19051
19052 if (!skip_outputs)
19053 {
19054 testCase test_case_out = {gohan,
19055 goten,
19056 static_cast<INTERPOLATIONS>(int_gohan),
19057 static_cast<INTERPOLATIONS>(int_goten),
19058 false,
19059 static_cast<Utils::Shader::STAGES>(stage),
19060 type_gohan,
19061 type_goten};
19062 m_test_cases.push_back(test_case_out);
19063 }
19064 }
19065 }
19066 }
19067 }
19068 }
19069 }
19070
19071 /** Get interpolation qualifier
19072 *
19073 * @param interpolation Enumeration
19074 *
19075 * @return GLSL qualifier
19076 **/
19077 const GLchar *VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation)
19078 {
19079 const GLchar *result = 0;
19080
19081 switch (interpolation)
19082 {
19083 case SMOOTH:
19084 result = "smooth";
19085 break;
19086 case FLAT:
19087 result = "flat";
19088 break;
19089 case NO_PERSPECTIVE:
19090 result = "noperspective";
19091 break;
19092 default:
19093 TCU_FAIL("Invalid enum");
19094 }
19095
19096 return result;
19097 }
19098
19099 /** Constructor
19100 *
19101 * @param context Test framework context
19102 **/
19103 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(
19104 deqp::Context &context)
19105 : NegativeTestBase(
19106 context, "varying_location_aliasing_with_mixed_auxiliary_storage",
19107 "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location")
19108 {
19109 }
19110
19111 /** Source for given test case and stage
19112 *
19113 * @param test_case_index Index of test case
19114 * @param stage Shader stage
19115 *
19116 * @return Shader source
19117 **/
19118 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint test_case_index,
19119 Utils::Shader::STAGES stage)
19120 {
19121 static const GLchar *var_definition =
19122 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
19123 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
19124 static const GLchar *input_use = " if ((TYPE(0) == gohanINDEX_GOHAN) &&\n"
19125 " (TYPE(1) == gotenINDEX_GOTEN) )\n"
19126 " {\n"
19127 " result += vec4(1, 0.5, 0.25, 0.125);\n"
19128 " }\n";
19129 static const GLchar *output_use = " gohanINDEX_GOHAN = TYPE(0);\n"
19130 " gotenINDEX_GOTEN = TYPE(1);\n"
19131 " if (vec4(0) == result)\n"
19132 " {\n"
19133 " gohanINDEX_GOHAN = TYPE(1);\n"
19134 " gotenINDEX_GOTEN = TYPE(0);\n"
19135 " }\n";
19136 static const GLchar *fs = "#version 430 core\n"
19137 "#extension GL_ARB_enhanced_layouts : require\n"
19138 "\n"
19139 "in vec4 gs_fs;\n"
19140 "out vec4 fs_out;\n"
19141 "\n"
19142 "void main()\n"
19143 "{\n"
19144 " fs_out = gs_fs;\n"
19145 "}\n"
19146 "\n";
19147 static const GLchar *fs_tested = "#version 430 core\n"
19148 "#extension GL_ARB_enhanced_layouts : require\n"
19149 "\n"
19150 "VAR_DEFINITION"
19151 "\n"
19152 "in vec4 gs_fs;\n"
19153 "out vec4 fs_out;\n"
19154 "\n"
19155 "void main()\n"
19156 "{\n"
19157 " vec4 result = gs_fs;\n"
19158 "\n"
19159 "VARIABLE_USE"
19160 "\n"
19161 " fs_out = result;\n"
19162 "}\n"
19163 "\n";
19164 static const GLchar *gs = "#version 430 core\n"
19165 "#extension GL_ARB_enhanced_layouts : require\n"
19166 "\n"
19167 "layout(points) in;\n"
19168 "layout(triangle_strip, max_vertices = 4) out;\n"
19169 "\n"
19170 "in vec4 tes_gs[];\n"
19171 "out vec4 gs_fs;\n"
19172 "\n"
19173 "void main()\n"
19174 "{\n"
19175 " gs_fs = tes_gs[0];\n"
19176 " gl_Position = vec4(-1, -1, 0, 1);\n"
19177 " EmitVertex();\n"
19178 " gs_fs = tes_gs[0];\n"
19179 " gl_Position = vec4(-1, 1, 0, 1);\n"
19180 " EmitVertex();\n"
19181 " gs_fs = tes_gs[0];\n"
19182 " gl_Position = vec4(1, -1, 0, 1);\n"
19183 " EmitVertex();\n"
19184 " gs_fs = tes_gs[0];\n"
19185 " gl_Position = vec4(1, 1, 0, 1);\n"
19186 " EmitVertex();\n"
19187 "}\n"
19188 "\n";
19189 static const GLchar *gs_tested = "#version 430 core\n"
19190 "#extension GL_ARB_enhanced_layouts : require\n"
19191 "\n"
19192 "layout(points) in;\n"
19193 "layout(triangle_strip, max_vertices = 4) out;\n"
19194 "\n"
19195 "VAR_DEFINITION"
19196 "\n"
19197 "in vec4 tes_gs[];\n"
19198 "out vec4 gs_fs;\n"
19199 "\n"
19200 "void main()\n"
19201 "{\n"
19202 " vec4 result = tes_gs[0];\n"
19203 "\n"
19204 "VARIABLE_USE"
19205 "\n"
19206 " gs_fs = result;\n"
19207 " gl_Position = vec4(-1, -1, 0, 1);\n"
19208 " EmitVertex();\n"
19209 " gs_fs = result;\n"
19210 " gl_Position = vec4(-1, 1, 0, 1);\n"
19211 " EmitVertex();\n"
19212 " gs_fs = result;\n"
19213 " gl_Position = vec4(1, -1, 0, 1);\n"
19214 " EmitVertex();\n"
19215 " gs_fs = result;\n"
19216 " gl_Position = vec4(1, 1, 0, 1);\n"
19217 " EmitVertex();\n"
19218 "}\n"
19219 "\n";
19220 static const GLchar *tcs = "#version 430 core\n"
19221 "#extension GL_ARB_enhanced_layouts : require\n"
19222 "\n"
19223 "layout(vertices = 1) out;\n"
19224 "\n"
19225 "in vec4 vs_tcs[];\n"
19226 "out vec4 tcs_tes[];\n"
19227 "\n"
19228 "void main()\n"
19229 "{\n"
19230 "\n"
19231 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
19232 "\n"
19233 " gl_TessLevelOuter[0] = 1.0;\n"
19234 " gl_TessLevelOuter[1] = 1.0;\n"
19235 " gl_TessLevelOuter[2] = 1.0;\n"
19236 " gl_TessLevelOuter[3] = 1.0;\n"
19237 " gl_TessLevelInner[0] = 1.0;\n"
19238 " gl_TessLevelInner[1] = 1.0;\n"
19239 "}\n"
19240 "\n";
19241 static const GLchar *tcs_tested = "#version 430 core\n"
19242 "#extension GL_ARB_enhanced_layouts : require\n"
19243 "\n"
19244 "layout(vertices = 1) out;\n"
19245 "\n"
19246 "VAR_DEFINITION"
19247 "\n"
19248 "in vec4 vs_tcs[];\n"
19249 "out vec4 tcs_tes[];\n"
19250 "\n"
19251 "void main()\n"
19252 "{\n"
19253 " vec4 result = vs_tcs[gl_InvocationID];\n"
19254 "\n"
19255 "VARIABLE_USE"
19256 "\n"
19257 " tcs_tes[gl_InvocationID] = result;\n"
19258 "\n"
19259 " gl_TessLevelOuter[0] = 1.0;\n"
19260 " gl_TessLevelOuter[1] = 1.0;\n"
19261 " gl_TessLevelOuter[2] = 1.0;\n"
19262 " gl_TessLevelOuter[3] = 1.0;\n"
19263 " gl_TessLevelInner[0] = 1.0;\n"
19264 " gl_TessLevelInner[1] = 1.0;\n"
19265 "}\n"
19266 "\n";
19267 static const GLchar *tes = "#version 430 core\n"
19268 "#extension GL_ARB_enhanced_layouts : require\n"
19269 "\n"
19270 "layout(isolines, point_mode) in;\n"
19271 "\n"
19272 "in vec4 tcs_tes[];\n"
19273 "out vec4 tes_gs;\n"
19274 "\n"
19275 "void main()\n"
19276 "{\n"
19277 " tes_gs = tcs_tes[0];\n"
19278 "}\n"
19279 "\n";
19280 static const GLchar *tes_tested = "#version 430 core\n"
19281 "#extension GL_ARB_enhanced_layouts : require\n"
19282 "\n"
19283 "layout(isolines, point_mode) in;\n"
19284 "\n"
19285 "VAR_DEFINITION"
19286 "\n"
19287 "in vec4 tcs_tes[];\n"
19288 "out vec4 tes_gs;\n"
19289 "\n"
19290 "void main()\n"
19291 "{\n"
19292 " vec4 result = tcs_tes[0];\n"
19293 "\n"
19294 "VARIABLE_USE"
19295 "\n"
19296 " tes_gs += result;\n"
19297 "}\n"
19298 "\n";
19299 static const GLchar *vs = "#version 430 core\n"
19300 "#extension GL_ARB_enhanced_layouts : require\n"
19301 "\n"
19302 "in vec4 in_vs;\n"
19303 "out vec4 vs_tcs;\n"
19304 "\n"
19305 "void main()\n"
19306 "{\n"
19307 " vs_tcs = in_vs;\n"
19308 "}\n"
19309 "\n";
19310 static const GLchar *vs_tested = "#version 430 core\n"
19311 "#extension GL_ARB_enhanced_layouts : require\n"
19312 "\n"
19313 "VAR_DEFINITION"
19314 "\n"
19315 "in vec4 in_vs;\n"
19316 "out vec4 vs_tcs;\n"
19317 "\n"
19318 "void main()\n"
19319 "{\n"
19320 " vec4 result = in_vs;\n"
19321 "\n"
19322 "VARIABLE_USE"
19323 "\n"
19324 " vs_tcs += result;\n"
19325 "}\n"
19326 "\n";
19327
19328 std::string source;
19329 testCase &test_case = m_test_cases[test_case_index];
19330
19331 if (test_case.m_stage == stage)
19332 {
19333 const GLchar *array_gohan = "";
19334 const GLchar *array_goten = "";
19335 const GLchar *aux_gohan = getAuxiliaryQualifier(test_case.m_aux_gohan);
19336 #if DEBUG_NEG_REMOVE_ERROR
19337 const GLchar *aux_goten = aux_gohan;
19338 #else
19339 const GLchar *aux_goten = getAuxiliaryQualifier(test_case.m_aux_goten);
19340 #endif /* DEBUG_NEG_REMOVE_ERROR */
19341 GLchar buffer_gohan[16];
19342 GLchar buffer_goten[16];
19343 const GLchar *direction = "in";
19344 const GLchar *index_gohan = "";
19345 const GLchar *index_goten = "";
19346 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
19347 const GLchar *interpolation = "";
19348 size_t position = 0;
19349 size_t temp;
19350 const GLchar *type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
19351 const GLchar *type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
19352 const GLchar *var_use = Utils::Shader::VERTEX == stage ? input_use : "\n";
19353
19354 if (false == test_case.m_is_input)
19355 {
19356 direction = "out";
19357 storage = Utils::Variable::VARYING_OUTPUT;
19358 var_use = output_use;
19359 }
19360
19361 if (isFlatRequired(stage, test_case.m_type_gohan, storage) ||
19362 isFlatRequired(stage, test_case.m_type_goten, storage))
19363 {
19364 interpolation = "flat";
19365 }
19366
19367 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
19368 sprintf(buffer_goten, "%d", test_case.m_component_goten);
19369
19370 switch (stage)
19371 {
19372 case Utils::Shader::FRAGMENT:
19373 source = fs_tested;
19374 break;
19375 case Utils::Shader::GEOMETRY:
19376 source = gs_tested;
19377 array_gohan = test_case.m_is_input ? "[]" : "";
19378 index_gohan = test_case.m_is_input ? "[0]" : "";
19379 array_goten = test_case.m_is_input ? "[]" : "";
19380 index_goten = test_case.m_is_input ? "[0]" : "";
19381 break;
19382 case Utils::Shader::TESS_CTRL:
19383 source = tcs_tested;
19384 if (PATCH != test_case.m_aux_gohan)
19385 {
19386 array_gohan = "[]";
19387 index_gohan = "[gl_InvocationID]";
19388 }
19389 #if DEBUG_NEG_REMOVE_ERROR
19390 array_goten = array_gohan;
19391 index_goten = index_gohan;
19392 #else
19393 if (PATCH != test_case.m_aux_goten)
19394 {
19395 array_goten = "[]";
19396 index_goten = "[gl_InvocationID]";
19397 }
19398 #endif /* DEBUG_NEG_REMOVE_ERROR */
19399 break;
19400 case Utils::Shader::TESS_EVAL:
19401 source = tes_tested;
19402 if (PATCH != test_case.m_aux_gohan)
19403 {
19404 array_gohan = test_case.m_is_input ? "[]" : "";
19405 index_gohan = test_case.m_is_input ? "[0]" : "";
19406 }
19407 #if DEBUG_NEG_REMOVE_ERROR
19408 array_goten = array_gohan;
19409 index_goten = index_gohan;
19410 #else
19411 if (PATCH != test_case.m_aux_goten)
19412 {
19413 array_goten = test_case.m_is_input ? "[]" : "";
19414 index_goten = test_case.m_is_input ? "[0]" : "";
19415 }
19416 #endif /* DEBUG_NEG_REMOVE_ERROR */
19417 break;
19418 case Utils::Shader::VERTEX:
19419 source = vs_tested;
19420 break;
19421 default:
19422 TCU_FAIL("Invalid enum");
19423 }
19424
19425 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
19426 position = 0;
19427 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
19428 Utils::replaceToken("AUX", position, aux_gohan, source);
19429 Utils::replaceToken("INTERPOLATION", position, interpolation, source);
19430 Utils::replaceToken("DIRECTION", position, direction, source);
19431 Utils::replaceToken("TYPE", position, type_gohan_name, source);
19432 Utils::replaceToken("ARRAY", position, array_gohan, source);
19433 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
19434 Utils::replaceToken("AUX", position, aux_goten, source);
19435 Utils::replaceToken("INTERPOLATION", position, interpolation, source);
19436 Utils::replaceToken("DIRECTION", position, direction, source);
19437 Utils::replaceToken("TYPE", position, type_goten_name, source);
19438 Utils::replaceToken("ARRAY", position, array_goten, source);
19439
19440 temp = position;
19441 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
19442 position = temp;
19443 if (!test_case.m_is_input)
19444 {
19445 Utils::replaceToken("TYPE", position, type_gohan_name, source);
19446 Utils::replaceToken("TYPE", position, type_goten_name, source);
19447 Utils::replaceToken("TYPE", position, type_gohan_name, source);
19448 Utils::replaceToken("TYPE", position, type_goten_name, source);
19449 }
19450 else if (Utils::Shader::VERTEX == stage)
19451 {
19452 Utils::replaceToken("TYPE", position, type_gohan_name, source);
19453 Utils::replaceToken("TYPE", position, type_goten_name, source);
19454 }
19455
19456 Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source);
19457 Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source);
19458 }
19459 else
19460 {
19461 switch (stage)
19462 {
19463 case Utils::Shader::FRAGMENT:
19464 source = fs;
19465 break;
19466 case Utils::Shader::GEOMETRY:
19467 source = gs;
19468 break;
19469 case Utils::Shader::TESS_CTRL:
19470 source = tcs;
19471 break;
19472 case Utils::Shader::TESS_EVAL:
19473 source = tes;
19474 break;
19475 case Utils::Shader::VERTEX:
19476 source = vs;
19477 break;
19478 default:
19479 TCU_FAIL("Invalid enum");
19480 }
19481 }
19482
19483 return source;
19484 }
19485
19486 /** Get description of test case
19487 *
19488 * @param test_case_index Index of test case
19489 *
19490 * @return Test case description
19491 **/
19492 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index)
19493 {
19494 std::stringstream stream;
19495 testCase &test_case = m_test_cases[test_case_index];
19496
19497 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
19498 << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at "
19499 << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " "
19500 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
19501
19502 if (true == test_case.m_is_input)
19503 {
19504 stream << "input";
19505 }
19506 else
19507 {
19508 stream << "output";
19509 }
19510
19511 return stream.str();
19512 }
19513
19514 /** Get number of test cases
19515 *
19516 * @return Number of test cases
19517 **/
19518 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber()
19519 {
19520 return static_cast<GLuint>(m_test_cases.size());
19521 }
19522
19523 /** Selects if "compute" stage is relevant for test
19524 *
19525 * @param ignored
19526 *
19527 * @return false
19528 **/
19529 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */)
19530 {
19531 return false;
19532 }
19533
19534 /** Prepare all test cases
19535 *
19536 **/
19537 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit()
19538 {
19539 const GLuint n_types = getTypesNumber();
19540
19541 for (GLuint i = 0; i < n_types; ++i)
19542 {
19543 const Utils::Type &type_gohan = getType(i);
19544 const std::vector<GLuint> &valid_components_gohan = type_gohan.GetValidComponents();
19545
19546 if (valid_components_gohan.empty())
19547 {
19548 continue;
19549 }
19550
19551 const GLuint gohan = valid_components_gohan.front();
19552
19553 for (GLuint j = 0; j < n_types; ++j)
19554 {
19555 const Utils::Type &type_goten = getType(j);
19556 const std::vector<GLuint> &valid_components_goten = type_goten.GetValidComponents();
19557
19558 if (valid_components_goten.empty())
19559 {
19560 continue;
19561 }
19562
19563 /* Just get the highest valid component for goten and
19564 * check if we can use it.
19565 */
19566 const GLuint min_component = gohan + type_gohan.GetNumComponents();
19567 const GLuint goten = valid_components_goten.back();
19568
19569 if (min_component > goten)
19570 {
19571 continue;
19572 }
19573
19574 /* Skip invalid combinations */
19575 if (!Utils::Type::CanTypesShareLocation(type_gohan.m_basic_type, type_goten.m_basic_type))
19576 {
19577 continue;
19578 }
19579
19580 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
19581 {
19582 /* Skip compute shader */
19583 if (Utils::Shader::COMPUTE == stage)
19584 {
19585 continue;
19586 }
19587
19588 for (GLuint aux = 0; aux < AUXILIARY_MAX; ++aux)
19589 {
19590 Utils::Shader::STAGES const shader_stage = static_cast<Utils::Shader::STAGES>(stage);
19591 AUXILIARIES const auxiliary = static_cast<AUXILIARIES>(aux);
19592
19593 if (PATCH == auxiliary)
19594 {
19595 if (Utils::Shader::TESS_CTRL == shader_stage || Utils::Shader::TESS_EVAL == shader_stage)
19596 {
19597 bool direction = Utils::Shader::TESS_EVAL == shader_stage;
19598 testCase test_case_patch_gohan = {gohan, goten, auxiliary, NONE,
19599 direction, shader_stage, type_gohan, type_goten};
19600 testCase test_case_patch_goten = {gohan, goten, NONE, auxiliary,
19601 direction, shader_stage, type_gohan, type_goten};
19602
19603 m_test_cases.push_back(test_case_patch_gohan);
19604 m_test_cases.push_back(test_case_patch_goten);
19605 }
19606 continue;
19607 }
19608
19609 for (GLuint second_aux = 0; second_aux < AUXILIARY_MAX; ++second_aux)
19610 {
19611 AUXILIARIES const second_auxiliary = static_cast<AUXILIARIES>(second_aux);
19612
19613 if (PATCH == second_auxiliary || auxiliary == second_auxiliary)
19614 {
19615 continue;
19616 }
19617
19618 if (Utils::Shader::FRAGMENT != shader_stage)
19619 {
19620 testCase test_case_out = {gohan, goten, auxiliary, second_auxiliary,
19621 false, shader_stage, type_gohan, type_goten};
19622
19623 m_test_cases.push_back(test_case_out);
19624 }
19625
19626 if (Utils::Shader::VERTEX != shader_stage)
19627 {
19628 testCase test_case_in = {gohan, goten, auxiliary, second_auxiliary,
19629 true, shader_stage, type_gohan, type_goten};
19630
19631 m_test_cases.push_back(test_case_in);
19632 }
19633 }
19634 }
19635 }
19636 }
19637 }
19638 }
19639
19640 /** Get auxiliary storage qualifier
19641 *
19642 * @param aux Enumeration
19643 *
19644 * @return GLSL qualifier
19645 **/
19646 const GLchar *VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux)
19647 {
19648 const GLchar *result = 0;
19649
19650 switch (aux)
19651 {
19652 case NONE:
19653 result = "";
19654 break;
19655 case PATCH:
19656 result = "patch";
19657 break;
19658 case CENTROID:
19659 result = "centroid";
19660 break;
19661 case SAMPLE:
19662 result = "sample";
19663 break;
19664 default:
19665 TCU_FAIL("Invalid enum");
19666 }
19667
19668 return result;
19669 }
19670
19671 /* Constants used by VertexAttribLocationAPITest */
19672 const GLuint VertexAttribLocationAPITest::m_goten_location = 6;
19673
19674 /** Constructor
19675 *
19676 * @param context Test framework context
19677 **/
19678 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context &context)
19679 : TextureTestBase(context, "vertex_attrib_location_api",
19680 "Test verifies that attribute locations API works as expected")
19681 {
19682 }
19683
19684 /** Does BindAttribLocation for "goten" and relink program
19685 *
19686 * @param program Program object
19687 * @param program_interface Interface of program
19688 **/
19689 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program &program,
19690 Utils::ProgramInterface &program_interface)
19691 {
19692 const Functions &gl = m_context.getRenderContext().getFunctions();
19693
19694 gl.bindAttribLocation(program.m_id, m_goten_location, "goten");
19695 GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation");
19696
19697 program.Link(gl, program.m_id);
19698
19699 /* We still need to get locations for gohan and chichi */
19700 TextureTestBase::prepareAttribLocation(program, program_interface);
19701 }
19702
19703 /** Get interface of program
19704 *
19705 * @param ignored
19706 * @param program_interface Interface of program
19707 * @param ignored
19708 **/
19709 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19710 Utils::ProgramInterface &program_interface,
19711 Utils::VaryingPassthrough & /* varying_passthrough */)
19712 {
19713 Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
19714 const Utils::Type &type = Utils::Type::vec4;
19715 const GLuint type_size = type.GetSize();
19716
19717 /* Offsets */
19718 const GLuint chichi_offset = 0;
19719 const GLuint goten_offset = chichi_offset + type_size;
19720 const GLuint gohan_offset = goten_offset + type_size;
19721 const GLuint goku_offset = gohan_offset + type_size;
19722
19723 /* Locations */
19724 const GLuint goku_location = 2;
19725 const GLuint goten_location = m_goten_location;
19726
19727 /* Generate data */
19728 m_goku_data = type.GenerateDataPacked();
19729 m_gohan_data = type.GenerateDataPacked();
19730 m_goten_data = type.GenerateDataPacked();
19731 m_chichi_data = type.GenerateDataPacked();
19732
19733 /* Globals */
19734 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19735
19736 /* Attributes */
19737 si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19738 goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19739 0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid *)&m_goku_data[0] /* data */,
19740 m_goku_data.size() /* data_size */);
19741
19742 si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19743 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19744 0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */,
19745 (GLvoid *)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */);
19746
19747 si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19748 goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19749 0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */,
19750 (GLvoid *)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */);
19751
19752 si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19753 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19754 0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */,
19755 (GLvoid *)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */);
19756 }
19757
19758 /** Selects if "compute" stage is relevant for test
19759 *
19760 * @param ignored
19761 *
19762 * @return false
19763 **/
19764 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19765 {
19766 return false;
19767 }
19768
19769 /* Constants used by FragmentDataLocationAPITest */
19770 const GLuint FragmentDataLocationAPITest::m_goten_location = 6;
19771
19772 /** Constructor
19773 *
19774 * @param context Test framework context
19775 **/
19776 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context &context)
19777 : TextureTestBase(context, "fragment_data_location_api",
19778 "Test verifies that fragment data locations API works as expected")
19779 , m_goku(context)
19780 , m_gohan(context)
19781 , m_goten(context)
19782 , m_chichi(context)
19783 , m_goku_location(0)
19784 , m_gohan_location(0)
19785 , m_chichi_location(0)
19786 {
19787 }
19788
19789 /** Verifies contents of drawn images
19790 *
19791 * @param ignored
19792 * @param ignored
19793 *
19794 * @return true if images are filled with expected values, false otherwise
19795 **/
19796 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture & /* color_0 */)
19797 {
19798 static const GLuint size = m_width * m_height;
19799 static const GLuint expected_goku = 0xff000000;
19800 static const GLuint expected_gohan = 0xff0000ff;
19801 static const GLuint expected_goten = 0xff00ff00;
19802 static const GLuint expected_chichi = 0xffff0000;
19803
19804 std::vector<GLuint> data;
19805 data.resize(size);
19806
19807 m_goku.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19808
19809 for (GLuint i = 0; i < size; ++i)
19810 {
19811 const GLuint color = data[i];
19812
19813 if (expected_goku != color)
19814 {
19815 m_context.getTestContext().getLog()
19816 << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color << tcu::TestLog::EndMessage;
19817 return false;
19818 }
19819 }
19820
19821 m_gohan.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19822
19823 for (GLuint i = 0; i < size; ++i)
19824 {
19825 const GLuint color = data[i];
19826
19827 if (expected_gohan != color)
19828 {
19829 m_context.getTestContext().getLog()
19830 << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color << tcu::TestLog::EndMessage;
19831 return false;
19832 }
19833 }
19834
19835 m_goten.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19836
19837 for (GLuint i = 0; i < size; ++i)
19838 {
19839 const GLuint color = data[i];
19840
19841 if (expected_goten != color)
19842 {
19843 m_context.getTestContext().getLog()
19844 << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color << tcu::TestLog::EndMessage;
19845 return false;
19846 }
19847 }
19848
19849 m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19850
19851 for (GLuint i = 0; i < size; ++i)
19852 {
19853 const GLuint color = data[i];
19854
19855 if (expected_chichi != color)
19856 {
19857 m_context.getTestContext().getLog()
19858 << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color << tcu::TestLog::EndMessage;
19859 return false;
19860 }
19861 }
19862
19863 return true;
19864 }
19865
19866 /** Prepare code snippet that will set out variables
19867 *
19868 * @param ignored
19869 * @param ignored
19870 * @param stage Shader stage
19871 *
19872 * @return Code that pass in variables to next stage
19873 **/
19874 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */,
19875 Utils::VaryingPassthrough & /* varying_passthrough */,
19876 Utils::Shader::STAGES stage)
19877 {
19878 std::string result;
19879
19880 /* Skip for compute shader */
19881 if (Utils::Shader::FRAGMENT != stage)
19882 {
19883 result = "";
19884 }
19885 else
19886 {
19887 result = "chichi = vec4(0, 0, 1, 1);\n"
19888 " goku = vec4(0, 0, 0, 1);\n"
19889 " goten = vec4(0, 1, 0, 1);\n"
19890 " gohan = vec4(1, 0, 0, 1);\n";
19891 }
19892
19893 return result;
19894 }
19895
19896 /** Get interface of program
19897 *
19898 * @param ignored
19899 * @param program_interface Interface of program
19900 * @param ignored
19901 **/
19902 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19903 Utils::ProgramInterface &program_interface,
19904 Utils::VaryingPassthrough & /* varying_passthrough */)
19905 {
19906 Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19907 const Utils::Type &type = Utils::Type::vec4;
19908
19909 /* Locations */
19910 m_goku_location = 2;
19911
19912 /* Globals */
19913 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19914
19915 /* Attributes */
19916 si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19917 m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19918 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)0 /* data */, 0u /* data_size */);
19919
19920 si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19921 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19922 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)0 /* data */, 0u /* data_size */);
19923
19924 si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19925 m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19926 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)0 /* data */, 0u /* data_size */);
19927
19928 si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19929 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19930 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)0 /* data */, 0u /* data_size */);
19931 }
19932
19933 /** Selects if "compute" stage is relevant for test
19934 *
19935 * @param ignored
19936 *
19937 * @return false
19938 **/
19939 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19940 {
19941 return false;
19942 }
19943
19944 /** Get locations for all outputs with automatic_location
19945 *
19946 * @param program Program object
19947 * @param program_interface Interface of program
19948 **/
19949 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program &program,
19950 Utils::ProgramInterface &program_interface)
19951 {
19952 /* Bind location of goten */
19953 const Functions &gl = m_context.getRenderContext().getFunctions();
19954
19955 gl.bindFragDataLocation(program.m_id, m_goten_location, "goten");
19956 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation");
19957
19958 program.Link(gl, program.m_id);
19959
19960 /* Prepare locations for gohan and chichi */
19961 TextureTestBase::prepareFragmentDataLoc(program, program_interface);
19962
19963 /* Get all locations */
19964 Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19965
19966 Utils::Variable::PtrVector &outputs = si.m_outputs;
19967
19968 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
19969 {
19970 const Utils::Variable::Descriptor &desc = (*it)->m_descriptor;
19971
19972 if (0 == desc.m_name.compare("gohan"))
19973 {
19974 m_gohan_location = desc.m_expected_location;
19975 }
19976 else if (0 == desc.m_name.compare("chichi"))
19977 {
19978 m_chichi_location = desc.m_expected_location;
19979 }
19980
19981 /* Locations of goku and goten are fixed */
19982 }
19983 }
19984
19985 /** Prepare framebuffer with single texture as color attachment
19986 *
19987 * @param framebuffer Framebuffer
19988 * @param color_0_texture Texture that will used as color attachment
19989 **/
19990 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer &framebuffer, Utils::Texture &color_0_texture)
19991 {
19992 /* Let parent prepare its stuff */
19993 TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture);
19994
19995 /* Prepare data */
19996 std::vector<GLuint> texture_data;
19997 texture_data.resize(m_width * m_height);
19998
19999 for (GLuint i = 0; i < texture_data.size(); ++i)
20000 {
20001 texture_data[i] = 0x20406080;
20002 }
20003
20004 /* Prepare textures */
20005 m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20006
20007 m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20008
20009 m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20010
20011 m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20012
20013 /* Attach textures to framebuffer */
20014 framebuffer.Bind();
20015 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height);
20016 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height);
20017 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height);
20018 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height);
20019
20020 /* Set up drawbuffers */
20021 const Functions &gl = m_context.getRenderContext().getFunctions();
20022 // The fragment shader can have more than 4 color outputs, but it only care about 4 (goku, gohan, goten, chichi).
20023 // We will first initialize all draw buffers to NONE and then set the real value for the 4 outputs we care about
20024 GLint maxDrawBuffers = 0;
20025 gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
20026
20027 std::vector<GLenum> buffers(maxDrawBuffers, GL_NONE);
20028 buffers[m_chichi_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location);
20029 buffers[m_goten_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location);
20030 buffers[m_goku_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location);
20031 buffers[m_gohan_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location);
20032
20033 gl.drawBuffers(maxDrawBuffers, buffers.data());
20034 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
20035 }
20036
20037 /** Constructor
20038 *
20039 * @param context Test framework context
20040 **/
20041 XFBInputTest::XFBInputTest(deqp::Context &context)
20042 : NegativeTestBase(context, "xfb_input",
20043 "Test verifies that compiler reports error when xfb qualifiers are used with input")
20044 {
20045 }
20046
20047 /** Source for given test case and stage
20048 *
20049 * @param test_case_index Index of test case
20050 * @param stage Shader stage
20051 *
20052 * @return Shader source
20053 **/
20054 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20055 {
20056 #if DEBUG_NEG_REMOVE_ERROR
20057 static const GLchar *buffer_var_definition = "/* layout (xfb_buffer = 2) */ in vec4 gohanARRAY;\n";
20058 static const GLchar *offset_var_definition = "/* layout (xfb_offset = 16) */ in vec4 gohanARRAY;\n";
20059 static const GLchar *stride_var_definition = "/* layout (xfb_stride = 32) */ in vec4 gohanARRAY;\n";
20060 #else
20061 static const GLchar *buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n";
20062 static const GLchar *offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n";
20063 static const GLchar *stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n";
20064 #endif /* DEBUG_NEG_REMOVE_ERROR */
20065 static const GLchar *fs = "#version 430 core\n"
20066 "#extension GL_ARB_enhanced_layouts : require\n"
20067 "\n"
20068 "in vec4 gs_fs;\n"
20069 "out vec4 fs_out;\n"
20070 "\n"
20071 "void main()\n"
20072 "{\n"
20073 " fs_out = gs_fs;\n"
20074 "}\n"
20075 "\n";
20076 static const GLchar *fs_tested = "#version 430 core\n"
20077 "#extension GL_ARB_enhanced_layouts : require\n"
20078 "\n"
20079 "VAR_DEFINITION"
20080 "\n"
20081 "in vec4 gs_fs;\n"
20082 "out vec4 fs_out;\n"
20083 "\n"
20084 "void main()\n"
20085 "{\n"
20086 " vec4 result = gs_fs;\n"
20087 "\n"
20088 " fs_out = result;\n"
20089 "}\n"
20090 "\n";
20091 static const GLchar *gs = "#version 430 core\n"
20092 "#extension GL_ARB_enhanced_layouts : require\n"
20093 "\n"
20094 "layout(points) in;\n"
20095 "layout(triangle_strip, max_vertices = 4) out;\n"
20096 "\n"
20097 "in vec4 tes_gs[];\n"
20098 "out vec4 gs_fs;\n"
20099 "\n"
20100 "void main()\n"
20101 "{\n"
20102 " gs_fs = tes_gs[0];\n"
20103 " gl_Position = vec4(-1, -1, 0, 1);\n"
20104 " EmitVertex();\n"
20105 " gs_fs = tes_gs[0];\n"
20106 " gl_Position = vec4(-1, 1, 0, 1);\n"
20107 " EmitVertex();\n"
20108 " gs_fs = tes_gs[0];\n"
20109 " gl_Position = vec4(1, -1, 0, 1);\n"
20110 " EmitVertex();\n"
20111 " gs_fs = tes_gs[0];\n"
20112 " gl_Position = vec4(1, 1, 0, 1);\n"
20113 " EmitVertex();\n"
20114 "}\n"
20115 "\n";
20116 static const GLchar *gs_tested = "#version 430 core\n"
20117 "#extension GL_ARB_enhanced_layouts : require\n"
20118 "\n"
20119 "layout(points) in;\n"
20120 "layout(triangle_strip, max_vertices = 4) out;\n"
20121 "\n"
20122 "VAR_DEFINITION"
20123 "\n"
20124 "in vec4 tes_gs[];\n"
20125 "out vec4 gs_fs;\n"
20126 "\n"
20127 "void main()\n"
20128 "{\n"
20129 " vec4 result = tes_gs[0];\n"
20130 "\n"
20131 " gs_fs = result;\n"
20132 " gl_Position = vec4(-1, -1, 0, 1);\n"
20133 " EmitVertex();\n"
20134 " gs_fs = result;\n"
20135 " gl_Position = vec4(-1, 1, 0, 1);\n"
20136 " EmitVertex();\n"
20137 " gs_fs = result;\n"
20138 " gl_Position = vec4(1, -1, 0, 1);\n"
20139 " EmitVertex();\n"
20140 " gs_fs = result;\n"
20141 " gl_Position = vec4(1, 1, 0, 1);\n"
20142 " EmitVertex();\n"
20143 "}\n"
20144 "\n";
20145 static const GLchar *tcs = "#version 430 core\n"
20146 "#extension GL_ARB_enhanced_layouts : require\n"
20147 "\n"
20148 "layout(vertices = 1) out;\n"
20149 "\n"
20150 "in vec4 vs_tcs[];\n"
20151 "out vec4 tcs_tes[];\n"
20152 "\n"
20153 "void main()\n"
20154 "{\n"
20155 "\n"
20156 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
20157 "\n"
20158 " gl_TessLevelOuter[0] = 1.0;\n"
20159 " gl_TessLevelOuter[1] = 1.0;\n"
20160 " gl_TessLevelOuter[2] = 1.0;\n"
20161 " gl_TessLevelOuter[3] = 1.0;\n"
20162 " gl_TessLevelInner[0] = 1.0;\n"
20163 " gl_TessLevelInner[1] = 1.0;\n"
20164 "}\n"
20165 "\n";
20166 static const GLchar *tcs_tested = "#version 430 core\n"
20167 "#extension GL_ARB_enhanced_layouts : require\n"
20168 "\n"
20169 "layout(vertices = 1) out;\n"
20170 "\n"
20171 "VAR_DEFINITION"
20172 "\n"
20173 "in vec4 vs_tcs[];\n"
20174 "out vec4 tcs_tes[];\n"
20175 "\n"
20176 "void main()\n"
20177 "{\n"
20178 " vec4 result = vs_tcs[gl_InvocationID];\n"
20179 "\n"
20180 " tcs_tes[gl_InvocationID] = result;\n"
20181 "\n"
20182 " gl_TessLevelOuter[0] = 1.0;\n"
20183 " gl_TessLevelOuter[1] = 1.0;\n"
20184 " gl_TessLevelOuter[2] = 1.0;\n"
20185 " gl_TessLevelOuter[3] = 1.0;\n"
20186 " gl_TessLevelInner[0] = 1.0;\n"
20187 " gl_TessLevelInner[1] = 1.0;\n"
20188 "}\n"
20189 "\n";
20190 static const GLchar *tes = "#version 430 core\n"
20191 "#extension GL_ARB_enhanced_layouts : require\n"
20192 "\n"
20193 "layout(isolines, point_mode) in;\n"
20194 "\n"
20195 "in vec4 tcs_tes[];\n"
20196 "out vec4 tes_gs;\n"
20197 "\n"
20198 "void main()\n"
20199 "{\n"
20200 " tes_gs = tcs_tes[0];\n"
20201 "}\n"
20202 "\n";
20203 static const GLchar *tes_tested = "#version 430 core\n"
20204 "#extension GL_ARB_enhanced_layouts : require\n"
20205 "\n"
20206 "layout(isolines, point_mode) in;\n"
20207 "\n"
20208 "VAR_DEFINITION"
20209 "\n"
20210 "in vec4 tcs_tes[];\n"
20211 "out vec4 tes_gs;\n"
20212 "\n"
20213 "void main()\n"
20214 "{\n"
20215 " vec4 result = tcs_tes[0];\n"
20216 "\n"
20217 " tes_gs += result;\n"
20218 "}\n"
20219 "\n";
20220 static const GLchar *vs = "#version 430 core\n"
20221 "#extension GL_ARB_enhanced_layouts : require\n"
20222 "\n"
20223 "in vec4 in_vs;\n"
20224 "out vec4 vs_tcs;\n"
20225 "\n"
20226 "void main()\n"
20227 "{\n"
20228 " vs_tcs = in_vs;\n"
20229 "}\n"
20230 "\n";
20231 static const GLchar *vs_tested = "#version 430 core\n"
20232 "#extension GL_ARB_enhanced_layouts : require\n"
20233 "\n"
20234 "VAR_DEFINITION"
20235 "\n"
20236 "in vec4 in_vs;\n"
20237 "out vec4 vs_tcs;\n"
20238 "\n"
20239 "void main()\n"
20240 "{\n"
20241 " vec4 result = in_vs;\n"
20242 "\n"
20243 " vs_tcs += result;\n"
20244 "}\n"
20245 "\n";
20246
20247 std::string source;
20248 testCase &test_case = m_test_cases[test_case_index];
20249
20250 if (test_case.m_stage == stage)
20251 {
20252 const GLchar *array = "";
20253 size_t position = 0;
20254 const GLchar *var_definition = 0;
20255
20256 switch (test_case.m_qualifier)
20257 {
20258 case BUFFER:
20259 var_definition = buffer_var_definition;
20260 break;
20261 case OFFSET:
20262 var_definition = offset_var_definition;
20263 break;
20264 case STRIDE:
20265 var_definition = stride_var_definition;
20266 break;
20267 default:
20268 TCU_FAIL("Invalid enum");
20269 }
20270
20271 switch (stage)
20272 {
20273 case Utils::Shader::FRAGMENT:
20274 source = fs_tested;
20275 break;
20276 case Utils::Shader::GEOMETRY:
20277 source = gs_tested;
20278 array = "[]";
20279 break;
20280 case Utils::Shader::TESS_CTRL:
20281 source = tcs_tested;
20282 array = "[]";
20283 break;
20284 case Utils::Shader::TESS_EVAL:
20285 source = tes_tested;
20286 array = "[]";
20287 break;
20288 case Utils::Shader::VERTEX:
20289 source = vs_tested;
20290 break;
20291 default:
20292 TCU_FAIL("Invalid enum");
20293 }
20294
20295 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
20296 position = 0;
20297 Utils::replaceToken("ARRAY", position, array, source);
20298 }
20299 else
20300 {
20301 switch (stage)
20302 {
20303 case Utils::Shader::FRAGMENT:
20304 source = fs;
20305 break;
20306 case Utils::Shader::GEOMETRY:
20307 source = gs;
20308 break;
20309 case Utils::Shader::TESS_CTRL:
20310 source = tcs;
20311 break;
20312 case Utils::Shader::TESS_EVAL:
20313 source = tes;
20314 break;
20315 case Utils::Shader::VERTEX:
20316 source = vs;
20317 break;
20318 default:
20319 TCU_FAIL("Invalid enum");
20320 }
20321 }
20322
20323 return source;
20324 }
20325
20326 /** Get description of test case
20327 *
20328 * @param test_case_index Index of test case
20329 *
20330 * @return Test case description
20331 **/
20332 std::string XFBInputTest::getTestCaseName(GLuint test_case_index)
20333 {
20334 std::stringstream stream;
20335 testCase &test_case = m_test_cases[test_case_index];
20336
20337 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: ";
20338
20339 switch (test_case.m_qualifier)
20340 {
20341 case BUFFER:
20342 stream << "xfb_buffer";
20343 break;
20344 case OFFSET:
20345 stream << "xfb_offset";
20346 break;
20347 case STRIDE:
20348 stream << "xfb_stride";
20349 break;
20350 default:
20351 TCU_FAIL("Invalid enum");
20352 }
20353
20354 return stream.str();
20355 }
20356
20357 /** Get number of test cases
20358 *
20359 * @return Number of test cases
20360 **/
20361 GLuint XFBInputTest::getTestCaseNumber()
20362 {
20363 return static_cast<GLuint>(m_test_cases.size());
20364 }
20365
20366 /** Selects if "compute" stage is relevant for test
20367 *
20368 * @param ignored
20369 *
20370 * @return false
20371 **/
20372 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */)
20373 {
20374 return false;
20375 }
20376
20377 /** Prepare all test cases
20378 *
20379 **/
20380 void XFBInputTest::testInit()
20381 {
20382 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
20383 {
20384 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
20385 {
20386 if (Utils::Shader::COMPUTE == stage)
20387 {
20388 continue;
20389 }
20390
20391 testCase test_case = {(QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage};
20392
20393 m_test_cases.push_back(test_case);
20394 }
20395 }
20396 }
20397
20398 /* Constants used by XFBAllStagesTest */
20399 const GLuint XFBAllStagesTest::m_gs_index = 3;
20400
20401 /** Constructor
20402 *
20403 * @param context Test context
20404 **/
20405 XFBAllStagesTest::XFBAllStagesTest(deqp::Context &context)
20406 : BufferTestBase(context, "xfb_all_stages",
20407 "Test verifies that only last stage in vertex processing can output to transform feedback")
20408 {
20409 /* Nothing to be done here */
20410 }
20411
20412 /** Get descriptors of buffers necessary for test
20413 *
20414 * @param ignored
20415 * @param out_descriptors Descriptors of buffers used by test
20416 **/
20417 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
20418 bufferDescriptor::Vector &out_descriptors)
20419 {
20420 static const GLuint n_stages = 4;
20421 const Utils::Type &vec4 = Utils::Type::vec4;
20422
20423 /* Data */
20424 tcu::Vec4 sum;
20425
20426 /* Test uses single uniform and xfb per stage + uniform for fragment shader */
20427 out_descriptors.resize(n_stages * 2 + 1);
20428
20429 /* */
20430 for (GLuint i = 0; i < n_stages; ++i)
20431 {
20432 /* Get references */
20433 bufferDescriptor &uniform = out_descriptors[i + 0];
20434 bufferDescriptor &xfb = out_descriptors[i + n_stages];
20435
20436 /* Index */
20437 uniform.m_index = i;
20438 xfb.m_index = i;
20439
20440 /* Target */
20441 uniform.m_target = Utils::Buffer::Uniform;
20442 xfb.m_target = Utils::Buffer::Transform_feedback;
20443
20444 /* Data */
20445 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
20446
20447 sum += var;
20448
20449 uniform.m_initial_data.resize(vec4.GetSize());
20450 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
20451
20452 xfb.m_initial_data = vec4.GenerateDataPacked();
20453
20454 if (m_gs_index != i)
20455 {
20456 xfb.m_expected_data = xfb.m_initial_data;
20457 }
20458 else
20459 {
20460 xfb.m_expected_data.resize(vec4.GetSize());
20461 memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize());
20462 }
20463 }
20464
20465 /* FS */
20466 {
20467 /* Get reference */
20468 bufferDescriptor &uniform = out_descriptors[n_stages * 2];
20469
20470 /* Index */
20471 uniform.m_index = n_stages;
20472
20473 /* Target */
20474 uniform.m_target = Utils::Buffer::Uniform;
20475
20476 /* Data */
20477 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
20478
20479 uniform.m_initial_data.resize(vec4.GetSize());
20480 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
20481 }
20482 }
20483
20484 /** Get body of main function for given shader stage
20485 *
20486 * @param ignored
20487 * @param stage Shader stage
20488 * @param out_assignments Set to empty
20489 * @param out_calculations Set to empty
20490 **/
20491 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20492 std::string &out_assignments, std::string &out_calculations)
20493 {
20494 out_calculations = "";
20495
20496 static const GLchar *vs = " vs_tcs = uni_vs;\n";
20497 static const GLchar *tcs = " tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n";
20498 static const GLchar *tes = " tes_gs = uni_tes + tcs_tes[0];\n";
20499 static const GLchar *gs = " gs_fs = uni_gs + tes_gs[0];\n";
20500 static const GLchar *fs = " fs_out = uni_fs + gs_fs;\n";
20501
20502 const GLchar *assignments = 0;
20503 switch (stage)
20504 {
20505 case Utils::Shader::FRAGMENT:
20506 assignments = fs;
20507 break;
20508 case Utils::Shader::GEOMETRY:
20509 assignments = gs;
20510 break;
20511 case Utils::Shader::TESS_CTRL:
20512 assignments = tcs;
20513 break;
20514 case Utils::Shader::TESS_EVAL:
20515 assignments = tes;
20516 break;
20517 case Utils::Shader::VERTEX:
20518 assignments = vs;
20519 break;
20520 default:
20521 TCU_FAIL("Invalid enum");
20522 }
20523
20524 out_assignments = assignments;
20525 }
20526
20527 /** Get interface of shader
20528 *
20529 * @param ignored
20530 * @param stage Shader stage
20531 * @param out_interface Set to ""
20532 **/
20533 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20534 std::string &out_interface)
20535 {
20536 static const GLchar *vs = "layout(xfb_buffer = 0, xfb_offset = 0) out vec4 vs_tcs;\n"
20537 "layout(binding = 0) uniform vs_block {\n"
20538 " vec4 uni_vs;\n"
20539 "};\n";
20540 static const GLchar *tcs = " in vec4 vs_tcs[];\n"
20541 "layout(xfb_buffer = 1, xfb_offset = 0) out vec4 tcs_tes[1];\n"
20542 "layout(binding = 1) uniform tcs_block {\n"
20543 " vec4 uni_tcs;\n"
20544 "};\n";
20545 static const GLchar *tes = " in vec4 tcs_tes[];\n"
20546 "layout(xfb_buffer = 2, xfb_offset = 0) out vec4 tes_gs;\n"
20547 "layout(binding = 2) uniform tes_block {\n"
20548 " vec4 uni_tes;\n"
20549 "};\n";
20550 static const GLchar *gs = " in vec4 tes_gs[];\n"
20551 "layout(xfb_buffer = 3, xfb_offset = 0) out vec4 gs_fs;\n"
20552 "layout(binding = 3) uniform gs_block {\n"
20553 " vec4 uni_gs;\n"
20554 "};\n";
20555 static const GLchar *fs = " in vec4 gs_fs;\n"
20556 " out vec4 fs_out;\n"
20557 "layout(binding = 4) uniform fs_block {\n"
20558 " vec4 uni_fs;\n"
20559 "};\n";
20560
20561 const GLchar *interface = 0;
20562 switch (stage)
20563 {
20564 case Utils::Shader::FRAGMENT:
20565 interface = fs;
20566 break;
20567 case Utils::Shader::GEOMETRY:
20568 interface = gs;
20569 break;
20570 case Utils::Shader::TESS_CTRL:
20571 interface = tcs;
20572 break;
20573 case Utils::Shader::TESS_EVAL:
20574 interface = tes;
20575 break;
20576 case Utils::Shader::VERTEX:
20577 interface = vs;
20578 break;
20579 default:
20580 TCU_FAIL("Invalid enum");
20581 }
20582
20583 out_interface = interface;
20584 }
20585
20586 /* Constants used by XFBStrideOfEmptyListTest */
20587 const GLuint XFBStrideOfEmptyListTest::m_stride = 64;
20588
20589 /** Constructor
20590 *
20591 * @param context Test context
20592 **/
20593 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context &context)
20594 : BufferTestBase(
20595 context, "xfb_stride_of_empty_list",
20596 "Test verifies correct behavior when xfb_stride qualifier is specified but no xfb_offset is specified")
20597 {
20598 /* Nothing to be done here */
20599 }
20600
20601 /** Execute drawArrays for single vertex
20602 *
20603 * @param test_case_index Index of test case
20604 *
20605 * @return true if proper error is reported
20606 **/
20607 bool XFBStrideOfEmptyListTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20608 {
20609 const Functions &gl = m_context.getRenderContext().getFunctions();
20610 bool result = true;
20611
20612 /* Draw */
20613 gl.disable(GL_RASTERIZER_DISCARD);
20614 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20615
20616 gl.beginTransformFeedback(GL_POINTS);
20617 GLenum error = gl.getError();
20618 switch (test_case_index)
20619 {
20620 case VALID:
20621 if (GL_NO_ERROR != error)
20622 {
20623 gl.endTransformFeedback();
20624 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20625 }
20626
20627 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20628 error = gl.getError();
20629
20630 gl.endTransformFeedback();
20631 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20632 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20633
20634 break;
20635
20636 case FIRST_MISSING:
20637 if (GL_NO_ERROR == error)
20638 {
20639 gl.endTransformFeedback();
20640 }
20641
20642 if (GL_INVALID_OPERATION != error)
20643 {
20644 m_context.getTestContext().getLog()
20645 << tcu::TestLog::Message
20646 << "XFB at index 0, that is written by GS, is missing. It was expected that "
20647 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20648 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20649
20650 result = false;
20651 }
20652
20653 break;
20654
20655 case SECOND_MISSING:
20656 if (GL_NO_ERROR != error)
20657 {
20658 gl.endTransformFeedback();
20659 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20660 }
20661
20662 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20663 error = gl.getError();
20664
20665 gl.endTransformFeedback();
20666 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20667 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20668
20669 break;
20670 }
20671
20672 /* Done */
20673 return result;
20674 }
20675
20676 /** Get descriptors of buffers necessary for test
20677 *
20678 * @param test_case_index Index of test case
20679 * @param out_descriptors Descriptors of buffers used by test
20680 **/
20681 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint test_case_index,
20682 bufferDescriptor::Vector &out_descriptors)
20683 {
20684 switch (test_case_index)
20685 {
20686 case VALID:
20687 {
20688 /* Test needs single uniform and two xfbs */
20689 out_descriptors.resize(3);
20690
20691 /* Get references */
20692 bufferDescriptor &uniform = out_descriptors[0];
20693 bufferDescriptor &xfb_0 = out_descriptors[1];
20694 bufferDescriptor &xfb_1 = out_descriptors[2];
20695
20696 /* Index */
20697 uniform.m_index = 0;
20698 xfb_0.m_index = 0;
20699 xfb_1.m_index = 1;
20700
20701 /* Target */
20702 uniform.m_target = Utils::Buffer::Uniform;
20703 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20704 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20705
20706 /* Data */
20707 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20708
20709 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20710 xfb_0.m_expected_data = uniform.m_initial_data;
20711
20712 /* Data, contents are the same as no modification is expected */
20713 xfb_1.m_initial_data.resize(m_stride);
20714 xfb_1.m_expected_data.resize(m_stride);
20715
20716 for (GLuint i = 0; i < m_stride; ++i)
20717 {
20718 xfb_1.m_initial_data[0] = (glw::GLubyte)i;
20719 xfb_1.m_expected_data[0] = (glw::GLubyte)i;
20720 }
20721 }
20722
20723 break;
20724
20725 case FIRST_MISSING:
20726 {
20727 /* Test needs single uniform and two xfbs */
20728 out_descriptors.resize(2);
20729
20730 /* Get references */
20731 bufferDescriptor &uniform = out_descriptors[0];
20732 bufferDescriptor &xfb_1 = out_descriptors[1];
20733
20734 /* Index */
20735 uniform.m_index = 0;
20736 xfb_1.m_index = 1;
20737
20738 /* Target */
20739 uniform.m_target = Utils::Buffer::Uniform;
20740 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20741
20742 /* Data */
20743 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20744
20745 /* Draw call will not be executed, contents does not matter */
20746 xfb_1.m_initial_data.resize(m_stride);
20747 }
20748
20749 break;
20750
20751 case SECOND_MISSING:
20752 {
20753 /* Test needs single uniform and two xfbs */
20754 out_descriptors.resize(2);
20755
20756 /* Get references */
20757 bufferDescriptor &uniform = out_descriptors[0];
20758 bufferDescriptor &xfb_0 = out_descriptors[1];
20759
20760 /* Index */
20761 uniform.m_index = 0;
20762 xfb_0.m_index = 0;
20763
20764 /* Target */
20765 uniform.m_target = Utils::Buffer::Uniform;
20766 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20767
20768 /* Data */
20769 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20770
20771 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20772 xfb_0.m_expected_data = uniform.m_initial_data;
20773 }
20774
20775 break;
20776 }
20777 }
20778
20779 /** Get body of main function for given shader stage
20780 *
20781 * @param ignored
20782 * @param stage Shader stage
20783 * @param out_assignments Set to empty
20784 * @param out_calculations Set to empty
20785 **/
20786 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20787 std::string &out_assignments, std::string &out_calculations)
20788 {
20789 out_calculations = "";
20790
20791 static const GLchar *gs = " gs_fs = uni_gs;\n";
20792 static const GLchar *fs = " fs_out = vec4(gs_fs);\n";
20793
20794 const GLchar *assignments = "";
20795 switch (stage)
20796 {
20797 case Utils::Shader::FRAGMENT:
20798 assignments = fs;
20799 break;
20800 case Utils::Shader::GEOMETRY:
20801 assignments = gs;
20802 break;
20803 default:
20804 break;
20805 }
20806
20807 out_assignments = assignments;
20808 }
20809
20810 /** Get interface of shader
20811 *
20812 * @param ignored
20813 * @param stage Shader stage
20814 * @param out_interface Set to ""
20815 **/
20816 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20817 std::string &out_interface)
20818 {
20819 static const GLchar *gs = "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 gs_fs;\n"
20820 "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
20821 "\n"
20822 "layout (binding = 0) uniform gs_block {\n"
20823 " vec4 uni_gs;\n"
20824 "};\n";
20825 static const GLchar *fs = "in vec4 gs_fs;\n"
20826 "out vec4 fs_out;\n";
20827
20828 switch (stage)
20829 {
20830 case Utils::Shader::FRAGMENT:
20831 out_interface = fs;
20832 break;
20833 case Utils::Shader::GEOMETRY:
20834 out_interface = gs;
20835 break;
20836 default:
20837 out_interface = "";
20838 return;
20839 }
20840 }
20841
20842 /** Returns buffer details in human readable form.
20843 *
20844 * @param test_case_index Index of test case
20845 *
20846 * @return Case description
20847 **/
20848 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index)
20849 {
20850 std::string result;
20851
20852 switch (test_case_index)
20853 {
20854 case VALID:
20855 result = "Valid case";
20856 break;
20857 case FIRST_MISSING:
20858 result = "Missing xfb at index 0";
20859 break;
20860 case SECOND_MISSING:
20861 result = "Missing xfb at index 1";
20862 break;
20863 default:
20864 TCU_FAIL("Invalid enum");
20865 }
20866
20867 return result;
20868 }
20869
20870 /** Get number of test cases
20871 *
20872 * @return 3
20873 **/
20874 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber()
20875 {
20876 return 3;
20877 }
20878
20879 /* Constants used by XFBStrideOfEmptyListTest */
20880 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64;
20881
20882 /** Constructor
20883 *
20884 * @param context Test context
20885 **/
20886 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context &context)
20887 : BufferTestBase(context, "xfb_stride_of_empty_list_and_api",
20888 "Test verifies that xfb_stride qualifier is not overriden by API")
20889 {
20890 /* Nothing to be done here */
20891 }
20892
20893 /** Execute drawArrays for single vertex
20894 *
20895 * @param test_case_index Index of test case
20896 *
20897 * @return true if proper error is reported
20898 **/
20899 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20900 {
20901 const Functions &gl = m_context.getRenderContext().getFunctions();
20902 bool result = true;
20903
20904 /* Draw */
20905 gl.disable(GL_RASTERIZER_DISCARD);
20906 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20907
20908 gl.beginTransformFeedback(GL_POINTS);
20909 GLenum error = gl.getError();
20910 switch (test_case_index)
20911 {
20912 case VALID:
20913 if (GL_NO_ERROR != error)
20914 {
20915 gl.endTransformFeedback();
20916 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20917 }
20918
20919 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20920 error = gl.getError();
20921
20922 gl.endTransformFeedback();
20923 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20924 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20925
20926 break;
20927
20928 case FIRST_MISSING:
20929 if (GL_NO_ERROR != error)
20930 {
20931 gl.endTransformFeedback();
20932 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20933 }
20934
20935 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20936 error = gl.getError();
20937
20938 gl.endTransformFeedback();
20939 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20940 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20941
20942 break;
20943
20944 case SECOND_MISSING:
20945 if (GL_NO_ERROR == error)
20946 {
20947 gl.endTransformFeedback();
20948 }
20949
20950 if (GL_INVALID_OPERATION != error)
20951 {
20952 m_context.getTestContext().getLog()
20953 << tcu::TestLog::Message
20954 << "XFB at index 1, that is declared as empty, is missing. It was expected "
20955 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20956 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20957
20958 result = false;
20959 }
20960
20961 break;
20962 }
20963
20964 /* Done */
20965 return result;
20966 }
20967
20968 /** Get descriptors of buffers necessary for test
20969 *
20970 * @param test_case_index Index of test case
20971 * @param out_descriptors Descriptors of buffers used by test
20972 **/
20973 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint test_case_index,
20974 bufferDescriptor::Vector &out_descriptors)
20975 {
20976 switch (test_case_index)
20977 {
20978 case VALID:
20979 {
20980 /* Test needs single uniform and two xfbs */
20981 out_descriptors.resize(3);
20982
20983 /* Get references */
20984 bufferDescriptor &uniform = out_descriptors[0];
20985 bufferDescriptor &xfb_0 = out_descriptors[1];
20986 bufferDescriptor &xfb_1 = out_descriptors[2];
20987
20988 /* Index */
20989 uniform.m_index = 0;
20990 xfb_0.m_index = 0;
20991 xfb_1.m_index = 1;
20992
20993 /* Target */
20994 uniform.m_target = Utils::Buffer::Uniform;
20995 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20996 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20997
20998 /* Data */
20999 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21000
21001 /* Data, contents are the same as no modification is expected */
21002 xfb_0.m_initial_data.resize(m_stride);
21003 xfb_0.m_expected_data.resize(m_stride);
21004
21005 for (GLuint i = 0; i < m_stride; ++i)
21006 {
21007 xfb_0.m_initial_data[0] = (glw::GLubyte)i;
21008 xfb_0.m_expected_data[0] = (glw::GLubyte)i;
21009 }
21010
21011 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21012 xfb_1.m_expected_data = uniform.m_initial_data;
21013 }
21014
21015 break;
21016
21017 case FIRST_MISSING:
21018 {
21019 /* Test needs single uniform and two xfbs */
21020 out_descriptors.resize(2);
21021
21022 /* Get references */
21023 bufferDescriptor &uniform = out_descriptors[0];
21024 bufferDescriptor &xfb_1 = out_descriptors[1];
21025
21026 /* Index */
21027 uniform.m_index = 0;
21028 xfb_1.m_index = 1;
21029
21030 /* Target */
21031 uniform.m_target = Utils::Buffer::Uniform;
21032 xfb_1.m_target = Utils::Buffer::Transform_feedback;
21033
21034 /* Data */
21035 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21036
21037 /* Data, contents are the same as no modification is expected */
21038 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21039 xfb_1.m_expected_data = uniform.m_initial_data;
21040 }
21041
21042 break;
21043
21044 case SECOND_MISSING:
21045 {
21046 /* Test needs single uniform and two xfbs */
21047 out_descriptors.resize(2);
21048
21049 /* Get references */
21050 bufferDescriptor &uniform = out_descriptors[0];
21051 bufferDescriptor &xfb_0 = out_descriptors[1];
21052
21053 /* Index */
21054 uniform.m_index = 0;
21055 xfb_0.m_index = 0;
21056
21057 /* Target */
21058 uniform.m_target = Utils::Buffer::Uniform;
21059 xfb_0.m_target = Utils::Buffer::Transform_feedback;
21060
21061 /* Data */
21062 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21063
21064 /* Draw call will not be executed, contents does not matter */
21065 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21066 }
21067
21068 break;
21069 }
21070 }
21071
21072 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
21073 *
21074 * @param ignored
21075 * @param captured_varyings Vector of varying names to be captured
21076 **/
21077 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
21078 Utils::Program::NameVector &captured_varyings,
21079 GLint *xfb_components)
21080 {
21081 captured_varyings.push_back("gs_fs1");
21082 captured_varyings.push_back("gs_fs2");
21083 *xfb_components = 4;
21084 }
21085
21086 /** Get body of main function for given shader stage
21087 *
21088 * @param ignored
21089 * @param stage Shader stage
21090 * @param out_assignments Set to empty
21091 * @param out_calculations Set to empty
21092 **/
21093 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21094 std::string &out_assignments, std::string &out_calculations)
21095 {
21096 out_calculations = "";
21097
21098 static const GLchar *gs = " gs_fs1 = -uni_gs;\n"
21099 " gs_fs2 = uni_gs;\n";
21100 static const GLchar *fs = " fs_out = vec4(gs_fs2);\n";
21101
21102 const GLchar *assignments = "";
21103 switch (stage)
21104 {
21105 case Utils::Shader::FRAGMENT:
21106 assignments = fs;
21107 break;
21108 case Utils::Shader::GEOMETRY:
21109 assignments = gs;
21110 break;
21111 default:
21112 break;
21113 }
21114
21115 out_assignments = assignments;
21116 }
21117
21118 /** Get interface of shader
21119 *
21120 * @param ignored
21121 * @param stage Shader stage
21122 * @param out_interface Set to ""
21123 **/
21124 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21125 std::string &out_interface)
21126 {
21127 static const GLchar *gs = "layout (xfb_buffer = 0, xfb_stride = 64) out vec4 gs_fs1;\n"
21128 "layout (xfb_buffer = 1, xfb_offset = 0) out vec4 gs_fs2;\n"
21129 "\n"
21130 "layout(binding = 0) uniform gs_block {\n"
21131 " vec4 uni_gs;\n"
21132 "};\n";
21133 static const GLchar *fs = "in vec4 gs_fs2;\n"
21134 "out vec4 fs_out;\n";
21135
21136 switch (stage)
21137 {
21138 case Utils::Shader::FRAGMENT:
21139 out_interface = fs;
21140 break;
21141 case Utils::Shader::GEOMETRY:
21142 out_interface = gs;
21143 break;
21144 default:
21145 out_interface = "";
21146 return;
21147 }
21148 }
21149
21150 /** Returns buffer details in human readable form.
21151 *
21152 * @param test_case_index Index of test case
21153 *
21154 * @return Case description
21155 **/
21156 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index)
21157 {
21158 std::string result;
21159
21160 switch (test_case_index)
21161 {
21162 case VALID:
21163 result = "Valid case";
21164 break;
21165 case FIRST_MISSING:
21166 result = "Missing xfb at index 0";
21167 break;
21168 case SECOND_MISSING:
21169 result = "Missing xfb at index 1";
21170 break;
21171 default:
21172 TCU_FAIL("Invalid enum");
21173 }
21174
21175 return result;
21176 }
21177
21178 /** Get number of test cases
21179 *
21180 * @return 2
21181 **/
21182 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber()
21183 {
21184 return 3;
21185 }
21186
21187 /** Constructor
21188 *
21189 * @param context Test framework context
21190 **/
21191 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context &context)
21192 : NegativeTestBase(context, "xfb_too_small_stride",
21193 "Test verifies that compiler reports error when xfb_stride sets not enough space")
21194 {
21195 }
21196
21197 /** Source for given test case and stage
21198 *
21199 * @param test_case_index Index of test case
21200 * @param stage Shader stage
21201 *
21202 * @return Shader source
21203 **/
21204 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21205 {
21206 #if DEBUG_NEG_REMOVE_ERROR
21207 static const GLchar *array_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 32 */ ) out;\n"
21208 #else
21209 static const GLchar *array_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
21210 #endif /* DEBUG_NEG_REMOVE_ERROR */
21211 "\n"
21212 "layout (xfb_offset = 16) out vec4 gohan[4];\n";
21213 #if DEBUG_NEG_REMOVE_ERROR
21214 static const GLchar *block_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 32 */ ) out;\n"
21215 #else
21216 static const GLchar *block_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
21217 #endif /* DEBUG_NEG_REMOVE_ERROR */
21218 "\n"
21219 "layout (xfb_offset = 0) out Goku {\n"
21220 " vec4 gohan;\n"
21221 " vec4 goten;\n"
21222 " vec4 chichi;\n"
21223 "} goku;\n";
21224 #if DEBUG_NEG_REMOVE_ERROR
21225 static const GLchar *offset_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 40 */ ) out;\n"
21226 #else
21227 static const GLchar *offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n"
21228 #endif /* DEBUG_NEG_REMOVE_ERROR */
21229 "\n"
21230 "layout (xfb_offset = 32) out vec4 gohan;\n";
21231 // The test considers gohan overflows the buffer 0, but according to spec, it is valid to declare the variable with qualifier "layout (xfb_offset = 16, xfb_stride = 32) out vec4 gohan;"
21232 // To make the shader failed to compile, change xfb_stride to a value that is smaller than 32
21233 #if DEBUG_NEG_REMOVE_ERROR
21234 static const GLchar *stride_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 28 */ ) out;\n"
21235 "\n"
21236 "layout (xfb_offset = 16 /*, xfb_stride = 28 */ ) out vec4 gohan;\n";
21237 #else
21238 static const GLchar *stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n"
21239 "\n"
21240 "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohan;\n";
21241 #endif /* DEBUG_NEG_REMOVE_ERROR */
21242 static const GLchar *array_use = " gohan[0] = result / 2;\n"
21243 " gohan[1] = result / 4;\n"
21244 " gohan[2] = result / 6;\n"
21245 " gohan[3] = result / 8;\n";
21246 static const GLchar *block_use = " goku.gohan = result / 2;\n"
21247 " goku.goten = result / 4;\n"
21248 " goku.chichi = result / 6;\n";
21249 static const GLchar *output_use = "gohan = result / 4;\n";
21250 static const GLchar *fs = "#version 430 core\n"
21251 "#extension GL_ARB_enhanced_layouts : require\n"
21252 "\n"
21253 "in vec4 any_fs;\n"
21254 "out vec4 fs_out;\n"
21255 "\n"
21256 "void main()\n"
21257 "{\n"
21258 " fs_out = any_fs;\n"
21259 "}\n"
21260 "\n";
21261 static const GLchar *gs_tested = "#version 430 core\n"
21262 "#extension GL_ARB_enhanced_layouts : require\n"
21263 "\n"
21264 "layout(points) in;\n"
21265 "layout(triangle_strip, max_vertices = 4) out;\n"
21266 "\n"
21267 "VAR_DEFINITION"
21268 "\n"
21269 "in vec4 vs_any[];\n"
21270 "out vec4 any_fs;\n"
21271 "\n"
21272 "void main()\n"
21273 "{\n"
21274 " vec4 result = vs_any[0];\n"
21275 "\n"
21276 "VARIABLE_USE"
21277 "\n"
21278 " any_fs = result;\n"
21279 " gl_Position = vec4(-1, -1, 0, 1);\n"
21280 " EmitVertex();\n"
21281 " any_fs = result;\n"
21282 " gl_Position = vec4(-1, 1, 0, 1);\n"
21283 " EmitVertex();\n"
21284 " any_fs = result;\n"
21285 " gl_Position = vec4(1, -1, 0, 1);\n"
21286 " EmitVertex();\n"
21287 " any_fs = result;\n"
21288 " gl_Position = vec4(1, 1, 0, 1);\n"
21289 " EmitVertex();\n"
21290 "}\n"
21291 "\n";
21292 static const GLchar *tcs = "#version 430 core\n"
21293 "#extension GL_ARB_enhanced_layouts : require\n"
21294 "\n"
21295 "layout(vertices = 1) out;\n"
21296 "\n"
21297 "in vec4 vs_any[];\n"
21298 "out vec4 tcs_tes[];\n"
21299 "\n"
21300 "void main()\n"
21301 "{\n"
21302 "\n"
21303 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21304 "\n"
21305 " gl_TessLevelOuter[0] = 1.0;\n"
21306 " gl_TessLevelOuter[1] = 1.0;\n"
21307 " gl_TessLevelOuter[2] = 1.0;\n"
21308 " gl_TessLevelOuter[3] = 1.0;\n"
21309 " gl_TessLevelInner[0] = 1.0;\n"
21310 " gl_TessLevelInner[1] = 1.0;\n"
21311 "}\n"
21312 "\n";
21313 static const GLchar *tes_tested = "#version 430 core\n"
21314 "#extension GL_ARB_enhanced_layouts : require\n"
21315 "\n"
21316 "layout(isolines, point_mode) in;\n"
21317 "\n"
21318 "VAR_DEFINITION"
21319 "\n"
21320 "in vec4 tcs_tes[];\n"
21321 "out vec4 any_fs;\n"
21322 "\n"
21323 "void main()\n"
21324 "{\n"
21325 " vec4 result = tcs_tes[0];\n"
21326 "\n"
21327 "VARIABLE_USE"
21328 "\n"
21329 " any_fs += result;\n"
21330 "}\n"
21331 "\n";
21332 static const GLchar *vs = "#version 430 core\n"
21333 "#extension GL_ARB_enhanced_layouts : require\n"
21334 "\n"
21335 "in vec4 in_vs;\n"
21336 "out vec4 vs_any;\n"
21337 "\n"
21338 "void main()\n"
21339 "{\n"
21340 " vs_any = in_vs;\n"
21341 "}\n"
21342 "\n";
21343 static const GLchar *vs_tested = "#version 430 core\n"
21344 "#extension GL_ARB_enhanced_layouts : require\n"
21345 "\n"
21346 "VAR_DEFINITION"
21347 "\n"
21348 "in vec4 in_vs;\n"
21349 "out vec4 any_fs;\n"
21350 "\n"
21351 "void main()\n"
21352 "{\n"
21353 " vec4 result = in_vs;\n"
21354 "\n"
21355 "VARIABLE_USE"
21356 "\n"
21357 " any_fs += result;\n"
21358 "}\n"
21359 "\n";
21360
21361 std::string source;
21362 testCase &test_case = m_test_cases[test_case_index];
21363
21364 if (test_case.m_stage == stage)
21365 {
21366 size_t position = 0;
21367 const GLchar *var_definition = 0;
21368 const GLchar *var_use = 0;
21369
21370 switch (test_case.m_case)
21371 {
21372 case OFFSET:
21373 var_definition = offset_var_definition;
21374 var_use = output_use;
21375 break;
21376 case STRIDE:
21377 var_definition = stride_var_definition;
21378 var_use = output_use;
21379 break;
21380 case BLOCK:
21381 var_definition = block_var_definition;
21382 var_use = block_use;
21383 break;
21384 case ARRAY:
21385 var_definition = array_var_definition;
21386 var_use = array_use;
21387 break;
21388 default:
21389 TCU_FAIL("Invalid enum");
21390 }
21391
21392 switch (stage)
21393 {
21394 case Utils::Shader::GEOMETRY:
21395 source = gs_tested;
21396 break;
21397 case Utils::Shader::TESS_EVAL:
21398 source = tes_tested;
21399 break;
21400 case Utils::Shader::VERTEX:
21401 source = vs_tested;
21402 break;
21403 default:
21404 TCU_FAIL("Invalid enum");
21405 }
21406
21407 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21408 position = 0;
21409 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21410 }
21411 else
21412 {
21413 switch (test_case.m_stage)
21414 {
21415 case Utils::Shader::GEOMETRY:
21416 switch (stage)
21417 {
21418 case Utils::Shader::FRAGMENT:
21419 source = fs;
21420 break;
21421 case Utils::Shader::VERTEX:
21422 source = vs;
21423 break;
21424 default:
21425 source = "";
21426 }
21427 break;
21428 case Utils::Shader::TESS_EVAL:
21429 switch (stage)
21430 {
21431 case Utils::Shader::FRAGMENT:
21432 source = fs;
21433 break;
21434 case Utils::Shader::TESS_CTRL:
21435 source = tcs;
21436 break;
21437 case Utils::Shader::VERTEX:
21438 source = vs;
21439 break;
21440 default:
21441 source = "";
21442 }
21443 break;
21444 case Utils::Shader::VERTEX:
21445 switch (stage)
21446 {
21447 case Utils::Shader::FRAGMENT:
21448 source = fs;
21449 break;
21450 default:
21451 source = "";
21452 }
21453 break;
21454 default:
21455 TCU_FAIL("Invalid enum");
21456 }
21457 }
21458
21459 return source;
21460 }
21461
21462 /** Get description of test case
21463 *
21464 * @param test_case_index Index of test case
21465 *
21466 * @return Test case description
21467 **/
21468 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index)
21469 {
21470 std::stringstream stream;
21471 testCase &test_case = m_test_cases[test_case_index];
21472
21473 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
21474
21475 switch (test_case.m_case)
21476 {
21477 case OFFSET:
21478 stream << "buffer stride: 40, vec4 offset: 32";
21479 break;
21480 case STRIDE:
21481 stream << "buffer stride: 32, vec4 off 16 stride: 32";
21482 break;
21483 case BLOCK:
21484 stream << "buffer stride: 32, block 3xvec4 offset 0";
21485 break;
21486 case ARRAY:
21487 stream << "buffer stride: 32, vec4[4] offset 16";
21488 break;
21489 default:
21490 TCU_FAIL("Invalid enum");
21491 }
21492
21493 return stream.str();
21494 }
21495
21496 /** Get number of test cases
21497 *
21498 * @return Number of test cases
21499 **/
21500 GLuint XFBTooSmallStrideTest::getTestCaseNumber()
21501 {
21502 return static_cast<GLuint>(m_test_cases.size());
21503 }
21504
21505 /** Selects if "compute" stage is relevant for test
21506 *
21507 * @param ignored
21508 *
21509 * @return false
21510 **/
21511 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21512 {
21513 return false;
21514 }
21515
21516 /** Prepare all test cases
21517 *
21518 **/
21519 void XFBTooSmallStrideTest::testInit()
21520 {
21521 for (GLuint c = 0; c < CASE_MAX; ++c)
21522 {
21523 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21524 {
21525 /*
21526 It is invalid to define transform feedback output in TCS, according to spec:
21527 The data captured in transform feedback mode depends on the active programs on each of the shader stages.
21528 If a program is active for the geometry shader stage, transform feedback captures the vertices of each
21529 primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation
21530 shader stage, transform feedback captures each primitive produced by the tessellation primitive generator,
21531 whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures
21532 each primitive processed by the vertex shader.
21533 */
21534 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21535 (Utils::Shader::FRAGMENT == stage))
21536 {
21537 continue;
21538 }
21539
21540 testCase test_case = {(CASES)c, (Utils::Shader::STAGES)stage};
21541
21542 m_test_cases.push_back(test_case);
21543 }
21544 }
21545 }
21546
21547 /** Constructor
21548 *
21549 * @param context Test framework context
21550 **/
21551 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context &context)
21552 : NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected")
21553 {
21554 }
21555
21556 /** Source for given test case and stage
21557 *
21558 * @param test_case_index Index of test case
21559 * @param stage Shader stage
21560 *
21561 * @return Shader source
21562 **/
21563 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21564 {
21565 static const GLchar *invalid_var_definition = "const uint type_size = SIZE;\n"
21566 "\n"
21567 #if DEBUG_NEG_REMOVE_ERROR
21568 "layout (xfb_stride = 2 * type_size) out;\n"
21569 #else
21570 "layout (xfb_stride = type_size) out;\n"
21571 #endif /* DEBUG_NEG_REMOVE_ERROR */
21572 "\n"
21573 "layout (xfb_offset = 0) out TYPE goku;\n"
21574 "layout (xfb_offset = type_size) out TYPE vegeta;\n";
21575 static const GLchar *valid_var_definition = "const uint type_size = SIZE;\n"
21576 "\n"
21577 "layout (xfb_stride = type_size) out;\n"
21578 "\n"
21579 "layout (xfb_offset = 0) out TYPE goku;\n";
21580 static const GLchar *invalid_use = " goku = TYPE(1);\n"
21581 " vegeta = TYPE(0);\n"
21582 " if (vec4(0) == result)\n"
21583 " {\n"
21584 " goku = TYPE(0);\n"
21585 " vegeta = TYPE(1);\n"
21586 " }\n";
21587 static const GLchar *valid_use = " goku = TYPE(1);\n"
21588 " if (vec4(0) == result)\n"
21589 " {\n"
21590 " goku = TYPE(0);\n"
21591 " }\n";
21592 static const GLchar *fs = "#version 430 core\n"
21593 "#extension GL_ARB_enhanced_layouts : require\n"
21594 "\n"
21595 "in vec4 any_fs;\n"
21596 "out vec4 fs_out;\n"
21597 "\n"
21598 "void main()\n"
21599 "{\n"
21600 " fs_out = any_fs;\n"
21601 "}\n"
21602 "\n";
21603 static const GLchar *gs_tested = "#version 430 core\n"
21604 "#extension GL_ARB_enhanced_layouts : require\n"
21605 "\n"
21606 "layout(points) in;\n"
21607 "layout(triangle_strip, max_vertices = 4) out;\n"
21608 "\n"
21609 "VAR_DEFINITION"
21610 "\n"
21611 "in vec4 vs_any[];\n"
21612 "out vec4 any_fs;\n"
21613 "\n"
21614 "void main()\n"
21615 "{\n"
21616 " vec4 result = vs_any[0];\n"
21617 "\n"
21618 "VARIABLE_USE"
21619 "\n"
21620 " any_fs = result;\n"
21621 " gl_Position = vec4(-1, -1, 0, 1);\n"
21622 " EmitVertex();\n"
21623 " any_fs = result;\n"
21624 " gl_Position = vec4(-1, 1, 0, 1);\n"
21625 " EmitVertex();\n"
21626 " any_fs = result;\n"
21627 " gl_Position = vec4(1, -1, 0, 1);\n"
21628 " EmitVertex();\n"
21629 " any_fs = result;\n"
21630 " gl_Position = vec4(1, 1, 0, 1);\n"
21631 " EmitVertex();\n"
21632 "}\n"
21633 "\n";
21634 static const GLchar *tcs = "#version 430 core\n"
21635 "#extension GL_ARB_enhanced_layouts : require\n"
21636 "\n"
21637 "layout(vertices = 1) out;\n"
21638 "\n"
21639 "in vec4 vs_any[];\n"
21640 "out vec4 tcs_tes[];\n"
21641 "\n"
21642 "void main()\n"
21643 "{\n"
21644 "\n"
21645 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21646 "\n"
21647 " gl_TessLevelOuter[0] = 1.0;\n"
21648 " gl_TessLevelOuter[1] = 1.0;\n"
21649 " gl_TessLevelOuter[2] = 1.0;\n"
21650 " gl_TessLevelOuter[3] = 1.0;\n"
21651 " gl_TessLevelInner[0] = 1.0;\n"
21652 " gl_TessLevelInner[1] = 1.0;\n"
21653 "}\n"
21654 "\n";
21655 static const GLchar *tes_tested = "#version 430 core\n"
21656 "#extension GL_ARB_enhanced_layouts : require\n"
21657 "\n"
21658 "layout(isolines, point_mode) in;\n"
21659 "\n"
21660 "VAR_DEFINITION"
21661 "\n"
21662 "in vec4 tcs_tes[];\n"
21663 "out vec4 any_fs;\n"
21664 "\n"
21665 "void main()\n"
21666 "{\n"
21667 " vec4 result = tcs_tes[0];\n"
21668 "\n"
21669 "VARIABLE_USE"
21670 "\n"
21671 " any_fs = result;\n"
21672 "}\n"
21673 "\n";
21674 static const GLchar *vs = "#version 430 core\n"
21675 "#extension GL_ARB_enhanced_layouts : require\n"
21676 "\n"
21677 "in vec4 in_vs;\n"
21678 "out vec4 vs_any;\n"
21679 "\n"
21680 "void main()\n"
21681 "{\n"
21682 " vs_any = in_vs;\n"
21683 "}\n"
21684 "\n";
21685 static const GLchar *vs_tested = "#version 430 core\n"
21686 "#extension GL_ARB_enhanced_layouts : require\n"
21687 "\n"
21688 "VAR_DEFINITION"
21689 "\n"
21690 "in vec4 in_vs;\n"
21691 "out vec4 any_fs;\n"
21692 "\n"
21693 "void main()\n"
21694 "{\n"
21695 " vec4 result = in_vs;\n"
21696 "\n"
21697 "VARIABLE_USE"
21698 "\n"
21699 " any_fs = result;\n"
21700 "}\n"
21701 "\n";
21702
21703 std::string source;
21704 testCase &test_case = m_test_cases[test_case_index];
21705
21706 if (test_case.m_stage == stage)
21707 {
21708 GLchar buffer[16];
21709 size_t position = 0;
21710 const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
21711 const GLchar *var_definition = 0;
21712 const GLchar *var_use = 0;
21713
21714 sprintf(buffer, "%d", test_case.m_type.GetSize());
21715
21716 switch (test_case.m_case)
21717 {
21718 case VALID:
21719 var_definition = valid_var_definition;
21720 var_use = valid_use;
21721 break;
21722 case INVALID:
21723 var_definition = invalid_var_definition;
21724 var_use = invalid_use;
21725 break;
21726 default:
21727 TCU_FAIL("Invalid enum");
21728 }
21729
21730 switch (stage)
21731 {
21732 case Utils::Shader::GEOMETRY:
21733 source = gs_tested;
21734 break;
21735 case Utils::Shader::TESS_EVAL:
21736 source = tes_tested;
21737 break;
21738 case Utils::Shader::VERTEX:
21739 source = vs_tested;
21740 break;
21741 default:
21742 TCU_FAIL("Invalid enum");
21743 }
21744
21745 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21746 position = 0;
21747 Utils::replaceToken("SIZE", position, buffer, source);
21748 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21749
21750 Utils::replaceAllTokens("TYPE", type_name, source);
21751 }
21752 else
21753 {
21754 switch (test_case.m_stage)
21755 {
21756 case Utils::Shader::GEOMETRY:
21757 switch (stage)
21758 {
21759 case Utils::Shader::FRAGMENT:
21760 source = fs;
21761 break;
21762 case Utils::Shader::VERTEX:
21763 source = vs;
21764 break;
21765 default:
21766 source = "";
21767 }
21768 break;
21769 case Utils::Shader::TESS_EVAL:
21770 switch (stage)
21771 {
21772 case Utils::Shader::FRAGMENT:
21773 source = fs;
21774 break;
21775 case Utils::Shader::TESS_CTRL:
21776 source = tcs;
21777 break;
21778 case Utils::Shader::VERTEX:
21779 source = vs;
21780 break;
21781 default:
21782 source = "";
21783 }
21784 break;
21785 case Utils::Shader::VERTEX:
21786 switch (stage)
21787 {
21788 case Utils::Shader::FRAGMENT:
21789 source = fs;
21790 break;
21791 default:
21792 source = "";
21793 }
21794 break;
21795 default:
21796 TCU_FAIL("Invalid enum");
21797 }
21798 }
21799
21800 return source;
21801 }
21802
21803 /** Get description of test case
21804 *
21805 * @param test_case_index Index of test case
21806 *
21807 * @return Test case description
21808 **/
21809 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index)
21810 {
21811 std::stringstream stream;
21812 testCase &test_case = m_test_cases[test_case_index];
21813
21814 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
21815 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
21816
21817 switch (test_case.m_case)
21818 {
21819 case VALID:
21820 stream << "valid";
21821 break;
21822 case INVALID:
21823 stream << "invalid";
21824 break;
21825 default:
21826 TCU_FAIL("Invalid enum");
21827 }
21828
21829 return stream.str();
21830 }
21831
21832 /** Get number of test cases
21833 *
21834 * @return Number of test cases
21835 **/
21836 GLuint XFBVariableStrideTest::getTestCaseNumber()
21837 {
21838 return static_cast<GLuint>(m_test_cases.size());
21839 }
21840
21841 /** Selects if "compute" stage is relevant for test
21842 *
21843 * @param ignored
21844 *
21845 * @return false
21846 **/
21847 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21848 {
21849 return false;
21850 }
21851
21852 /** Selects if compilation failure is expected result
21853 *
21854 * @param test_case_index Index of test case
21855 *
21856 * @return true
21857 **/
21858 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index)
21859 {
21860 testCase &test_case = m_test_cases[test_case_index];
21861
21862 return (INVALID == test_case.m_case);
21863 }
21864
21865 /** Prepare all test cases
21866 *
21867 **/
21868 void XFBVariableStrideTest::testInit()
21869 {
21870 const GLuint n_types = getTypesNumber();
21871
21872 for (GLuint i = 0; i < n_types; ++i)
21873 {
21874 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21875 {
21876 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21877 (Utils::Shader::FRAGMENT == stage))
21878 {
21879 continue;
21880 }
21881
21882 const Utils::Type &type = getType(i);
21883 for (GLuint c = 0; c < CASE_MAX; ++c)
21884 {
21885 testCase test_case = {static_cast<CASES>(c), static_cast<Utils::Shader::STAGES>(stage), type};
21886
21887 m_test_cases.push_back(test_case);
21888 }
21889 }
21890 }
21891 }
21892
21893 /** Constructor
21894 *
21895 * @param context Test framework context
21896 **/
21897 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context &context)
21898 : TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks")
21899 {
21900 }
21901
21902 /** Source for given test case and stage
21903 *
21904 * @param test_case_index Index of test case
21905 * @param stage Shader stage
21906 *
21907 * @return Shader source
21908 **/
21909 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21910 {
21911 static const GLchar *var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n"
21912 " vec4 gohan;\n"
21913 " vec4 goten;\n"
21914 " vec4 chichi;\n"
21915 "} gokuARRAY;\n";
21916 static const GLchar *var_use = " gokuINDEX.gohan = vec4(1, 0, 0, 0);\n"
21917 " gokuINDEX.goten = vec4(0, 0, 1, 0);\n"
21918 " gokuINDEX.chichi = vec4(0, 1, 0, 0);\n"
21919 " if (vec4(0) == result)\n"
21920 " {\n"
21921 " gokuINDEX.gohan = vec4(0, 1, 1, 1);\n"
21922 " gokuINDEX.goten = vec4(1, 1, 0, 1);\n"
21923 " gokuINDEX.chichi = vec4(1, 0, 1, 1);\n"
21924 " }\n";
21925 static const GLchar *gs_tested =
21926 "#version 430 core\n"
21927 "#extension GL_ARB_enhanced_layouts : require\n"
21928 "\n"
21929 "layout(points) in;\n"
21930 "layout(triangle_strip, max_vertices = 4) out;\n"
21931 "\n"
21932 "VAR_DEFINITION"
21933 "\n"
21934 "out gl_PerVertex \n"
21935 "{ \n"
21936 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
21937 "}; \n"
21938 "in vec4 tes_gs[];\n"
21939 "out vec4 gs_fs;\n"
21940 "\n"
21941 "void main()\n"
21942 "{\n"
21943 " vec4 result = tes_gs[0];\n"
21944 "\n"
21945 "VARIABLE_USE"
21946 "\n"
21947 " gs_fs = result;\n"
21948 " gl_Position = vec4(-1, -1, 0, 1);\n"
21949 " EmitVertex();\n"
21950 " gs_fs = result;\n"
21951 " gl_Position = vec4(-1, 1, 0, 1);\n"
21952 " EmitVertex();\n"
21953 " gs_fs = result;\n"
21954 " gl_Position = vec4(1, -1, 0, 1);\n"
21955 " EmitVertex();\n"
21956 " gs_fs = result;\n"
21957 " gl_Position = vec4(1, 1, 0, 1);\n"
21958 " EmitVertex();\n"
21959 "}\n"
21960 "\n";
21961 static const GLchar *tcs = "#version 430 core\n"
21962 "#extension GL_ARB_enhanced_layouts : require\n"
21963 "\n"
21964 "layout(vertices = 1) out;\n"
21965 "\n"
21966 "in vec4 vs_tcs[];\n"
21967 "out vec4 tcs_tes[];\n"
21968 "\n"
21969 "void main()\n"
21970 "{\n"
21971 "\n"
21972 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
21973 "\n"
21974 " gl_TessLevelOuter[0] = 1.0;\n"
21975 " gl_TessLevelOuter[1] = 1.0;\n"
21976 " gl_TessLevelOuter[2] = 1.0;\n"
21977 " gl_TessLevelOuter[3] = 1.0;\n"
21978 " gl_TessLevelInner[0] = 1.0;\n"
21979 " gl_TessLevelInner[1] = 1.0;\n"
21980 "}\n"
21981 "\n";
21982 #if 0
21983 static const GLchar* tcs_tested =
21984 "#version 430 core\n"
21985 "#extension GL_ARB_enhanced_layouts : require\n"
21986 "\n"
21987 "layout(vertices = 1) out;\n"
21988 "\n"
21989 "VAR_DEFINITION"
21990 "\n"
21991 "in vec4 vs_tcs[];\n"
21992 "out vec4 tcs_tes[];\n"
21993 "\n"
21994 "void main()\n"
21995 "{\n"
21996 " vec4 result = vs_tcs[gl_InvocationID];\n"
21997 "\n"
21998 "VARIABLE_USE"
21999 "\n"
22000 " tcs_tes[gl_InvocationID] = result;\n"
22001 "\n"
22002 " gl_TessLevelOuter[0] = 1.0;\n"
22003 " gl_TessLevelOuter[1] = 1.0;\n"
22004 " gl_TessLevelOuter[2] = 1.0;\n"
22005 " gl_TessLevelOuter[3] = 1.0;\n"
22006 " gl_TessLevelInner[0] = 1.0;\n"
22007 " gl_TessLevelInner[1] = 1.0;\n"
22008 "}\n"
22009 "\n";
22010 #endif
22011 static const GLchar *tes_tested = "#version 430 core\n"
22012 "#extension GL_ARB_enhanced_layouts : require\n"
22013 "\n"
22014 "layout(isolines, point_mode) in;\n"
22015 "\n"
22016 "VAR_DEFINITION"
22017 "\n"
22018 "in vec4 tcs_tes[];\n"
22019 "out vec4 tes_gs;\n"
22020 "\n"
22021 "void main()\n"
22022 "{\n"
22023 " vec4 result = tcs_tes[0];\n"
22024 "\n"
22025 "VARIABLE_USE"
22026 "\n"
22027 " tes_gs += result;\n"
22028 "}\n"
22029 "\n";
22030 static const GLchar *vs = "#version 430 core\n"
22031 "#extension GL_ARB_enhanced_layouts : require\n"
22032 "\n"
22033 "in vec4 in_vs;\n"
22034 "out vec4 vs_tcs;\n"
22035 "out vec4 tes_gs;\n"
22036 "\n"
22037 "void main()\n"
22038 "{\n"
22039 " vs_tcs = tes_gs = in_vs;\n"
22040 "}\n"
22041 "\n";
22042 static const GLchar *vs_tested = "#version 430 core\n"
22043 "#extension GL_ARB_enhanced_layouts : require\n"
22044 "\n"
22045 "VAR_DEFINITION"
22046 "\n"
22047 "in vec4 in_vs;\n"
22048 "out vec4 vs_tcs;\n"
22049 "\n"
22050 "void main()\n"
22051 "{\n"
22052 " vec4 result = in_vs;\n"
22053 "\n"
22054 "VARIABLE_USE"
22055 "\n"
22056 " vs_tcs += result;\n"
22057 "}\n"
22058 "\n";
22059
22060 std::string source;
22061 Utils::Shader::STAGES test_case = m_test_cases[test_case_index];
22062
22063 if (test_case == stage)
22064 {
22065 const GLchar *array = "";
22066 const GLchar *index = "";
22067 size_t position = 0;
22068 size_t temp;
22069 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22070 // change array = "[]" to "[1]"
22071 switch (stage)
22072 {
22073 case Utils::Shader::GEOMETRY:
22074 source = gs_tested;
22075 array = "[1]";
22076 index = "[0]";
22077 break;
22078 /*
22079 It is invalid to define transform feedback output in HS
22080 */
22081 #if 0
22082 case Utils::Shader::TESS_CTRL:
22083 source = tcs_tested;
22084 array = "[]";
22085 index = "[gl_InvocationID]";
22086 break;
22087 #endif
22088 case Utils::Shader::TESS_EVAL:
22089 source = tes_tested;
22090 array = "[1]";
22091 index = "[0]";
22092 break;
22093 case Utils::Shader::VERTEX:
22094 source = vs_tested;
22095 break;
22096 default:
22097 TCU_FAIL("Invalid enum");
22098 }
22099
22100 temp = position;
22101 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22102 position = temp;
22103 Utils::replaceToken("ARRAY", position, array, source);
22104 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22105
22106 Utils::replaceAllTokens("INDEX", index, source);
22107 }
22108 else
22109 {
22110 switch (test_case)
22111 {
22112 case Utils::Shader::GEOMETRY:
22113 switch (stage)
22114 {
22115 case Utils::Shader::VERTEX:
22116 source = vs;
22117 break;
22118 default:
22119 source = "";
22120 }
22121 break;
22122 case Utils::Shader::TESS_CTRL:
22123 switch (stage)
22124 {
22125 case Utils::Shader::VERTEX:
22126 source = vs;
22127 break;
22128 default:
22129 source = "";
22130 }
22131 break;
22132 case Utils::Shader::TESS_EVAL:
22133 switch (stage)
22134 {
22135 case Utils::Shader::TESS_CTRL:
22136 source = tcs;
22137 break;
22138 case Utils::Shader::VERTEX:
22139 source = vs;
22140 break;
22141 default:
22142 source = "";
22143 }
22144 break;
22145 case Utils::Shader::VERTEX:
22146 source = "";
22147 break;
22148 default:
22149 TCU_FAIL("Invalid enum");
22150 }
22151 }
22152
22153 return source;
22154 }
22155
22156 /** Get description of test case
22157 *
22158 * @param test_case_index Index of test case
22159 *
22160 * @return Test case description
22161 **/
22162 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index)
22163 {
22164 std::stringstream stream;
22165
22166 stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]);
22167
22168 return stream.str();
22169 }
22170
22171 /** Get number of test cases
22172 *
22173 * @return Number of test cases
22174 **/
22175 GLuint XFBBlockStrideTest::getTestCaseNumber()
22176 {
22177 return static_cast<GLuint>(m_test_cases.size());
22178 }
22179
22180 /** Inspects program for xfb stride
22181 *
22182 * @param program Program to query
22183 *
22184 * @return true if query results match expected values, false otherwise
22185 **/
22186 bool XFBBlockStrideTest::inspectProgram(Utils::Program &program)
22187 {
22188 GLint stride = 0;
22189
22190 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
22191 1 /* buf_size */, &stride);
22192
22193 return (128 == stride);
22194 }
22195
22196 /** Runs test case
22197 *
22198 * @param test_case_index Id of test case
22199 *
22200 * @return true if test case pass, false otherwise
22201 **/
22202 bool XFBBlockStrideTest::testCase(GLuint test_case_index)
22203 {
22204 const std::string &gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
22205 Utils::Program program(m_context);
22206 const std::string &tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
22207 const std::string &tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
22208 bool test_case_result = true;
22209 const std::string &vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
22210
22211 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
22212
22213 test_case_result = inspectProgram(program);
22214
22215 return test_case_result;
22216 }
22217
22218 /** Prepare all test cases
22219 *
22220 **/
22221 void XFBBlockStrideTest::testInit()
22222 {
22223 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22224 {
22225 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22226 (Utils::Shader::FRAGMENT == stage))
22227 {
22228 continue;
22229 }
22230
22231 m_test_cases.push_back((Utils::Shader::STAGES)stage);
22232 }
22233 }
22234
22235 /** Constructor
22236 *
22237 * @param context Test context
22238 **/
22239 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context &context)
22240 : BufferTestBase(context, "xfb_block_member_stride",
22241 "Test verifies that xfb_stride qualifier is respected for block member")
22242 {
22243 /* Nothing to be done here */
22244 }
22245
22246 /** Get descriptors of buffers necessary for test
22247 *
22248 * @param ignored
22249 * @param out_descriptors Descriptors of buffers used by test
22250 **/
22251 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
22252 bufferDescriptor::Vector &out_descriptors)
22253 {
22254 const Utils::Type &vec4 = Utils::Type::vec4;
22255
22256 /* Test needs single uniform and xfb */
22257 out_descriptors.resize(2);
22258
22259 /* Get references */
22260 bufferDescriptor &uniform = out_descriptors[0];
22261 bufferDescriptor &xfb = out_descriptors[1];
22262
22263 /* Index */
22264 uniform.m_index = 0;
22265 xfb.m_index = 0;
22266
22267 /* Target */
22268 uniform.m_target = Utils::Buffer::Uniform;
22269 xfb.m_target = Utils::Buffer::Transform_feedback;
22270
22271 /* Data */
22272 static const GLuint vec4_size = 16;
22273 const std::vector<GLubyte> &gohan_data = vec4.GenerateDataPacked();
22274 const std::vector<GLubyte> &goten_data = vec4.GenerateDataPacked();
22275 const std::vector<GLubyte> &chichi_data = vec4.GenerateDataPacked();
22276
22277 /* Uniform data */
22278 uniform.m_initial_data.resize(3 * vec4_size);
22279 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size);
22280 memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size);
22281 memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
22282
22283 /* XFB data */
22284 xfb.m_initial_data.resize(4 * vec4_size);
22285 xfb.m_expected_data.resize(4 * vec4_size);
22286
22287 for (GLuint i = 0; i < 4 * vec4_size; ++i)
22288 {
22289 xfb.m_initial_data[i] = (glw::GLubyte)i;
22290 xfb.m_expected_data[i] = (glw::GLubyte)i;
22291 }
22292
22293 // the xfb_offset of "chichi" should be 32
22294 memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size);
22295 memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size);
22296 memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
22297 }
22298
22299 /** Get body of main function for given shader stage
22300 *
22301 * @param ignored
22302 * @param stage Shader stage
22303 * @param out_assignments Set to empty
22304 * @param out_calculations Set to empty
22305 **/
22306 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
22307 std::string &out_assignments, std::string &out_calculations)
22308 {
22309 out_calculations = "";
22310
22311 static const GLchar *gs = " gohan = uni_gohan;\n"
22312 " goten = uni_goten;\n"
22313 " chichi = uni_chichi;\n";
22314 static const GLchar *fs = " fs_out = gohan + goten + chichi;\n";
22315
22316 const GLchar *assignments = "";
22317 switch (stage)
22318 {
22319 case Utils::Shader::FRAGMENT:
22320 assignments = fs;
22321 break;
22322 case Utils::Shader::GEOMETRY:
22323 assignments = gs;
22324 break;
22325 default:
22326 break;
22327 }
22328
22329 out_assignments = assignments;
22330 }
22331
22332 /** Get interface of shader
22333 *
22334 * @param ignored
22335 * @param stage Shader stage
22336 * @param out_interface Set to ""
22337 **/
22338 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
22339 std::string &out_interface)
22340 {
22341 static const GLchar *gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
22342 " vec4 gohan;\n"
22343 " layout (xfb_stride = 48) vec4 goten;\n"
22344 " vec4 chichi;\n"
22345 "};\n"
22346 "layout(binding = 0) uniform gs_block {\n"
22347 " vec4 uni_gohan;\n"
22348 " vec4 uni_goten;\n"
22349 " vec4 uni_chichi;\n"
22350 "};\n";
22351 static const GLchar *fs = "in Goku {\n"
22352 " vec4 gohan;\n"
22353 " vec4 goten;\n"
22354 " vec4 chichi;\n"
22355 "};\n"
22356 "out vec4 fs_out;\n";
22357
22358 switch (stage)
22359 {
22360 case Utils::Shader::FRAGMENT:
22361 out_interface = fs;
22362 break;
22363 case Utils::Shader::GEOMETRY:
22364 out_interface = gs;
22365 break;
22366 default:
22367 out_interface = "";
22368 return;
22369 }
22370 }
22371
22372 /** Inspects program to check if all resources are as expected
22373 *
22374 * @param ignored
22375 * @param program Program instance
22376 * @param out_stream Error message
22377 *
22378 * @return true if everything is ok, false otherwise
22379 **/
22380 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program &program,
22381 std::stringstream &out_stream)
22382 {
22383 const GLuint gohan_id = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING);
22384 const GLuint goten_id = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING);
22385 const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING);
22386
22387 GLint gohan_offset = 0;
22388 GLint goten_offset = 0;
22389 GLint chichi_offset = 0;
22390
22391 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset);
22392 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset);
22393 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset);
22394
22395 // the xfb_offset of "chichi" should be 32
22396 if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset))
22397 {
22398 out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset
22399 << "] expected: [0, 16, 32]";
22400 return false;
22401 }
22402
22403 return true;
22404 }
22405
22406 /** Constructor
22407 *
22408 * @param context Test framework context
22409 **/
22410 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context &context)
22411 : NegativeTestBase(context, "xfb_duplicated_stride",
22412 "Test verifies that compiler reports error when conflicting stride qualifiers are used")
22413 {
22414 }
22415
22416 /** Source for given test case and stage
22417 *
22418 * @param test_case_index Index of test case
22419 * @param stage Shader stage
22420 *
22421 * @return Shader source
22422 **/
22423 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22424 {
22425 static const GLchar *invalid_var_definition = "const uint valid_stride = 64;\n"
22426 #if DEBUG_NEG_REMOVE_ERROR
22427 "const uint conflicting_stride = 64;\n"
22428 #else
22429 "const uint conflicting_stride = 128;\n"
22430 #endif /* DEBUG_NEG_REMOVE_ERROR */
22431 "\n"
22432 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
22433 "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n";
22434 static const GLchar *valid_var_definition = "const uint valid_stride = 64;\n"
22435 "\n"
22436 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
22437 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n";
22438 static const GLchar *fs = "#version 430 core\n"
22439 "#extension GL_ARB_enhanced_layouts : require\n"
22440 "\n"
22441 "in vec4 any_fs;\n"
22442 "out vec4 fs_out;\n"
22443 "\n"
22444 "void main()\n"
22445 "{\n"
22446 " fs_out = any_fs;\n"
22447 "}\n"
22448 "\n";
22449 static const GLchar *gs_tested = "#version 430 core\n"
22450 "#extension GL_ARB_enhanced_layouts : require\n"
22451 "\n"
22452 "layout(points) in;\n"
22453 "layout(triangle_strip, max_vertices = 4) out;\n"
22454 "\n"
22455 "VAR_DEFINITION"
22456 "\n"
22457 "in vec4 vs_any[];\n"
22458 "out vec4 any_fs;\n"
22459 "\n"
22460 "void main()\n"
22461 "{\n"
22462 " vec4 result = vs_any[0];\n"
22463 "\n"
22464 " any_fs = result;\n"
22465 " gl_Position = vec4(-1, -1, 0, 1);\n"
22466 " EmitVertex();\n"
22467 " any_fs = result;\n"
22468 " gl_Position = vec4(-1, 1, 0, 1);\n"
22469 " EmitVertex();\n"
22470 " any_fs = result;\n"
22471 " gl_Position = vec4(1, -1, 0, 1);\n"
22472 " EmitVertex();\n"
22473 " any_fs = result;\n"
22474 " gl_Position = vec4(1, 1, 0, 1);\n"
22475 " EmitVertex();\n"
22476 "}\n"
22477 "\n";
22478 static const GLchar *tcs = "#version 430 core\n"
22479 "#extension GL_ARB_enhanced_layouts : require\n"
22480 "\n"
22481 "layout(vertices = 1) out;\n"
22482 "\n"
22483 "in vec4 vs_any[];\n"
22484 "out vec4 tcs_tes[];\n"
22485 "\n"
22486 "void main()\n"
22487 "{\n"
22488 "\n"
22489 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
22490 "\n"
22491 " gl_TessLevelOuter[0] = 1.0;\n"
22492 " gl_TessLevelOuter[1] = 1.0;\n"
22493 " gl_TessLevelOuter[2] = 1.0;\n"
22494 " gl_TessLevelOuter[3] = 1.0;\n"
22495 " gl_TessLevelInner[0] = 1.0;\n"
22496 " gl_TessLevelInner[1] = 1.0;\n"
22497 "}\n"
22498 "\n";
22499 static const GLchar *tes_tested = "#version 430 core\n"
22500 "#extension GL_ARB_enhanced_layouts : require\n"
22501 "\n"
22502 "layout(isolines, point_mode) in;\n"
22503 "\n"
22504 "VAR_DEFINITION"
22505 "\n"
22506 "in vec4 tcs_tes[];\n"
22507 "out vec4 any_fs;\n"
22508 "\n"
22509 "void main()\n"
22510 "{\n"
22511 " vec4 result = tcs_tes[0];\n"
22512 "\n"
22513 " any_fs = result;\n"
22514 "}\n"
22515 "\n";
22516 static const GLchar *vs = "#version 430 core\n"
22517 "#extension GL_ARB_enhanced_layouts : require\n"
22518 "\n"
22519 "in vec4 in_vs;\n"
22520 "out vec4 vs_any;\n"
22521 "\n"
22522 "void main()\n"
22523 "{\n"
22524 " vs_any = in_vs;\n"
22525 "}\n"
22526 "\n";
22527 static const GLchar *vs_tested = "#version 430 core\n"
22528 "#extension GL_ARB_enhanced_layouts : require\n"
22529 "\n"
22530 "VAR_DEFINITION"
22531 "\n"
22532 "in vec4 in_vs;\n"
22533 "out vec4 any_fs;\n"
22534 "\n"
22535 "void main()\n"
22536 "{\n"
22537 " vec4 result = in_vs;\n"
22538 "\n"
22539 " any_fs += result;\n"
22540 "}\n"
22541 "\n";
22542
22543 std::string source;
22544 testCase &test_case = m_test_cases[test_case_index];
22545
22546 if (test_case.m_stage == stage)
22547 {
22548 size_t position = 0;
22549 const GLchar *var_definition = 0;
22550
22551 switch (test_case.m_case)
22552 {
22553 case VALID:
22554 var_definition = valid_var_definition;
22555 break;
22556 case INVALID:
22557 var_definition = invalid_var_definition;
22558 break;
22559 default:
22560 TCU_FAIL("Invalid enum");
22561 }
22562
22563 switch (stage)
22564 {
22565 case Utils::Shader::GEOMETRY:
22566 source = gs_tested;
22567 break;
22568 case Utils::Shader::TESS_EVAL:
22569 source = tes_tested;
22570 break;
22571 case Utils::Shader::VERTEX:
22572 source = vs_tested;
22573 break;
22574 default:
22575 TCU_FAIL("Invalid enum");
22576 }
22577
22578 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22579 }
22580 else
22581 {
22582 switch (test_case.m_stage)
22583 {
22584 case Utils::Shader::GEOMETRY:
22585 switch (stage)
22586 {
22587 case Utils::Shader::FRAGMENT:
22588 source = fs;
22589 break;
22590 case Utils::Shader::VERTEX:
22591 source = vs;
22592 break;
22593 default:
22594 source = "";
22595 }
22596 break;
22597 case Utils::Shader::TESS_EVAL:
22598 switch (stage)
22599 {
22600 case Utils::Shader::FRAGMENT:
22601 source = fs;
22602 break;
22603 case Utils::Shader::TESS_CTRL:
22604 source = tcs;
22605 break;
22606 case Utils::Shader::VERTEX:
22607 source = vs;
22608 break;
22609 default:
22610 source = "";
22611 }
22612 break;
22613 case Utils::Shader::VERTEX:
22614 switch (stage)
22615 {
22616 case Utils::Shader::FRAGMENT:
22617 source = fs;
22618 break;
22619 default:
22620 source = "";
22621 }
22622 break;
22623 default:
22624 TCU_FAIL("Invalid enum");
22625 }
22626 }
22627
22628 return source;
22629 }
22630
22631 /** Get description of test case
22632 *
22633 * @param test_case_index Index of test case
22634 *
22635 * @return Test case description
22636 **/
22637 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index)
22638 {
22639 std::stringstream stream;
22640 testCase &test_case = m_test_cases[test_case_index];
22641
22642 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
22643
22644 switch (test_case.m_case)
22645 {
22646 case VALID:
22647 stream << "valid";
22648 break;
22649 case INVALID:
22650 stream << "invalid";
22651 break;
22652 default:
22653 TCU_FAIL("Invalid enum");
22654 }
22655
22656 return stream.str();
22657 }
22658
22659 /** Get number of test cases
22660 *
22661 * @return Number of test cases
22662 **/
22663 GLuint XFBDuplicatedStrideTest::getTestCaseNumber()
22664 {
22665 return static_cast<GLuint>(m_test_cases.size());
22666 }
22667
22668 /** Selects if "compute" stage is relevant for test
22669 *
22670 * @param ignored
22671 *
22672 * @return false
22673 **/
22674 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */)
22675 {
22676 return false;
22677 }
22678
22679 /** Selects if compilation failure is expected result
22680 *
22681 * @param test_case_index Index of test case
22682 *
22683 * @return true
22684 **/
22685 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index)
22686 {
22687 testCase &test_case = m_test_cases[test_case_index];
22688
22689 return (INVALID == test_case.m_case);
22690 }
22691
22692 /** Prepare all test cases
22693 *
22694 **/
22695 void XFBDuplicatedStrideTest::testInit()
22696 {
22697 for (GLuint c = 0; c < CASE_MAX; ++c)
22698 {
22699 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22700 {
22701 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22702 (Utils::Shader::FRAGMENT == stage))
22703 {
22704 continue;
22705 }
22706
22707 testCase test_case = {(CASES)c, (Utils::Shader::STAGES)stage};
22708
22709 m_test_cases.push_back(test_case);
22710 }
22711 }
22712 }
22713
22714 /** Constructor
22715 *
22716 * @param context Test framework context
22717 **/
22718 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context &context)
22719 : TestBase(context, "xfb_get_program_resource_api",
22720 "Test verifies that get program resource reports correct results for XFB")
22721 {
22722 }
22723
22724 /** Source for given test case and stage
22725 *
22726 * @param test_case_index Index of test case
22727 * @param stage Shader stage
22728 *
22729 * @return Shader source
22730 **/
22731 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22732 {
22733 static const GLchar *api_var_definition = "out TYPE b0_v1ARRAY;\n"
22734 "out TYPE b1_v1ARRAY;\n"
22735 "out TYPE b0_v3ARRAY;\n"
22736 "out TYPE b0_v0ARRAY;\n";
22737 static const GLchar *xfb_var_definition =
22738 "const uint type_size = SIZE;\n"
22739 "\n"
22740 "layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n"
22741 "\n"
22742 "layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n"
22743 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n"
22744 "layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n"
22745 "layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n";
22746 static const GLchar *var_use = " b0_v1INDEX = TYPE(0);\n"
22747 " b1_v1INDEX = TYPE(1);\n"
22748 " b0_v3INDEX = TYPE(0);\n"
22749 " b0_v0INDEX = TYPE(1);\n"
22750 " if (vec4(0) == result)\n"
22751 " {\n"
22752 " b0_v1INDEX = TYPE(1);\n"
22753 " b1_v1INDEX = TYPE(0);\n"
22754 " b0_v3INDEX = TYPE(1);\n"
22755 " b0_v0INDEX = TYPE(0);\n"
22756 " }\n";
22757 static const GLchar *gs_tested =
22758 "#version 430 core\n"
22759 "#extension GL_ARB_enhanced_layouts : require\n"
22760 "\n"
22761 "layout(points) in;\n"
22762 "layout(triangle_strip, max_vertices = 4) out;\n"
22763 "\n"
22764 "VAR_DEFINITION"
22765 "\n"
22766 "out gl_PerVertex \n"
22767 "{ \n"
22768 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
22769 "}; \n"
22770 "in vec4 tes_gs[];\n"
22771 "out vec4 gs_fs;\n"
22772 "\n"
22773 "void main()\n"
22774 "{\n"
22775 " vec4 result = tes_gs[0];\n"
22776 "\n"
22777 "VARIABLE_USE"
22778 "\n"
22779 " gs_fs = result;\n"
22780 " gl_Position = vec4(-1, -1, 0, 1);\n"
22781 " EmitVertex();\n"
22782 " gs_fs = result;\n"
22783 " gl_Position = vec4(-1, 1, 0, 1);\n"
22784 " EmitVertex();\n"
22785 " gs_fs = result;\n"
22786 " gl_Position = vec4(1, -1, 0, 1);\n"
22787 " EmitVertex();\n"
22788 " gs_fs = result;\n"
22789 " gl_Position = vec4(1, 1, 0, 1);\n"
22790 " EmitVertex();\n"
22791 "}\n"
22792 "\n";
22793 #if 0
22794 static const GLchar* tcs_tested =
22795 "#version 430 core\n"
22796 "#extension GL_ARB_enhanced_layouts : require\n"
22797 "\n"
22798 "layout(vertices = 1) out;\n"
22799 "\n"
22800 "VAR_DEFINITION"
22801 "\n"
22802 "in vec4 vs_tcs[];\n"
22803 "out vec4 tcs_tes[];\n"
22804 "\n"
22805 "void main()\n"
22806 "{\n"
22807 " vec4 result = vs_tcs[gl_InvocationID];\n"
22808 "\n"
22809 "VARIABLE_USE"
22810 "\n"
22811 " tcs_tes[gl_InvocationID] = result;\n"
22812 "\n"
22813 " gl_TessLevelOuter[0] = 1.0;\n"
22814 " gl_TessLevelOuter[1] = 1.0;\n"
22815 " gl_TessLevelOuter[2] = 1.0;\n"
22816 " gl_TessLevelOuter[3] = 1.0;\n"
22817 " gl_TessLevelInner[0] = 1.0;\n"
22818 " gl_TessLevelInner[1] = 1.0;\n"
22819 "}\n"
22820 "\n";
22821 #endif
22822 static const GLchar *tes_tested = "#version 430 core\n"
22823 "#extension GL_ARB_enhanced_layouts : require\n"
22824 "\n"
22825 "layout(isolines, point_mode) in;\n"
22826 "\n"
22827 "VAR_DEFINITION"
22828 "\n"
22829 "in vec4 tcs_tes[];\n"
22830 "out vec4 tes_gs;\n"
22831 "\n"
22832 "void main()\n"
22833 "{\n"
22834 " vec4 result = tcs_tes[0];\n"
22835 "\n"
22836 "VARIABLE_USE"
22837 "\n"
22838 " tes_gs = result;\n"
22839 "}\n"
22840 "\n";
22841 static const GLchar *vs_tested = "#version 430 core\n"
22842 "#extension GL_ARB_enhanced_layouts : require\n"
22843 "\n"
22844 "VAR_DEFINITION"
22845 "\n"
22846 "in vec4 in_vs;\n"
22847 "out vec4 vs_tcs;\n"
22848 "\n"
22849 "void main()\n"
22850 "{\n"
22851 " vec4 result = in_vs;\n"
22852 "\n"
22853 "VARIABLE_USE"
22854 "\n"
22855 " vs_tcs = result;\n"
22856 "}\n"
22857 "\n";
22858
22859 std::string source;
22860 const test_Case &test_case = m_test_cases[test_case_index];
22861
22862 if (test_case.m_stage == stage)
22863 {
22864 const GLchar *array = "";
22865 GLchar buffer[16];
22866 const GLchar *index = "";
22867 size_t position = 0;
22868 size_t temp;
22869 const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
22870 const GLchar *var_definition = 0;
22871
22872 sprintf(buffer, "%d", test_case.m_type.GetSize());
22873
22874 if (XFB == test_case.m_case)
22875 {
22876 var_definition = xfb_var_definition;
22877 }
22878 else
22879 {
22880 var_definition = api_var_definition;
22881 }
22882
22883 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22884 // change array = "[]" to "[1]"
22885 switch (stage)
22886 {
22887 case Utils::Shader::GEOMETRY:
22888 source = gs_tested;
22889 array = "[1]";
22890 index = "[0]";
22891 break;
22892 // It is invalid to output transform feedback varyings in tessellation control shader
22893 #if 0
22894 case Utils::Shader::TESS_CTRL:
22895 source = tcs_tested;
22896 array = "[]";
22897 index = "[gl_InvocationID]";
22898 break;
22899 #endif
22900 case Utils::Shader::TESS_EVAL:
22901 source = tes_tested;
22902 array = "[1]";
22903 index = "[0]";
22904 break;
22905 case Utils::Shader::VERTEX:
22906 source = vs_tested;
22907 break;
22908 default:
22909 TCU_FAIL("Invalid enum");
22910 }
22911
22912 temp = position;
22913 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22914 if (XFB == test_case.m_case)
22915 {
22916 position = temp;
22917 Utils::replaceToken("SIZE", position, buffer, source);
22918 }
22919 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22920
22921 Utils::replaceAllTokens("ARRAY", array, source);
22922 Utils::replaceAllTokens("INDEX", index, source);
22923 Utils::replaceAllTokens("TYPE", type_name, source);
22924 }
22925 else
22926 {
22927 source = "";
22928 }
22929
22930 return source;
22931 }
22932
22933 /** Get description of test case
22934 *
22935 * @param test_case_index Index of test case
22936 *
22937 * @return Test case description
22938 **/
22939 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index)
22940 {
22941 std::stringstream stream;
22942 const test_Case &test_case = m_test_cases[test_case_index];
22943
22944 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
22945 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
22946
22947 switch (test_case.m_case)
22948 {
22949 case INTERLEAVED:
22950 stream << "interleaved";
22951 break;
22952 case SEPARATED:
22953 stream << "separated";
22954 break;
22955 case XFB:
22956 stream << "xfb";
22957 break;
22958 default:
22959 TCU_FAIL("Invalid enum");
22960 }
22961
22962 return stream.str();
22963 }
22964
22965 /** Get number of test cases
22966 *
22967 * @return Number of test cases
22968 **/
22969 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber()
22970 {
22971 return static_cast<GLuint>(m_test_cases.size());
22972 }
22973
22974 /** Inspects program for offset, buffer index, buffer stride and type
22975 *
22976 * @param test_case_index Index of test case
22977 * @param program Program to query
22978 *
22979 * @return true if query results match expected values, false otherwise
22980 **/
22981 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program &program)
22982 {
22983 GLint b0_stride = 0;
22984 GLint b1_stride = 0;
22985 GLint b0_v0_buf = 0;
22986 GLint b0_v0_offset = 0;
22987 GLint b0_v0_type = 0;
22988 GLint b0_v1_buf = 0;
22989 GLint b0_v1_offset = 0;
22990 GLint b0_v1_type = 0;
22991 GLint b0_v3_buf = 0;
22992 GLint b0_v3_offset = 0;
22993 GLint b0_v3_type = 0;
22994 GLint b1_v1_buf = 0;
22995 GLint b1_v1_offset = 0;
22996 GLint b1_v1_type = 0;
22997 const test_Case &test_case = m_test_cases[test_case_index];
22998 const GLenum type_enum = test_case.m_type.GetTypeGLenum();
22999 const GLint type_size = test_case.m_type.GetSize();
23000
23001 GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING);
23002 GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING);
23003 GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING);
23004 GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING);
23005
23006 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset);
23007 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset);
23008 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset);
23009 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset);
23010
23011 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type);
23012 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type);
23013 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type);
23014 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type);
23015
23016 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23017 1 /* buf_size */, &b0_v0_buf);
23018 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23019 1 /* buf_size */, &b0_v1_buf);
23020 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23021 1 /* buf_size */, &b0_v3_buf);
23022 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23023 1 /* buf_size */, &b1_v1_buf);
23024
23025 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
23026 &b0_stride);
23027 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
23028 &b1_stride);
23029
23030 if (SEPARATED != test_case.m_case)
23031 {
23032 return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) &&
23033 ((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) &&
23034 ((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) &&
23035 ((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
23036 ((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) &&
23037 ((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) &&
23038 ((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
23039 }
23040 else
23041 {
23042 return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) &&
23043 ((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) &&
23044 ((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
23045 ((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) &&
23046 ((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
23047 }
23048 }
23049
23050 /** Insert gl_SkipComponents
23051 *
23052 * @param num_components How many gl_SkipComponents1 need to be inserted
23053 * @param varyings The transform feedback varyings string vector
23054 *
23055 **/
23056 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector &varyings)
23057 {
23058 int num_component_4 = num_components / 4;
23059 int num_component_1 = num_components % 4;
23060 for (int i = 0; i < num_component_4; i++)
23061 {
23062 varyings.push_back("gl_SkipComponents4");
23063 }
23064 switch (num_component_1)
23065 {
23066 case 1:
23067 varyings.push_back("gl_SkipComponents1");
23068 break;
23069 case 2:
23070 varyings.push_back("gl_SkipComponents2");
23071 break;
23072 case 3:
23073 varyings.push_back("gl_SkipComponents3");
23074 break;
23075 default:
23076 break;
23077 }
23078 }
23079
23080 /** Runs test case
23081 *
23082 * @param test_case_index Id of test case
23083 *
23084 * @return true if test case pass, false otherwise
23085 **/
23086 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index)
23087 {
23088 const std::string &gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
23089 Utils::Program program(m_context);
23090 const std::string &tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
23091 const std::string &tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
23092 const test_Case &test_case = m_test_cases[test_case_index];
23093 bool test_case_result = true;
23094 const std::string &vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
23095
23096 // According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values.
23097 // No data will be recorded for such strings, but the offset assigned to the next variable in varyings and the stride of the assigned bingding point will be affected.
23098
23099 if (INTERLEAVED == test_case.m_case)
23100 {
23101 /*
23102 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
23103 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
23104 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
23105 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
23106
23107 Note: the type can be float, double, mat2, mat3x2, dmat2, dmat3x2..., so to make the each variable of "captured_varyings" has the same xfb_offset with the above shaders,
23108 we need to calculate how many "gl_SkipComponents" need to be inserted.
23109 */
23110 Utils::Program::NameVector captured_varyings;
23111 captured_varyings.push_back("b0_v0");
23112 captured_varyings.push_back("b0_v1");
23113 // Compute how many gl_SkipComponents to be inserted
23114 int numComponents = test_case.m_type.GetSize() / 4;
23115 insertSkipComponents(numComponents, captured_varyings);
23116 captured_varyings.push_back("b0_v3");
23117 captured_varyings.push_back("gl_NextBuffer");
23118 insertSkipComponents(numComponents, captured_varyings);
23119 captured_varyings.push_back("b1_v1");
23120 insertSkipComponents(numComponents * 2, captured_varyings);
23121
23122 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true,
23123 true /* separable */);
23124 }
23125 else if (SEPARATED == test_case.m_case)
23126 {
23127 Utils::Program::NameVector captured_varyings;
23128
23129 captured_varyings.push_back("b0_v0");
23130 captured_varyings.push_back("b0_v1");
23131 captured_varyings.push_back("b0_v3");
23132 captured_varyings.push_back("b1_v1");
23133
23134 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false,
23135 true /* separable */);
23136 }
23137 else
23138 {
23139
23140 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
23141 }
23142
23143 test_case_result = inspectProgram(test_case_index, program);
23144
23145 return test_case_result;
23146 }
23147
23148 /** Prepare all test cases
23149 *
23150 **/
23151 void XFBGetProgramResourceAPITest::testInit()
23152 {
23153 const Functions &gl = m_context.getRenderContext().getFunctions();
23154 const GLuint n_types = getTypesNumber();
23155 GLint max_xfb_int;
23156 GLint max_xfb_sep;
23157
23158 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
23159 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23160
23161 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep);
23162 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23163
23164 GLint max_varyings;
23165 gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings);
23166
23167 for (GLuint i = 0; i < n_types; ++i)
23168 {
23169 // When i == 7, the type is dmat4, i == 9 the type is dmat4x3, the number of output components exceeds the maximum value that AMD's driver supported,
23170 // the MAX_VARYING_COMPONENTS is 32 in our driver, but when the variable type is dmat4 or dmat4x3, the number of output component is 33, to make the
23171 // shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader
23172 // to guarantee the number of varying not exceeded.
23173 /*
23174 layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;
23175 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
23176 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
23177 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
23178 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
23179 in vec4 in_vs;
23180 out vec4 vs_tcs;
23181 */
23182 if (i == 7 || i == 9)
23183 continue;
23184 const Utils::Type &type = getType(i);
23185 if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings)
23186 {
23187 continue;
23188 }
23189 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23190 {
23191 /*
23192 It is invalid to define transform feedback output in HS
23193 */
23194 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23195 (Utils::Shader::FRAGMENT == stage))
23196 {
23197 continue;
23198 }
23199
23200 test_Case test_case_int = {INTERLEAVED, (Utils::Shader::STAGES)stage, type};
23201 test_Case test_case_sep = {SEPARATED, (Utils::Shader::STAGES)stage, type};
23202 test_Case test_case_xfb = {XFB, (Utils::Shader::STAGES)stage, type};
23203
23204 if ((int)type.GetSize() <= max_xfb_int)
23205 {
23206 m_test_cases.push_back(test_case_xfb);
23207 m_test_cases.push_back(test_case_int);
23208 }
23209
23210 if ((int)type.GetSize() <= max_xfb_sep)
23211 {
23212 m_test_cases.push_back(test_case_sep);
23213 }
23214 }
23215 }
23216 }
23217
23218 /** Constructor
23219 *
23220 * @param context Test context
23221 **/
23222 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context &context)
23223 : BufferTestBase(context, "xfb_override_qualifiers_with_api",
23224 "Test verifies that xfb_offset qualifier is not overriden with API")
23225 {
23226 /* Nothing to be done here */
23227 }
23228
23229 /** Get descriptors of buffers necessary for test
23230 *
23231 * @param test_case_index Index of test case
23232 * @param out_descriptors Descriptors of buffers used by test
23233 **/
23234 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint test_case_index,
23235 bufferDescriptor::Vector &out_descriptors)
23236 {
23237 const Utils::Type &type = getType(test_case_index);
23238
23239 /* Test needs single uniform and xfb */
23240 out_descriptors.resize(2);
23241
23242 /* Get references */
23243 bufferDescriptor &uniform = out_descriptors[0];
23244 bufferDescriptor &xfb = out_descriptors[1];
23245
23246 /* Index */
23247 uniform.m_index = 0;
23248 xfb.m_index = 0;
23249
23250 /* Target */
23251 uniform.m_target = Utils::Buffer::Uniform;
23252 xfb.m_target = Utils::Buffer::Transform_feedback;
23253
23254 /* Data */
23255 const GLuint gen_start = Utils::s_rand;
23256 const std::vector<GLubyte> &vegeta_data = type.GenerateData();
23257 const std::vector<GLubyte> &trunks_data = type.GenerateData();
23258 const std::vector<GLubyte> &goku_data = type.GenerateData();
23259
23260 Utils::s_rand = gen_start;
23261 const std::vector<GLubyte> &vegeta_data_pck = type.GenerateDataPacked();
23262 type.GenerateDataPacked(); // generate the data for trunks
23263 const std::vector<GLubyte> &goku_data_pck = type.GenerateDataPacked();
23264
23265 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
23266 const GLuint padded_type_size = type.GetBaseAlignment(false) * type.m_n_columns;
23267 const GLuint type_size_pck = static_cast<GLuint>(vegeta_data_pck.size());
23268
23269 /* Uniform data */
23270 uniform.m_initial_data.resize(3 * padded_type_size);
23271 memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size);
23272 memcpy(&uniform.m_initial_data[0] + padded_type_size, &trunks_data[0], type_size);
23273 memcpy(&uniform.m_initial_data[0] + 2 * padded_type_size, &goku_data[0], type_size);
23274
23275 /* XFB data */
23276 xfb.m_initial_data.resize(3 * type_size_pck);
23277 xfb.m_expected_data.resize(3 * type_size_pck);
23278
23279 for (GLuint i = 0; i < 3 * type_size_pck; ++i)
23280 {
23281 xfb.m_initial_data[i] = (glw::GLubyte)i;
23282 xfb.m_expected_data[i] = (glw::GLubyte)i;
23283 }
23284
23285 memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck);
23286 memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck);
23287 }
23288
23289 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
23290 *
23291 * @param ignored
23292 * @param captured_varyings List of names
23293 **/
23294 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint test_case_index,
23295 Utils::Program::NameVector &captured_varyings,
23296 GLint *xfb_components)
23297 {
23298 captured_varyings.resize(1);
23299
23300 captured_varyings[0] = "trunks";
23301
23302 /* The test captures 3 varyings of type 'type' */
23303 Utils::Type type = getType(test_case_index);
23304 GLint type_size = type.GetSize(false);
23305 *xfb_components = 3 * type_size / 4;
23306 }
23307
23308 /** Get body of main function for given shader stage
23309 *
23310 * @param test_case_index Index of test case
23311 * @param stage Shader stage
23312 * @param out_assignments Set to empty
23313 * @param out_calculations Set to empty
23314 **/
23315 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
23316 std::string &out_assignments, std::string &out_calculations)
23317 {
23318 out_calculations = "";
23319
23320 static const GLchar *gs = " vegeta = uni_vegeta;\n"
23321 " trunks = uni_trunks;\n"
23322 " goku = uni_goku;\n";
23323 static const GLchar *fs = " fs_out = vec4(0);\n"
23324 " if (TYPE(1) == goku + trunks + vegeta)\n"
23325 " {\n"
23326 " fs_out = vec4(1);\n"
23327 " }\n";
23328
23329 const GLchar *assignments = "";
23330 switch (stage)
23331 {
23332 case Utils::Shader::FRAGMENT:
23333 assignments = fs;
23334 break;
23335 case Utils::Shader::GEOMETRY:
23336 assignments = gs;
23337 break;
23338 default:
23339 break;
23340 }
23341
23342 out_assignments = assignments;
23343
23344 if (Utils::Shader::FRAGMENT == stage)
23345 {
23346 const Utils::Type &type = getType(test_case_index);
23347
23348 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments);
23349 }
23350 }
23351
23352 /** Get interface of shader
23353 *
23354 * @param test_case_index Index of test case
23355 * @param stage Shader stage
23356 * @param out_interface Set to ""
23357 **/
23358 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
23359 std::string &out_interface)
23360 {
23361 static const GLchar *gs =
23362 "const uint sizeof_type = SIZE;\n"
23363 "\n"
23364 "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n"
23365 " flat out TYPE trunks;\n"
23366 "layout (xfb_offset = 0) flat out TYPE goku;\n"
23367 "\n"
23368 /*
23369 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default,
23370 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will
23371 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API
23372 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the
23373 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed,
23374 we need to add the qualifier std140, and change the declaration as layout(binding=0, std140), which can make
23375 sure all the block members are packed and the application can upload the data by glBufferData() directly.
23376 */
23377 "layout(binding = 0, std140) uniform gs_block {\n"
23378 " TYPE uni_vegeta;\n"
23379 " TYPE uni_trunks;\n"
23380 " TYPE uni_goku;\n"
23381 "};\n";
23382 static const GLchar *fs = "flat in TYPE vegeta;\n"
23383 "flat in TYPE trunks;\n"
23384 "flat in TYPE goku;\n"
23385 "\n"
23386 "out vec4 fs_out;\n";
23387
23388 const Utils::Type &type = getType(test_case_index);
23389
23390 switch (stage)
23391 {
23392 case Utils::Shader::FRAGMENT:
23393 out_interface = fs;
23394 break;
23395 case Utils::Shader::GEOMETRY:
23396 out_interface = gs;
23397 break;
23398 default:
23399 out_interface = "";
23400 return;
23401 }
23402
23403 if (Utils::Shader::GEOMETRY == stage)
23404 {
23405 GLchar buffer[16];
23406 size_t position = 0;
23407 const GLuint type_size = type.GetSize();
23408
23409 sprintf(buffer, "%d", type_size);
23410
23411 Utils::replaceToken("SIZE", position, buffer, out_interface);
23412 }
23413
23414 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface);
23415 }
23416
23417 /** Get type name
23418 *
23419 * @param test_case_index Index of test case
23420 *
23421 * @return Name of type test in test_case_index
23422 **/
23423 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index)
23424 {
23425 return getTypeName(test_case_index);
23426 }
23427
23428 /** Returns number of types to test
23429 *
23430 * @return Number of types, 34
23431 **/
23432 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber()
23433 {
23434 return getTypesNumber();
23435 }
23436
23437 /** Inspects program to check if all resources are as expected
23438 *
23439 * @param test_case_index Index of test case
23440 * @param program Program instance
23441 * @param out_stream Error message
23442 *
23443 * @return true if everything is ok, false otherwise
23444 **/
23445 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program &program,
23446 std::stringstream &out_stream)
23447 {
23448 GLint stride = 0;
23449 const Utils::Type &type = getType(test_case_index);
23450 const GLuint type_size = type.GetSize(false);
23451
23452 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
23453 1 /* buf_size */, &stride);
23454
23455 if ((GLint)(3 * type_size) != stride)
23456 {
23457 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
23458
23459 return false;
23460 }
23461
23462 return true;
23463 }
23464
23465 /** Constructor
23466 *
23467 * @param context Test context
23468 **/
23469 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context &context)
23470 : BufferTestBase(context, "xfb_vertex_streams",
23471 "Test verifies that xfb qualifier works with multiple output streams")
23472 {
23473 /* Nothing to be done here */
23474 }
23475
23476 /** Get descriptors of buffers necessary for test
23477 *
23478 * @param ignored
23479 * @param out_descriptors Descriptors of buffers used by test
23480 **/
23481 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
23482 bufferDescriptor::Vector &out_descriptors)
23483 {
23484 const Utils::Type &type = Utils::Type::vec4;
23485
23486 /* Test needs single uniform and three xfbs */
23487 out_descriptors.resize(4);
23488
23489 /* Get references */
23490 bufferDescriptor &uniform = out_descriptors[0];
23491 bufferDescriptor &xfb_1 = out_descriptors[1];
23492 bufferDescriptor &xfb_2 = out_descriptors[2];
23493 bufferDescriptor &xfb_3 = out_descriptors[3];
23494
23495 /* Index */
23496 uniform.m_index = 0;
23497 xfb_1.m_index = 1;
23498 xfb_2.m_index = 2;
23499 xfb_3.m_index = 3;
23500
23501 /* Target */
23502 uniform.m_target = Utils::Buffer::Uniform;
23503 xfb_1.m_target = Utils::Buffer::Transform_feedback;
23504 xfb_2.m_target = Utils::Buffer::Transform_feedback;
23505 xfb_3.m_target = Utils::Buffer::Transform_feedback;
23506
23507 /* Data */
23508 const std::vector<GLubyte> &goku_data = type.GenerateData();
23509 const std::vector<GLubyte> &gohan_data = type.GenerateData();
23510 const std::vector<GLubyte> &goten_data = type.GenerateData();
23511 const std::vector<GLubyte> &picolo_data = type.GenerateData();
23512 const std::vector<GLubyte> &vegeta_data = type.GenerateData();
23513 const std::vector<GLubyte> &bulma_data = type.GenerateData();
23514
23515 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
23516
23517 /* Uniform data */
23518 uniform.m_initial_data.resize(6 * type_size);
23519 memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size);
23520 memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size);
23521 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
23522 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size);
23523 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
23524 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size);
23525
23526 /* XFB data */
23527 static const GLuint xfb_stride = 64;
23528 xfb_1.m_initial_data.resize(xfb_stride);
23529 xfb_1.m_expected_data.resize(xfb_stride);
23530 xfb_2.m_initial_data.resize(xfb_stride);
23531 xfb_2.m_expected_data.resize(xfb_stride);
23532 xfb_3.m_initial_data.resize(xfb_stride);
23533 xfb_3.m_expected_data.resize(xfb_stride);
23534
23535 for (GLuint i = 0; i < xfb_stride; ++i)
23536 {
23537 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
23538 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
23539 xfb_2.m_initial_data[i] = (glw::GLubyte)i;
23540 xfb_2.m_expected_data[i] = (glw::GLubyte)i;
23541 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
23542 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
23543 }
23544
23545 memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size);
23546 memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size);
23547 memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size);
23548 memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size);
23549 memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size);
23550 memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size);
23551 }
23552
23553 /** Get body of main function for given shader stage
23554 *
23555 * @param ignored
23556 * @param stage Shader stage
23557 * @param out_assignments Set to empty
23558 * @param out_calculations Set to empty
23559 **/
23560 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23561 std::string &out_assignments, std::string &out_calculations)
23562 {
23563 out_calculations = "";
23564
23565 // the shader declares the output variables with different "stream" qualifier, to make the data can export to
23566 // each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted
23567 // by the GS is assigned to specific stream.
23568 static const GLchar *gs = " goku = uni_goku;\n"
23569 " gohan = uni_gohan;\n"
23570 " goten = uni_goten;\n"
23571 " EmitStreamVertex(0);\n"
23572 " EndStreamPrimitive(0);\n"
23573 " picolo = uni_picolo;\n"
23574 " vegeta = uni_vegeta;\n"
23575 " EmitStreamVertex(1);\n"
23576 " EndStreamPrimitive(1);\n"
23577 " bulma = uni_bulma;\n"
23578 " EmitStreamVertex(2);\n"
23579 " EndStreamPrimitive(2);\n";
23580
23581 static const GLchar *fs = " fs_out = gohan + goku + goten;\n";
23582
23583 const GLchar *assignments = "";
23584 switch (stage)
23585 {
23586 case Utils::Shader::FRAGMENT:
23587 assignments = fs;
23588 break;
23589 case Utils::Shader::GEOMETRY:
23590 assignments = gs;
23591 break;
23592 default:
23593 break;
23594 }
23595
23596 out_assignments = assignments;
23597 }
23598
23599 /** Get interface of shader
23600 *
23601 * @param ignored
23602 * @param stage Shader stage
23603 * @param out_interface Set to ""
23604 **/
23605 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23606 std::string &out_interface)
23607 {
23608 static const GLchar *gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
23609 "layout (xfb_buffer = 2, xfb_stride = 64) out;\n"
23610 "layout (xfb_buffer = 3, xfb_stride = 64) out;\n"
23611 "\n"
23612 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23613 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23614 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"
23615 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n"
23616 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n"
23617 "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n"
23618 "\n"
23619 "layout(binding = 0) uniform gs_block {\n"
23620 " vec4 uni_goku;\n"
23621 " vec4 uni_gohan;\n"
23622 " vec4 uni_goten;\n"
23623 " vec4 uni_picolo;\n"
23624 " vec4 uni_vegeta;\n"
23625 " vec4 uni_bulma;\n"
23626 "};\n";
23627 /*
23628 Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader
23629 */
23630 static const GLchar *fs = "in vec4 goku;\n"
23631 "in vec4 gohan;\n"
23632 "in vec4 goten;\n"
23633 "\n"
23634 "out vec4 fs_out;\n";
23635
23636 switch (stage)
23637 {
23638 case Utils::Shader::FRAGMENT:
23639 out_interface = fs;
23640 break;
23641 case Utils::Shader::GEOMETRY:
23642 out_interface = gs;
23643 break;
23644 default:
23645 out_interface = "";
23646 return;
23647 }
23648 }
23649
23650 /** Constructor
23651 *
23652 * @param context Test framework context
23653 **/
23654 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context &context)
23655 : NegativeTestBase(
23656 context, "xfb_multiple_vertex_streams",
23657 "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer")
23658 {
23659 }
23660
23661 /** Source for given test case and stage
23662 *
23663 * @param ignored
23664 * @param stage Shader stage
23665 *
23666 * @return Shader source
23667 **/
23668 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage)
23669 {
23670 static const GLchar *var_definition = "const uint valid_stride = 64;\n"
23671 "\n"
23672 "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n"
23673 "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n"
23674 "\n"
23675 "\n"
23676 #if DEBUG_NEG_REMOVE_ERROR
23677 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23678 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 gohan;\n"
23679 "layout (stream = 2, xfb_buffer = 2, xfb_offset = 16) out vec4 goten;\n";
23680 #else
23681 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23682 "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23683 "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n";
23684 #endif /* DEBUG_NEG_REMOVE_ERROR */
23685 static const GLchar *var_use = " goku = result / 2;\n"
23686 " gohan = result / 4;\n"
23687 " goten = result / 6;\n";
23688 static const GLchar *fs = "#version 430 core\n"
23689 "#extension GL_ARB_enhanced_layouts : require\n"
23690 "\n"
23691 "in vec4 gs_fs;\n"
23692 "in vec4 goku;\n"
23693 "out vec4 fs_out;\n"
23694 "\n"
23695 "void main()\n"
23696 "{\n"
23697 " fs_out = gs_fs + goku;\n"
23698 "}\n"
23699 "\n";
23700 static const GLchar *gs = "#version 430 core\n"
23701 "#extension GL_ARB_enhanced_layouts : require\n"
23702 "\n"
23703 "layout(points) in;\n"
23704 "layout(triangle_strip, max_vertices = 4) out;\n"
23705 "\n"
23706 "VAR_DEFINITION"
23707 "\n"
23708 "in vec4 vs_gs[];\n"
23709 "out vec4 gs_fs;\n"
23710 "\n"
23711 "void main()\n"
23712 "{\n"
23713 " vec4 result = vs_gs[0];\n"
23714 "\n"
23715 "VARIABLE_USE"
23716 "\n"
23717 " gs_fs = result;\n"
23718 " gl_Position = vec4(-1, -1, 0, 1);\n"
23719 " EmitVertex();\n"
23720 " gs_fs = result;\n"
23721 " gl_Position = vec4(-1, 1, 0, 1);\n"
23722 " EmitVertex();\n"
23723 " gs_fs = result;\n"
23724 " gl_Position = vec4(1, -1, 0, 1);\n"
23725 " EmitVertex();\n"
23726 " gs_fs = result;\n"
23727 " gl_Position = vec4(1, 1, 0, 1);\n"
23728 " EmitVertex();\n"
23729 "}\n"
23730 "\n";
23731 static const GLchar *vs = "#version 430 core\n"
23732 "#extension GL_ARB_enhanced_layouts : require\n"
23733 "\n"
23734 "in vec4 in_vs;\n"
23735 "out vec4 vs_gs;\n"
23736 "\n"
23737 "void main()\n"
23738 "{\n"
23739 " vs_gs = in_vs;\n"
23740 "}\n"
23741 "\n";
23742
23743 std::string source;
23744
23745 if (Utils::Shader::GEOMETRY == stage)
23746 {
23747 size_t position = 0;
23748
23749 source = gs;
23750
23751 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23752 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23753 }
23754 else
23755 {
23756 switch (stage)
23757 {
23758 case Utils::Shader::FRAGMENT:
23759 source = fs;
23760 break;
23761 case Utils::Shader::VERTEX:
23762 source = vs;
23763 break;
23764 default:
23765 source = "";
23766 }
23767 }
23768
23769 return source;
23770 }
23771
23772 /** Selects if "compute" stage is relevant for test
23773 *
23774 * @param ignored
23775 *
23776 * @return false
23777 **/
23778 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */)
23779 {
23780 return false;
23781 }
23782
23783 /** Constructor
23784 *
23785 * @param context Test framework context
23786 **/
23787 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context &context)
23788 : NegativeTestBase(context, "xfb_exceed_buffer_limit",
23789 "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit")
23790 {
23791 }
23792
23793 /** Source for given test case and stage
23794 *
23795 * @param test_case_index Index of test case
23796 * @param stage Shader stage
23797 *
23798 * @return Shader source
23799 **/
23800 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23801 {
23802 static const GLchar *block_var_definition = "const uint buffer_index = MAX_BUFFER;\n"
23803 "\n"
23804 #if DEBUG_NEG_REMOVE_ERROR
23805 "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
23806 #else
23807 "layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n"
23808 #endif /* DEBUG_NEG_REMOVE_ERROR */
23809 " vec4 member;\n"
23810 "} goku;\n";
23811 static const GLchar *global_var_definition = "const uint buffer_index = MAX_BUFFER;\n"
23812 "\n"
23813 #if DEBUG_NEG_REMOVE_ERROR
23814 "layout (xfb_buffer = 0) out;\n";
23815 #else
23816 "layout (xfb_buffer = buffer_index) out;\n";
23817 #endif /* DEBUG_NEG_REMOVE_ERROR */
23818 static const GLchar *vector_var_definition = "const uint buffer_index = MAX_BUFFER;\n"
23819 "\n"
23820 #if DEBUG_NEG_REMOVE_ERROR
23821 "layout (xfb_buffer = 0) out vec4 goku;\n";
23822 #else
23823 "layout (xfb_buffer = buffer_index) out vec4 goku;\n";
23824 #endif /* DEBUG_NEG_REMOVE_ERROR */
23825 static const GLchar *block_use = " goku.member = result / 2;\n";
23826 static const GLchar *global_use = "";
23827 static const GLchar *vector_use = " goku = result / 2;\n";
23828 static const GLchar *fs = "#version 430 core\n"
23829 "#extension GL_ARB_enhanced_layouts : require\n"
23830 "\n"
23831 "in vec4 any_fs;\n"
23832 "out vec4 fs_out;\n"
23833 "\n"
23834 "void main()\n"
23835 "{\n"
23836 " fs_out = any_fs;\n"
23837 "}\n"
23838 "\n";
23839 static const GLchar *gs_tested = "#version 430 core\n"
23840 "#extension GL_ARB_enhanced_layouts : require\n"
23841 "\n"
23842 "layout(points) in;\n"
23843 "layout(triangle_strip, max_vertices = 4) out;\n"
23844 "\n"
23845 "VAR_DEFINITION"
23846 "\n"
23847 "in vec4 vs_any[];\n"
23848 "out vec4 any_fs;\n"
23849 "\n"
23850 "void main()\n"
23851 "{\n"
23852 " vec4 result = vs_any[0];\n"
23853 "\n"
23854 "VARIABLE_USE"
23855 "\n"
23856 " any_fs = result;\n"
23857 " gl_Position = vec4(-1, -1, 0, 1);\n"
23858 " EmitVertex();\n"
23859 " any_fs = result;\n"
23860 " gl_Position = vec4(-1, 1, 0, 1);\n"
23861 " EmitVertex();\n"
23862 " any_fs = result;\n"
23863 " gl_Position = vec4(1, -1, 0, 1);\n"
23864 " EmitVertex();\n"
23865 " any_fs = result;\n"
23866 " gl_Position = vec4(1, 1, 0, 1);\n"
23867 " EmitVertex();\n"
23868 "}\n"
23869 "\n";
23870 static const GLchar *tcs = "#version 430 core\n"
23871 "#extension GL_ARB_enhanced_layouts : require\n"
23872 "\n"
23873 "layout(vertices = 1) out;\n"
23874 "\n"
23875 "in vec4 vs_any[];\n"
23876 "out vec4 tcs_tes[];\n"
23877 "\n"
23878 "void main()\n"
23879 "{\n"
23880 "\n"
23881 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
23882 "\n"
23883 " gl_TessLevelOuter[0] = 1.0;\n"
23884 " gl_TessLevelOuter[1] = 1.0;\n"
23885 " gl_TessLevelOuter[2] = 1.0;\n"
23886 " gl_TessLevelOuter[3] = 1.0;\n"
23887 " gl_TessLevelInner[0] = 1.0;\n"
23888 " gl_TessLevelInner[1] = 1.0;\n"
23889 "}\n"
23890 "\n";
23891 static const GLchar *tes_tested = "#version 430 core\n"
23892 "#extension GL_ARB_enhanced_layouts : require\n"
23893 "\n"
23894 "layout(isolines, point_mode) in;\n"
23895 "\n"
23896 "VAR_DEFINITION"
23897 "\n"
23898 "in vec4 tcs_tes[];\n"
23899 "out vec4 any_fs;\n"
23900 "\n"
23901 "void main()\n"
23902 "{\n"
23903 " vec4 result = tcs_tes[0];\n"
23904 "\n"
23905 "VARIABLE_USE"
23906 "\n"
23907 " any_fs += result;\n"
23908 "}\n"
23909 "\n";
23910 static const GLchar *vs = "#version 430 core\n"
23911 "#extension GL_ARB_enhanced_layouts : require\n"
23912 "\n"
23913 "in vec4 in_vs;\n"
23914 "out vec4 vs_any;\n"
23915 "\n"
23916 "void main()\n"
23917 "{\n"
23918 " vs_any = in_vs;\n"
23919 "}\n"
23920 "\n";
23921 static const GLchar *vs_tested = "#version 430 core\n"
23922 "#extension GL_ARB_enhanced_layouts : require\n"
23923 "\n"
23924 "VAR_DEFINITION"
23925 "\n"
23926 "in vec4 in_vs;\n"
23927 "out vec4 any_fs;\n"
23928 "\n"
23929 "void main()\n"
23930 "{\n"
23931 " vec4 result = in_vs;\n"
23932 "\n"
23933 "VARIABLE_USE"
23934 "\n"
23935 " any_fs = result;\n"
23936 "}\n"
23937 "\n";
23938
23939 std::string source;
23940 testCase &test_case = m_test_cases[test_case_index];
23941
23942 if (test_case.m_stage == stage)
23943 {
23944 GLchar buffer[16];
23945 const Functions &gl = m_context.getRenderContext().getFunctions();
23946 GLint max_n_xfb = 0;
23947 size_t position = 0;
23948 const GLchar *var_definition = 0;
23949 const GLchar *var_use = 0;
23950
23951 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb);
23952 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23953
23954 sprintf(buffer, "%d", max_n_xfb);
23955
23956 switch (test_case.m_case)
23957 {
23958 case BLOCK:
23959 var_definition = block_var_definition;
23960 var_use = block_use;
23961 break;
23962 case GLOBAL:
23963 var_definition = global_var_definition;
23964 var_use = global_use;
23965 break;
23966 case VECTOR:
23967 var_definition = vector_var_definition;
23968 var_use = vector_use;
23969 break;
23970 default:
23971 TCU_FAIL("Invalid enum");
23972 }
23973
23974 switch (stage)
23975 {
23976 case Utils::Shader::GEOMETRY:
23977 source = gs_tested;
23978 break;
23979 case Utils::Shader::TESS_EVAL:
23980 source = tes_tested;
23981 break;
23982 case Utils::Shader::VERTEX:
23983 source = vs_tested;
23984 break;
23985 default:
23986 TCU_FAIL("Invalid enum");
23987 }
23988
23989 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23990 position = 0;
23991 Utils::replaceToken("MAX_BUFFER", position, buffer, source);
23992 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23993 }
23994 else
23995 {
23996 switch (test_case.m_stage)
23997 {
23998 case Utils::Shader::GEOMETRY:
23999 switch (stage)
24000 {
24001 case Utils::Shader::FRAGMENT:
24002 source = fs;
24003 break;
24004 case Utils::Shader::VERTEX:
24005 source = vs;
24006 break;
24007 default:
24008 source = "";
24009 }
24010 break;
24011 case Utils::Shader::TESS_EVAL:
24012 switch (stage)
24013 {
24014 case Utils::Shader::FRAGMENT:
24015 source = fs;
24016 break;
24017 case Utils::Shader::TESS_CTRL:
24018 source = tcs;
24019 break;
24020 case Utils::Shader::VERTEX:
24021 source = vs;
24022 break;
24023 default:
24024 source = "";
24025 }
24026 break;
24027 case Utils::Shader::VERTEX:
24028 switch (stage)
24029 {
24030 case Utils::Shader::FRAGMENT:
24031 source = fs;
24032 break;
24033 default:
24034 source = "";
24035 }
24036 break;
24037 default:
24038 TCU_FAIL("Invalid enum");
24039 }
24040 }
24041
24042 return source;
24043 }
24044
24045 /** Get description of test case
24046 *
24047 * @param test_case_index Index of test case
24048 *
24049 * @return Test case description
24050 **/
24051 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index)
24052 {
24053 std::stringstream stream;
24054 testCase &test_case = m_test_cases[test_case_index];
24055
24056 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
24057
24058 switch (test_case.m_case)
24059 {
24060 case BLOCK:
24061 stream << "BLOCK";
24062 break;
24063 case GLOBAL:
24064 stream << "GLOBAL";
24065 break;
24066 case VECTOR:
24067 stream << "VECTOR";
24068 break;
24069 default:
24070 TCU_FAIL("Invalid enum");
24071 }
24072
24073 return stream.str();
24074 }
24075
24076 /** Get number of test cases
24077 *
24078 * @return Number of test cases
24079 **/
24080 GLuint XFBExceedBufferLimitTest::getTestCaseNumber()
24081 {
24082 return static_cast<GLuint>(m_test_cases.size());
24083 }
24084
24085 /** Selects if "compute" stage is relevant for test
24086 *
24087 * @param ignored
24088 *
24089 * @return false
24090 **/
24091 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */)
24092 {
24093 return false;
24094 }
24095
24096 /** Prepare all test cases
24097 *
24098 **/
24099 void XFBExceedBufferLimitTest::testInit()
24100 {
24101 for (GLuint c = 0; c < CASE_MAX; ++c)
24102 {
24103 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24104 {
24105 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24106 (Utils::Shader::FRAGMENT == stage))
24107 {
24108 continue;
24109 }
24110
24111 testCase test_case = {(CASES)c, (Utils::Shader::STAGES)stage};
24112
24113 m_test_cases.push_back(test_case);
24114 }
24115 }
24116 }
24117
24118 /** Constructor
24119 *
24120 * @param context Test framework context
24121 **/
24122 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context &context)
24123 : NegativeTestBase(context, "xfb_exceed_offset_limit",
24124 "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit")
24125 {
24126 }
24127
24128 /** Source for given test case and stage
24129 *
24130 * @param test_case_index Index of test case
24131 * @param stage Shader stage
24132 *
24133 * @return Shader source
24134 **/
24135 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24136 {
24137 static const GLchar *block_var_definition = "const uint overflow_offset = MAX_SIZE + 16;\n"
24138 "\n"
24139 #if DEBUG_NEG_REMOVE_ERROR
24140 "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
24141 #else
24142 "layout (xfb_buffer = 0, xfb_offset = overflow_offset + 16) out Goku "
24143 "{\n"
24144 #endif /* DEBUG_NEG_REMOVE_ERROR */
24145 " vec4 member;\n"
24146 "} goku;\n";
24147 static const GLchar *global_var_definition = "const uint overflow_offset = MAX_SIZE + 16;\n"
24148 "\n"
24149 #if DEBUG_NEG_REMOVE_ERROR
24150 "layout (xfb_buffer = 0, xfb_stride = 0) out;\n";
24151 #else
24152 "layout (xfb_buffer = 0, xfb_stride = overflow_offset) out;\n";
24153 #endif /* DEBUG_NEG_REMOVE_ERROR */
24154 static const GLchar *vector_var_definition = "const uint overflow_offset = MAX_SIZE + 16;\n"
24155 "\n"
24156 #if DEBUG_NEG_REMOVE_ERROR
24157 "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 goku;\n";
24158 #else
24159 "layout (xfb_buffer = 0, xfb_offset = overflow_offset) out vec4 "
24160 "goku;\n";
24161 #endif /* DEBUG_NEG_REMOVE_ERROR */
24162 static const GLchar *block_use = " goku.member = result / 2;\n";
24163 static const GLchar *global_use = "";
24164 static const GLchar *vector_use = " goku = result / 2;\n";
24165 static const GLchar *fs = "#version 430 core\n"
24166 "#extension GL_ARB_enhanced_layouts : require\n"
24167 "\n"
24168 "in vec4 any_fs;\n"
24169 "out vec4 fs_out;\n"
24170 "\n"
24171 "void main()\n"
24172 "{\n"
24173 " fs_out = any_fs;\n"
24174 "}\n"
24175 "\n";
24176 static const GLchar *gs_tested = "#version 430 core\n"
24177 "#extension GL_ARB_enhanced_layouts : require\n"
24178 "\n"
24179 "layout(points) in;\n"
24180 "layout(triangle_strip, max_vertices = 4) out;\n"
24181 "\n"
24182 "VAR_DEFINITION"
24183 "\n"
24184 "in vec4 vs_any[];\n"
24185 "out vec4 any_fs;\n"
24186 "\n"
24187 "void main()\n"
24188 "{\n"
24189 " vec4 result = vs_any[0];\n"
24190 "\n"
24191 "VARIABLE_USE"
24192 "\n"
24193 " any_fs = result;\n"
24194 " gl_Position = vec4(-1, -1, 0, 1);\n"
24195 " EmitVertex();\n"
24196 " any_fs = result;\n"
24197 " gl_Position = vec4(-1, 1, 0, 1);\n"
24198 " EmitVertex();\n"
24199 " any_fs = result;\n"
24200 " gl_Position = vec4(1, -1, 0, 1);\n"
24201 " EmitVertex();\n"
24202 " any_fs = result;\n"
24203 " gl_Position = vec4(1, 1, 0, 1);\n"
24204 " EmitVertex();\n"
24205 "}\n"
24206 "\n";
24207 static const GLchar *tcs = "#version 430 core\n"
24208 "#extension GL_ARB_enhanced_layouts : require\n"
24209 "\n"
24210 "layout(vertices = 1) out;\n"
24211 "\n"
24212 "in vec4 vs_any[];\n"
24213 "out vec4 tcs_tes[];\n"
24214 "\n"
24215 "void main()\n"
24216 "{\n"
24217 "\n"
24218 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
24219 "\n"
24220 " gl_TessLevelOuter[0] = 1.0;\n"
24221 " gl_TessLevelOuter[1] = 1.0;\n"
24222 " gl_TessLevelOuter[2] = 1.0;\n"
24223 " gl_TessLevelOuter[3] = 1.0;\n"
24224 " gl_TessLevelInner[0] = 1.0;\n"
24225 " gl_TessLevelInner[1] = 1.0;\n"
24226 "}\n"
24227 "\n";
24228 static const GLchar *tes_tested = "#version 430 core\n"
24229 "#extension GL_ARB_enhanced_layouts : require\n"
24230 "\n"
24231 "layout(isolines, point_mode) in;\n"
24232 "\n"
24233 "VAR_DEFINITION"
24234 "\n"
24235 "in vec4 tcs_tes[];\n"
24236 "out vec4 any_fs;\n"
24237 "\n"
24238 "void main()\n"
24239 "{\n"
24240 " vec4 result = tcs_tes[0];\n"
24241 "\n"
24242 "VARIABLE_USE"
24243 "\n"
24244 " any_fs += result;\n"
24245 "}\n"
24246 "\n";
24247 static const GLchar *vs = "#version 430 core\n"
24248 "#extension GL_ARB_enhanced_layouts : require\n"
24249 "\n"
24250 "in vec4 in_vs;\n"
24251 "out vec4 vs_any;\n"
24252 "\n"
24253 "void main()\n"
24254 "{\n"
24255 " vs_any = in_vs;\n"
24256 "}\n"
24257 "\n";
24258 static const GLchar *vs_tested = "#version 430 core\n"
24259 "#extension GL_ARB_enhanced_layouts : require\n"
24260 "\n"
24261 "VAR_DEFINITION"
24262 "\n"
24263 "in vec4 in_vs;\n"
24264 "out vec4 any_fs;\n"
24265 "\n"
24266 "void main()\n"
24267 "{\n"
24268 " vec4 result = in_vs;\n"
24269 "\n"
24270 "VARIABLE_USE"
24271 "\n"
24272 " any_fs = result;\n"
24273 "}\n"
24274 "\n";
24275
24276 std::string source;
24277 testCase &test_case = m_test_cases[test_case_index];
24278
24279 if (test_case.m_stage == stage)
24280 {
24281 GLchar buffer[16];
24282 const Functions &gl = m_context.getRenderContext().getFunctions();
24283 GLint max_n_xfb_comp = 0;
24284 GLint max_n_xfb_bytes = 0;
24285 size_t position = 0;
24286 const GLchar *var_definition = 0;
24287 const GLchar *var_use = 0;
24288
24289 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp);
24290 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
24291
24292 max_n_xfb_bytes = max_n_xfb_comp * 4;
24293
24294 sprintf(buffer, "%d", max_n_xfb_bytes);
24295
24296 switch (test_case.m_case)
24297 {
24298 case BLOCK:
24299 var_definition = block_var_definition;
24300 var_use = block_use;
24301 break;
24302 case GLOBAL:
24303 var_definition = global_var_definition;
24304 var_use = global_use;
24305 break;
24306 case VECTOR:
24307 var_definition = vector_var_definition;
24308 var_use = vector_use;
24309 break;
24310 default:
24311 TCU_FAIL("Invalid enum");
24312 }
24313
24314 switch (stage)
24315 {
24316 case Utils::Shader::GEOMETRY:
24317 source = gs_tested;
24318 break;
24319 case Utils::Shader::TESS_EVAL:
24320 source = tes_tested;
24321 break;
24322 case Utils::Shader::VERTEX:
24323 source = vs_tested;
24324 break;
24325 default:
24326 TCU_FAIL("Invalid enum");
24327 }
24328
24329 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
24330 position = 0;
24331 Utils::replaceToken("MAX_SIZE", position, buffer, source);
24332 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
24333 }
24334 else
24335 {
24336 switch (test_case.m_stage)
24337 {
24338 case Utils::Shader::GEOMETRY:
24339 switch (stage)
24340 {
24341 case Utils::Shader::FRAGMENT:
24342 source = fs;
24343 break;
24344 case Utils::Shader::VERTEX:
24345 source = vs;
24346 break;
24347 default:
24348 source = "";
24349 }
24350 break;
24351 case Utils::Shader::TESS_EVAL:
24352 switch (stage)
24353 {
24354 case Utils::Shader::FRAGMENT:
24355 source = fs;
24356 break;
24357 case Utils::Shader::TESS_CTRL:
24358 source = tcs;
24359 break;
24360 case Utils::Shader::VERTEX:
24361 source = vs;
24362 break;
24363 default:
24364 source = "";
24365 }
24366 break;
24367 case Utils::Shader::VERTEX:
24368 switch (stage)
24369 {
24370 case Utils::Shader::FRAGMENT:
24371 source = fs;
24372 break;
24373 default:
24374 source = "";
24375 }
24376 break;
24377 default:
24378 TCU_FAIL("Invalid enum");
24379 }
24380 }
24381
24382 return source;
24383 }
24384
24385 /** Get description of test case
24386 *
24387 * @param test_case_index Index of test case
24388 *
24389 * @return Test case description
24390 **/
24391 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index)
24392 {
24393 std::stringstream stream;
24394 testCase &test_case = m_test_cases[test_case_index];
24395
24396 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
24397
24398 switch (test_case.m_case)
24399 {
24400 case BLOCK:
24401 stream << "BLOCK";
24402 break;
24403 case GLOBAL:
24404 stream << "GLOBAL";
24405 break;
24406 case VECTOR:
24407 stream << "VECTOR";
24408 break;
24409 default:
24410 TCU_FAIL("Invalid enum");
24411 }
24412
24413 return stream.str();
24414 }
24415
24416 /** Get number of test cases
24417 *
24418 * @return Number of test cases
24419 **/
24420 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber()
24421 {
24422 return static_cast<GLuint>(m_test_cases.size());
24423 }
24424
24425 /** Selects if "compute" stage is relevant for test
24426 *
24427 * @param ignored
24428 *
24429 * @return false
24430 **/
24431 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */)
24432 {
24433 return false;
24434 }
24435
24436 /** Prepare all test cases
24437 *
24438 **/
24439 void XFBExceedOffsetLimitTest::testInit()
24440 {
24441 for (GLuint c = 0; c < CASE_MAX; ++c)
24442 {
24443 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24444 {
24445 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24446 (Utils::Shader::FRAGMENT == stage))
24447 {
24448 continue;
24449 }
24450
24451 testCase test_case = {(CASES)c, (Utils::Shader::STAGES)stage};
24452
24453 m_test_cases.push_back(test_case);
24454 }
24455 }
24456 }
24457
24458 /** Constructor
24459 *
24460 * @param context Test context
24461 **/
24462 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context &context)
24463 : BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected")
24464 {
24465 /* Nothing to be done here */
24466 }
24467
24468 /** Get descriptors of buffers necessary for test
24469 *
24470 * @param test_case_index Index of test case
24471 * @param out_descriptors Descriptors of buffers used by test
24472 **/
24473 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector &out_descriptors)
24474 {
24475 // the function "getType(test_case_index)" can't return correct data type, so change code as following:
24476 const Utils::Type &type = m_test_cases[test_case_index].m_type;
24477
24478 /* Test needs single uniform and two xfbs */
24479 out_descriptors.resize(3);
24480
24481 /* Get references */
24482 bufferDescriptor &uniform = out_descriptors[0];
24483 bufferDescriptor &xfb_1 = out_descriptors[1];
24484 bufferDescriptor &xfb_3 = out_descriptors[2];
24485
24486 /* Index */
24487 uniform.m_index = 0;
24488 xfb_1.m_index = 1;
24489 xfb_3.m_index = 3;
24490
24491 /* Target */
24492 uniform.m_target = Utils::Buffer::Uniform;
24493 xfb_1.m_target = Utils::Buffer::Transform_feedback;
24494 xfb_3.m_target = Utils::Buffer::Transform_feedback;
24495
24496 /* Data */
24497 const GLuint gen_start = Utils::s_rand;
24498 const std::vector<GLubyte> &chichi_data = type.GenerateData();
24499 const std::vector<GLubyte> &bulma_data = type.GenerateData();
24500 const std::vector<GLubyte> &trunks_data = type.GenerateData();
24501 const std::vector<GLubyte> &bra_data = type.GenerateData();
24502 const std::vector<GLubyte> &gohan_data = type.GenerateData();
24503 const std::vector<GLubyte> &goten_data = type.GenerateData();
24504
24505 Utils::s_rand = gen_start;
24506 const std::vector<GLubyte> &chichi_data_pck = type.GenerateDataPacked();
24507 const std::vector<GLubyte> &bulma_data_pck = type.GenerateDataPacked();
24508 const std::vector<GLubyte> &trunks_data_pck = type.GenerateDataPacked();
24509 const std::vector<GLubyte> &bra_data_pck = type.GenerateDataPacked();
24510 const std::vector<GLubyte> &gohan_data_pck = type.GenerateDataPacked();
24511 const std::vector<GLubyte> &goten_data_pck = type.GenerateDataPacked();
24512
24513 const GLuint type_size = static_cast<GLuint>(chichi_data.size());
24514 const GLuint padded_type_size = type.GetBaseAlignment(false) * type.m_n_columns;
24515 const GLuint type_size_pck = static_cast<GLuint>(chichi_data_pck.size());
24516
24517 /* Uniform data */
24518 uniform.m_initial_data.resize(6 * padded_type_size);
24519 memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size);
24520 memcpy(&uniform.m_initial_data[0] + padded_type_size, &bulma_data[0], type_size);
24521 memcpy(&uniform.m_initial_data[0] + 2 * padded_type_size, &trunks_data[0], type_size);
24522 memcpy(&uniform.m_initial_data[0] + 3 * padded_type_size, &bra_data[0], type_size);
24523 memcpy(&uniform.m_initial_data[0] + 4 * padded_type_size, &gohan_data[0], type_size);
24524 memcpy(&uniform.m_initial_data[0] + 5 * padded_type_size, &goten_data[0], type_size);
24525
24526 /* XFB data */
24527 xfb_1.m_initial_data.resize(3 * type_size_pck);
24528 xfb_1.m_expected_data.resize(3 * type_size_pck);
24529 xfb_3.m_initial_data.resize(3 * type_size_pck);
24530 xfb_3.m_expected_data.resize(3 * type_size_pck);
24531
24532 for (GLuint i = 0; i < 3 * type_size_pck; ++i)
24533 {
24534 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
24535 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
24536 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
24537 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
24538 }
24539
24540 memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck);
24541 memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck);
24542 memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck);
24543 memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck);
24544 memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck);
24545 memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck);
24546 }
24547
24548 /** Source for given test case and stage
24549 *
24550 * @param test_case_index Index of test case
24551 * @param stage Shader stage
24552 *
24553 * @return Shader source
24554 **/
24555 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24556 {
24557 static const GLchar *fs =
24558 "#version 430 core\n"
24559 "#extension GL_ARB_enhanced_layouts : require\n"
24560 "\n"
24561 "flat in TYPE chichi;\n"
24562 "flat in TYPE bulma;\n"
24563 "in Vegeta {\n"
24564 " flat TYPE trunk;\n"
24565 " flat TYPE bra;\n"
24566 "} vegeta;\n"
24567 "in Goku {\n"
24568 " flat TYPE gohan;\n"
24569 " flat TYPE goten;\n"
24570 "} goku;\n"
24571 "\n"
24572 "out vec4 fs_out;\n"
24573 "\n"
24574 "void main()\n"
24575 "{\n"
24576 " fs_out = vec4(1);\n"
24577 " if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n"
24578 " {\n"
24579 " fs_out = vec4(0);\n"
24580 " }\n"
24581 "}\n"
24582 "\n";
24583
24584 static const GLchar *gs = "#version 430 core\n"
24585 "#extension GL_ARB_enhanced_layouts : require\n"
24586 "\n"
24587 "layout(points) in;\n"
24588 "layout(points, max_vertices = 1) out;\n"
24589 "\n"
24590 "INTERFACE"
24591 "\n"
24592 "void main()\n"
24593 "{\n"
24594 "ASSIGNMENTS"
24595 " EmitVertex();\n"
24596 "}\n"
24597 "\n";
24598
24599 static const GLchar *tcs = "#version 430 core\n"
24600 "#extension GL_ARB_enhanced_layouts : require\n"
24601 "\n"
24602 "layout(vertices = 1) out;\n"
24603 "\n"
24604 "\n"
24605 "void main()\n"
24606 "{\n"
24607 " gl_TessLevelOuter[0] = 1.0;\n"
24608 " gl_TessLevelOuter[1] = 1.0;\n"
24609 " gl_TessLevelOuter[2] = 1.0;\n"
24610 " gl_TessLevelOuter[3] = 1.0;\n"
24611 " gl_TessLevelInner[0] = 1.0;\n"
24612 " gl_TessLevelInner[1] = 1.0;\n"
24613 "}\n"
24614 "\n";
24615
24616 static const GLchar *tes = "#version 430 core\n"
24617 "#extension GL_ARB_enhanced_layouts : require\n"
24618 "\n"
24619 "layout(isolines, point_mode) in;\n"
24620 "\n"
24621 "INTERFACE"
24622 "\n"
24623 "void main()\n"
24624 "{\n"
24625 "ASSIGNMENTS"
24626 "}\n"
24627 "\n";
24628
24629 static const GLchar *vs = "#version 430 core\n"
24630 "#extension GL_ARB_enhanced_layouts : require\n"
24631 "\n"
24632 "void main()\n"
24633 "{\n"
24634 "}\n"
24635 "\n";
24636
24637 static const GLchar *vs_tested = "#version 430 core\n"
24638 "#extension GL_ARB_enhanced_layouts : require\n"
24639 "\n"
24640 "INTERFACE"
24641 "\n"
24642 "void main()\n"
24643 "{\n"
24644 "ASSIGNMENTS"
24645 "}\n"
24646 "\n";
24647
24648 std::string source;
24649 const _testCase &test_case = m_test_cases[test_case_index];
24650 const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
24651
24652 if (test_case.m_stage == stage)
24653 {
24654 std::string assignments = " chichi = uni_chichi;\n"
24655 " bulma = uni_bulma;\n"
24656 " vegeta.trunk = uni_trunk;\n"
24657 " vegeta.bra = uni_bra;\n"
24658 " goku.gohan = uni_gohan;\n"
24659 " goku.goten = uni_goten;\n";
24660
24661 std::string interface = "layout (xfb_buffer = 3) out;\n"
24662 "\n"
24663 "const uint type_size = SIZE;\n"
24664 "\n"
24665 "layout ( xfb_offset = 2 * type_size) flat out TYPE chichi;\n"
24666 "layout (xfb_buffer = 1, xfb_offset = 0) flat out TYPE bulma;\n"
24667 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n"
24668 " flat TYPE trunk;\n"
24669 " flat TYPE bra;\n"
24670 "} vegeta;\n"
24671 "layout ( xfb_offset = 0) out Goku {\n"
24672 " flat TYPE gohan;\n"
24673 " flat TYPE goten;\n"
24674 "} goku;\n"
24675 "\n"
24676 // Uniform block must be declared with std140, otherwise each block member is not packed
24677 "layout(binding = 0, std140) uniform block {\n"
24678 " TYPE uni_chichi;\n"
24679 " TYPE uni_bulma;\n"
24680 " TYPE uni_trunk;\n"
24681 " TYPE uni_bra;\n"
24682 " TYPE uni_gohan;\n"
24683 " TYPE uni_goten;\n"
24684 "};\n";
24685
24686 /* Prepare interface string */
24687 {
24688 GLchar buffer[16];
24689 size_t position = 0;
24690 const GLuint type_size = test_case.m_type.GetSize();
24691
24692 sprintf(buffer, "%d", type_size);
24693
24694 Utils::replaceToken("SIZE", position, buffer, interface);
24695 Utils::replaceAllTokens("TYPE", type_name, interface);
24696 }
24697
24698 switch (stage)
24699 {
24700 case Utils::Shader::GEOMETRY:
24701 source = gs;
24702 break;
24703 case Utils::Shader::TESS_EVAL:
24704 source = tes;
24705 break;
24706 case Utils::Shader::VERTEX:
24707 source = vs_tested;
24708 break;
24709 default:
24710 TCU_FAIL("Invalid enum");
24711 }
24712
24713 /* Replace tokens */
24714 {
24715 size_t position = 0;
24716
24717 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
24718 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
24719 }
24720 }
24721 else
24722 {
24723 switch (test_case.m_stage)
24724 {
24725 case Utils::Shader::GEOMETRY:
24726 switch (stage)
24727 {
24728 case Utils::Shader::FRAGMENT:
24729 source = fs;
24730 Utils::replaceAllTokens("TYPE", type_name, source);
24731 break;
24732 case Utils::Shader::VERTEX:
24733 source = vs;
24734 break;
24735 default:
24736 source = "";
24737 }
24738 break;
24739 case Utils::Shader::TESS_EVAL:
24740 switch (stage)
24741 {
24742 case Utils::Shader::FRAGMENT:
24743 source = fs;
24744 Utils::replaceAllTokens("TYPE", type_name, source);
24745 break;
24746 case Utils::Shader::TESS_CTRL:
24747 source = tcs;
24748 break;
24749 case Utils::Shader::VERTEX:
24750 source = vs;
24751 break;
24752 default:
24753 source = "";
24754 }
24755 break;
24756 case Utils::Shader::VERTEX:
24757 switch (stage)
24758 {
24759 case Utils::Shader::FRAGMENT:
24760 source = fs;
24761 Utils::replaceAllTokens("TYPE", type_name, source);
24762 break;
24763 default:
24764 source = "";
24765 }
24766 break;
24767 default:
24768 TCU_FAIL("Invalid enum");
24769 }
24770 }
24771
24772 return source;
24773 }
24774
24775 /** Get name of test case
24776 *
24777 * @param test_case_index Index of test case
24778 *
24779 * @return Name of case
24780 **/
24781 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index)
24782 {
24783 std::string name;
24784 const _testCase &test_case = m_test_cases[test_case_index];
24785
24786 name = "Tested stage: ";
24787 name.append(Utils::Shader::GetStageName(test_case.m_stage));
24788 name.append(". Tested type: ");
24789 name.append(test_case.m_type.GetGLSLTypeName());
24790
24791 return name;
24792 }
24793
24794 /** Get number of cases
24795 *
24796 * @return Number of test cases
24797 **/
24798 GLuint XFBGlobalBufferTest::getTestCaseNumber()
24799 {
24800 return static_cast<GLuint>(m_test_cases.size());
24801 }
24802
24803 /** Prepare set of test cases
24804 *
24805 **/
24806 void XFBGlobalBufferTest::testInit()
24807 {
24808 GLuint n_types = getTypesNumber();
24809
24810 for (GLuint i = 0; i < n_types; ++i)
24811 {
24812 const Utils::Type &type = getType(i);
24813 /*
24814 When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will
24815 cause a link time error.
24816 */
24817 if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 ||
24818 strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0)
24819 {
24820 continue;
24821 }
24822 const _testCase test_cases[] = {
24823 {Utils::Shader::VERTEX, type}, {Utils::Shader::GEOMETRY, type}, {Utils::Shader::TESS_EVAL, type}};
24824
24825 m_test_cases.push_back(test_cases[0]);
24826 m_test_cases.push_back(test_cases[1]);
24827 m_test_cases.push_back(test_cases[2]);
24828 }
24829 }
24830
24831 /** Constructor
24832 *
24833 * @param context Test context
24834 **/
24835 XFBStrideTest::XFBStrideTest(deqp::Context &context)
24836 : BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types")
24837 {
24838 /* Nothing to be done here */
24839 }
24840
24841 /** Execute drawArrays for single vertex
24842 *
24843 * @param test_case_index
24844 *
24845 * @return true
24846 **/
24847 bool XFBStrideTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
24848 {
24849 const Functions &gl = m_context.getRenderContext().getFunctions();
24850 GLenum primitive_type = GL_PATCHES;
24851 const testCase &test_case = m_test_cases[test_case_index];
24852
24853 if (Utils::Shader::VERTEX == test_case.m_stage)
24854 {
24855 primitive_type = GL_POINTS;
24856 }
24857
24858 gl.disable(GL_RASTERIZER_DISCARD);
24859 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
24860
24861 gl.beginTransformFeedback(GL_POINTS);
24862 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
24863
24864 gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
24865 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
24866
24867 gl.endTransformFeedback();
24868 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
24869
24870 return true;
24871 }
24872
24873 /** Get descriptors of buffers necessary for test
24874 *
24875 * @param test_case_index Index of test case
24876 * @param out_descriptors Descriptors of buffers used by test
24877 **/
24878 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector &out_descriptors)
24879 {
24880 const testCase &test_case = m_test_cases[test_case_index];
24881 const Utils::Type &type = test_case.m_type;
24882
24883 /* Test needs single uniform and xfb */
24884 out_descriptors.resize(2);
24885
24886 /* Get references */
24887 bufferDescriptor &uniform = out_descriptors[0];
24888 bufferDescriptor &xfb = out_descriptors[1];
24889
24890 /* Index */
24891 uniform.m_index = 0;
24892 xfb.m_index = 0;
24893
24894 /* Target */
24895 uniform.m_target = Utils::Buffer::Uniform;
24896 xfb.m_target = Utils::Buffer::Transform_feedback;
24897
24898 /* Data */
24899 const GLuint rand_start = Utils::s_rand;
24900 const std::vector<GLubyte> &uniform_data = type.GenerateData();
24901
24902 Utils::s_rand = rand_start;
24903 const std::vector<GLubyte> &xfb_data = type.GenerateDataPacked();
24904
24905 const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
24906 const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
24907 /*
24908 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
24909 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
24910 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
24911 only one valid data should be initialized in xfb.m_expected_data
24912 */
24913 const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
24914 /* Uniform data */
24915 uniform.m_initial_data.resize(uni_type_size);
24916 memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
24917
24918 /* XFB data */
24919 xfb.m_initial_data.resize(xfb_data_size);
24920 xfb.m_expected_data.resize(xfb_data_size);
24921
24922 for (GLuint i = 0; i < xfb_data_size; ++i)
24923 {
24924 xfb.m_initial_data[i] = (glw::GLubyte)i;
24925 xfb.m_expected_data[i] = (glw::GLubyte)i;
24926 }
24927
24928 if (test_case.m_stage == Utils::Shader::VERTEX)
24929 {
24930 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24931 }
24932 else
24933 {
24934 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24935 memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
24936 }
24937 }
24938
24939 /** Get body of main function for given shader stage
24940 *
24941 * @param test_case_index Index of test case
24942 * @param stage Shader stage
24943 * @param out_assignments Set to empty
24944 * @param out_calculations Set to empty
24945 **/
24946 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string &out_assignments,
24947 std::string &out_calculations)
24948 {
24949 const testCase &test_case = m_test_cases[test_case_index];
24950
24951 out_calculations = "";
24952
24953 static const GLchar *vs_tes_gs = " goku = uni_goku;\n";
24954 static const GLchar *fs = " fs_out = vec4(1, 0.25, 0.5, 0.75);\n"
24955 " if (TYPE(0) == goku)\n"
24956 " {\n"
24957 " fs_out = vec4(1, 0.75, 0.5, 0.5);\n"
24958 " }\n";
24959
24960 const GLchar *assignments = "";
24961
24962 if (test_case.m_stage == stage)
24963 {
24964 switch (stage)
24965 {
24966 case Utils::Shader::GEOMETRY:
24967 assignments = vs_tes_gs;
24968 break;
24969 case Utils::Shader::TESS_EVAL:
24970 assignments = vs_tes_gs;
24971 break;
24972 case Utils::Shader::VERTEX:
24973 assignments = vs_tes_gs;
24974 break;
24975 default:
24976 TCU_FAIL("Invalid enum");
24977 }
24978 }
24979 else
24980 {
24981 switch (stage)
24982 {
24983 case Utils::Shader::FRAGMENT:
24984 assignments = fs;
24985 break;
24986 case Utils::Shader::GEOMETRY:
24987 case Utils::Shader::TESS_CTRL:
24988 case Utils::Shader::TESS_EVAL:
24989 case Utils::Shader::VERTEX:
24990 break;
24991 default:
24992 TCU_FAIL("Invalid enum");
24993 }
24994 }
24995
24996 out_assignments = assignments;
24997
24998 if (Utils::Shader::FRAGMENT == stage)
24999 {
25000 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
25001 }
25002 }
25003
25004 /** Get interface of shader
25005 *
25006 * @param test_case_index Index of test case
25007 * @param stage Shader stage
25008 * @param out_interface Set to ""
25009 **/
25010 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string &out_interface)
25011 {
25012 static const GLchar *vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n"
25013 "\n"
25014 "layout(std140, binding = 0) uniform Goku {\n"
25015 " TYPE uni_goku;\n"
25016 "};\n";
25017 static const GLchar *fs = "FLAT in TYPE goku;\n"
25018 "\n"
25019 "out vec4 fs_out;\n";
25020
25021 const testCase &test_case = m_test_cases[test_case_index];
25022 const GLchar *interface = "";
25023 const GLchar *flat = "";
25024
25025 if (test_case.m_stage == stage)
25026 {
25027 switch (stage)
25028 {
25029 case Utils::Shader::GEOMETRY:
25030 interface = vs_tes_gs;
25031 break;
25032 case Utils::Shader::TESS_EVAL:
25033 interface = vs_tes_gs;
25034 break;
25035 case Utils::Shader::VERTEX:
25036 interface = vs_tes_gs;
25037 break;
25038 default:
25039 TCU_FAIL("Invalid enum");
25040 }
25041 }
25042 else
25043 {
25044 switch (stage)
25045 {
25046 case Utils::Shader::FRAGMENT:
25047 interface = fs;
25048 break;
25049 case Utils::Shader::GEOMETRY:
25050 case Utils::Shader::TESS_CTRL:
25051 case Utils::Shader::TESS_EVAL:
25052 case Utils::Shader::VERTEX:
25053 break;
25054 default:
25055 TCU_FAIL("Invalid enum");
25056 }
25057 }
25058
25059 out_interface = interface;
25060
25061 if (Utils::Type::Float != test_case.m_type.m_basic_type)
25062 {
25063 flat = "flat";
25064 }
25065
25066 Utils::replaceAllTokens("FLAT", flat, out_interface);
25067 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
25068 }
25069
25070 /** Get source code of shader
25071 *
25072 * @param test_case_index Index of test case
25073 * @param stage Shader stage
25074 *
25075 * @return Source
25076 **/
25077 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25078 {
25079 std::string source;
25080 const testCase &test_case = m_test_cases[test_case_index];
25081
25082 switch (test_case.m_stage)
25083 {
25084 case Utils::Shader::VERTEX:
25085 switch (stage)
25086 {
25087 case Utils::Shader::FRAGMENT:
25088 case Utils::Shader::VERTEX:
25089 source = BufferTestBase::getShaderSource(test_case_index, stage);
25090 break;
25091 default:
25092 break;
25093 }
25094 break;
25095
25096 case Utils::Shader::TESS_EVAL:
25097 switch (stage)
25098 {
25099 case Utils::Shader::FRAGMENT:
25100 case Utils::Shader::TESS_CTRL:
25101 case Utils::Shader::TESS_EVAL:
25102 case Utils::Shader::VERTEX:
25103 source = BufferTestBase::getShaderSource(test_case_index, stage);
25104 break;
25105 default:
25106 break;
25107 }
25108 break;
25109
25110 case Utils::Shader::GEOMETRY:
25111 source = BufferTestBase::getShaderSource(test_case_index, stage);
25112 break;
25113
25114 default:
25115 TCU_FAIL("Invalid enum");
25116 }
25117
25118 /* */
25119 return source;
25120 }
25121
25122 /** Get name of test case
25123 *
25124 * @param test_case_index Index of test case
25125 *
25126 * @return Name of tested stage
25127 **/
25128 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index)
25129 {
25130 std::stringstream stream;
25131 const testCase &test_case = m_test_cases[test_case_index];
25132
25133 stream << "Type: " << test_case.m_type.GetGLSLTypeName()
25134 << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25135
25136 return stream.str();
25137 }
25138
25139 /** Returns number of test cases
25140 *
25141 * @return TEST_MAX
25142 **/
25143 glw::GLuint XFBStrideTest::getTestCaseNumber()
25144 {
25145 return static_cast<GLuint>(m_test_cases.size());
25146 }
25147
25148 /** Prepare all test cases
25149 *
25150 **/
25151 void XFBStrideTest::testInit()
25152 {
25153 const GLuint n_types = getTypesNumber();
25154
25155 for (GLuint i = 0; i < n_types; ++i)
25156 {
25157 const Utils::Type &type = getType(i);
25158
25159 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25160 {
25161 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
25162 (Utils::Shader::TESS_CTRL == stage))
25163 {
25164 continue;
25165 }
25166
25167 testCase test_case = {(Utils::Shader::STAGES)stage, type};
25168
25169 m_test_cases.push_back(test_case);
25170 }
25171 }
25172 }
25173
25174 /** Constructor
25175 *
25176 * @param context Test framework context
25177 **/
25178 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context &context)
25179 : NegativeTestBase(
25180 context, "xfb_block_member_buffer",
25181 "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer")
25182 {
25183 }
25184
25185 /** Source for given test case and stage
25186 *
25187 * @param test_case_index Index of test case
25188 * @param stage Shader stage
25189 *
25190 * @return Shader source
25191 **/
25192 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25193 {
25194 static const GLchar *var_definition = "layout (xfb_offset = 0) out Goku {\n"
25195 " vec4 gohan;\n"
25196 #if DEBUG_NEG_REMOVE_ERROR
25197 " /* layout (xfb_buffer = 1) */ vec4 goten;\n"
25198 #else
25199 " layout (xfb_buffer = 1) vec4 goten;\n"
25200 #endif /* DEBUG_NEG_REMOVE_ERROR */
25201 "} goku;\n";
25202 static const GLchar *var_use = " goku.gohan = result / 2;\n"
25203 " goku.goten = result / 4;\n";
25204 static const GLchar *fs = "#version 430 core\n"
25205 "#extension GL_ARB_enhanced_layouts : require\n"
25206 "\n"
25207 "in vec4 any_fs;\n"
25208 "out vec4 fs_out;\n"
25209 "\n"
25210 "void main()\n"
25211 "{\n"
25212 " fs_out = any_fs;\n"
25213 "}\n"
25214 "\n";
25215 static const GLchar *gs_tested = "#version 430 core\n"
25216 "#extension GL_ARB_enhanced_layouts : require\n"
25217 "\n"
25218 "layout(points) in;\n"
25219 "layout(triangle_strip, max_vertices = 4) out;\n"
25220 "\n"
25221 "VAR_DEFINITION"
25222 "\n"
25223 "in vec4 vs_any[];\n"
25224 "out vec4 any_fs;\n"
25225 "\n"
25226 "void main()\n"
25227 "{\n"
25228 " vec4 result = vs_any[0];\n"
25229 "\n"
25230 "VARIABLE_USE"
25231 "\n"
25232 " any_fs = result;\n"
25233 " gl_Position = vec4(-1, -1, 0, 1);\n"
25234 " EmitVertex();\n"
25235 " any_fs = result;\n"
25236 " gl_Position = vec4(-1, 1, 0, 1);\n"
25237 " EmitVertex();\n"
25238 " any_fs = result;\n"
25239 " gl_Position = vec4(1, -1, 0, 1);\n"
25240 " EmitVertex();\n"
25241 " any_fs = result;\n"
25242 " gl_Position = vec4(1, 1, 0, 1);\n"
25243 " EmitVertex();\n"
25244 "}\n"
25245 "\n";
25246 static const GLchar *tcs = "#version 430 core\n"
25247 "#extension GL_ARB_enhanced_layouts : require\n"
25248 "\n"
25249 "layout(vertices = 1) out;\n"
25250 "\n"
25251 "in vec4 vs_any[];\n"
25252 "out vec4 tcs_tes[];\n"
25253 "\n"
25254 "void main()\n"
25255 "{\n"
25256 "\n"
25257 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
25258 "\n"
25259 " gl_TessLevelOuter[0] = 1.0;\n"
25260 " gl_TessLevelOuter[1] = 1.0;\n"
25261 " gl_TessLevelOuter[2] = 1.0;\n"
25262 " gl_TessLevelOuter[3] = 1.0;\n"
25263 " gl_TessLevelInner[0] = 1.0;\n"
25264 " gl_TessLevelInner[1] = 1.0;\n"
25265 "}\n"
25266 "\n";
25267 static const GLchar *tes_tested = "#version 430 core\n"
25268 "#extension GL_ARB_enhanced_layouts : require\n"
25269 "\n"
25270 "layout(isolines, point_mode) in;\n"
25271 "\n"
25272 "VAR_DEFINITION"
25273 "\n"
25274 "in vec4 tcs_tes[];\n"
25275 "out vec4 any_fs;\n"
25276 "\n"
25277 "void main()\n"
25278 "{\n"
25279 " vec4 result = tcs_tes[0];\n"
25280 "\n"
25281 "VARIABLE_USE"
25282 "\n"
25283 " any_fs += result;\n"
25284 "}\n"
25285 "\n";
25286 static const GLchar *vs = "#version 430 core\n"
25287 "#extension GL_ARB_enhanced_layouts : require\n"
25288 "\n"
25289 "in vec4 in_vs;\n"
25290 "out vec4 vs_any;\n"
25291 "\n"
25292 "void main()\n"
25293 "{\n"
25294 " vs_any = in_vs;\n"
25295 "}\n"
25296 "\n";
25297 static const GLchar *vs_tested = "#version 430 core\n"
25298 "#extension GL_ARB_enhanced_layouts : require\n"
25299 "\n"
25300 "VAR_DEFINITION"
25301 "\n"
25302 "in vec4 in_vs;\n"
25303 "out vec4 any_fs;\n"
25304 "\n"
25305 "void main()\n"
25306 "{\n"
25307 " vec4 result = in_vs;\n"
25308 "\n"
25309 "VARIABLE_USE"
25310 "\n"
25311 " any_fs = result;\n"
25312 "}\n"
25313 "\n";
25314
25315 std::string source;
25316 testCase &test_case = m_test_cases[test_case_index];
25317
25318 if (test_case.m_stage == stage)
25319 {
25320 size_t position = 0;
25321
25322 switch (stage)
25323 {
25324 case Utils::Shader::GEOMETRY:
25325 source = gs_tested;
25326 break;
25327 case Utils::Shader::TESS_EVAL:
25328 source = tes_tested;
25329 break;
25330 case Utils::Shader::VERTEX:
25331 source = vs_tested;
25332 break;
25333 default:
25334 TCU_FAIL("Invalid enum");
25335 }
25336
25337 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25338 position = 0;
25339 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25340 }
25341 else
25342 {
25343 switch (test_case.m_stage)
25344 {
25345 case Utils::Shader::GEOMETRY:
25346 switch (stage)
25347 {
25348 case Utils::Shader::FRAGMENT:
25349 source = fs;
25350 break;
25351 case Utils::Shader::VERTEX:
25352 source = vs;
25353 break;
25354 default:
25355 source = "";
25356 }
25357 break;
25358 case Utils::Shader::TESS_EVAL:
25359 switch (stage)
25360 {
25361 case Utils::Shader::FRAGMENT:
25362 source = fs;
25363 break;
25364 case Utils::Shader::TESS_CTRL:
25365 source = tcs;
25366 break;
25367 case Utils::Shader::VERTEX:
25368 source = vs;
25369 break;
25370 default:
25371 source = "";
25372 }
25373 break;
25374 case Utils::Shader::VERTEX:
25375 switch (stage)
25376 {
25377 case Utils::Shader::FRAGMENT:
25378 source = fs;
25379 break;
25380 default:
25381 source = "";
25382 }
25383 break;
25384 default:
25385 TCU_FAIL("Invalid enum");
25386 }
25387 }
25388
25389 return source;
25390 }
25391
25392 /** Get description of test case
25393 *
25394 * @param test_case_index Index of test case
25395 *
25396 * @return Test case description
25397 **/
25398 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index)
25399 {
25400 std::stringstream stream;
25401 testCase &test_case = m_test_cases[test_case_index];
25402
25403 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25404
25405 return stream.str();
25406 }
25407
25408 /** Get number of test cases
25409 *
25410 * @return Number of test cases
25411 **/
25412 GLuint XFBBlockMemberBufferTest::getTestCaseNumber()
25413 {
25414 return static_cast<GLuint>(m_test_cases.size());
25415 }
25416
25417 /** Selects if "compute" stage is relevant for test
25418 *
25419 * @param ignored
25420 *
25421 * @return false
25422 **/
25423 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */)
25424 {
25425 return false;
25426 }
25427
25428 /** Prepare all test cases
25429 *
25430 **/
25431 void XFBBlockMemberBufferTest::testInit()
25432 {
25433 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25434 {
25435 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25436 (Utils::Shader::FRAGMENT == stage))
25437 {
25438 continue;
25439 }
25440
25441 testCase test_case = {(Utils::Shader::STAGES)stage};
25442
25443 m_test_cases.push_back(test_case);
25444 }
25445 }
25446
25447 /** Constructor
25448 *
25449 * @param context Test framework context
25450 **/
25451 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context &context)
25452 : NegativeTestBase(context, "xfb_output_overlapping",
25453 "Test verifies that compiler reports error when two xfb qualified outputs overlap")
25454 {
25455 }
25456
25457 /** Source for given test case and stage
25458 *
25459 * @param test_case_index Index of test case
25460 * @param stage Shader stage
25461 *
25462 * @return Shader source
25463 **/
25464 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25465 {
25466 static const GLchar *var_definition = "layout (xfb_offset = 0) out TYPE gohan;\n"
25467 #if DEBUG_NEG_REMOVE_ERROR
25468 "/* layout (xfb_offset = OFFSET) */ out TYPE goten;\n";
25469 #else
25470 "layout (xfb_offset = OFFSET) out TYPE goten;\n";
25471 #endif /* DEBUG_NEG_REMOVE_ERROR */
25472 static const GLchar *var_use = " gohan = TYPE(0);\n"
25473 " goten = TYPE(1);\n"
25474 " if (vec4(0) == result)\n"
25475 " {\n"
25476 " gohan = TYPE(1);\n"
25477 " goten = TYPE(0);\n"
25478 " }\n";
25479 static const GLchar *fs = "#version 430 core\n"
25480 "#extension GL_ARB_enhanced_layouts : require\n"
25481 "\n"
25482 "in vec4 any_fs;\n"
25483 "out vec4 fs_out;\n"
25484 "\n"
25485 "void main()\n"
25486 "{\n"
25487 " fs_out = any_fs;\n"
25488 "}\n"
25489 "\n";
25490 static const GLchar *gs_tested = "#version 430 core\n"
25491 "#extension GL_ARB_enhanced_layouts : require\n"
25492 "\n"
25493 "layout(points) in;\n"
25494 "layout(triangle_strip, max_vertices = 4) out;\n"
25495 "\n"
25496 "VAR_DEFINITION"
25497 "\n"
25498 "in vec4 vs_any[];\n"
25499 "out vec4 any_fs;\n"
25500 "\n"
25501 "void main()\n"
25502 "{\n"
25503 " vec4 result = vs_any[0];\n"
25504 "\n"
25505 "VARIABLE_USE"
25506 "\n"
25507 " any_fs = result;\n"
25508 " gl_Position = vec4(-1, -1, 0, 1);\n"
25509 " EmitVertex();\n"
25510 " any_fs = result;\n"
25511 " gl_Position = vec4(-1, 1, 0, 1);\n"
25512 " EmitVertex();\n"
25513 " any_fs = result;\n"
25514 " gl_Position = vec4(1, -1, 0, 1);\n"
25515 " EmitVertex();\n"
25516 " any_fs = result;\n"
25517 " gl_Position = vec4(1, 1, 0, 1);\n"
25518 " EmitVertex();\n"
25519 "}\n"
25520 "\n";
25521 static const GLchar *tcs = "#version 430 core\n"
25522 "#extension GL_ARB_enhanced_layouts : require\n"
25523 "\n"
25524 "layout(vertices = 1) out;\n"
25525 "\n"
25526 "in vec4 vs_any[];\n"
25527 "out vec4 tcs_tes[];\n"
25528 "\n"
25529 "void main()\n"
25530 "{\n"
25531 "\n"
25532 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
25533 "\n"
25534 " gl_TessLevelOuter[0] = 1.0;\n"
25535 " gl_TessLevelOuter[1] = 1.0;\n"
25536 " gl_TessLevelOuter[2] = 1.0;\n"
25537 " gl_TessLevelOuter[3] = 1.0;\n"
25538 " gl_TessLevelInner[0] = 1.0;\n"
25539 " gl_TessLevelInner[1] = 1.0;\n"
25540 "}\n"
25541 "\n";
25542 static const GLchar *tes_tested = "#version 430 core\n"
25543 "#extension GL_ARB_enhanced_layouts : require\n"
25544 "\n"
25545 "layout(isolines, point_mode) in;\n"
25546 "\n"
25547 "VAR_DEFINITION"
25548 "\n"
25549 "in vec4 tcs_tes[];\n"
25550 "out vec4 any_fs;\n"
25551 "\n"
25552 "void main()\n"
25553 "{\n"
25554 " vec4 result = tcs_tes[0];\n"
25555 "\n"
25556 "VARIABLE_USE"
25557 "\n"
25558 " any_fs += result;\n"
25559 "}\n"
25560 "\n";
25561 static const GLchar *vs = "#version 430 core\n"
25562 "#extension GL_ARB_enhanced_layouts : require\n"
25563 "\n"
25564 "in vec4 in_vs;\n"
25565 "out vec4 vs_any;\n"
25566 "\n"
25567 "void main()\n"
25568 "{\n"
25569 " vs_any = in_vs;\n"
25570 "}\n"
25571 "\n";
25572 static const GLchar *vs_tested = "#version 430 core\n"
25573 "#extension GL_ARB_enhanced_layouts : require\n"
25574 "\n"
25575 "VAR_DEFINITION"
25576 "\n"
25577 "in vec4 in_vs;\n"
25578 "out vec4 any_fs;\n"
25579 "\n"
25580 "void main()\n"
25581 "{\n"
25582 " vec4 result = in_vs;\n"
25583 "\n"
25584 "VARIABLE_USE"
25585 "\n"
25586 " any_fs = result;\n"
25587 "}\n"
25588 "\n";
25589
25590 std::string source;
25591 testCase &test_case = m_test_cases[test_case_index];
25592
25593 if (test_case.m_stage == stage)
25594 {
25595 GLchar offset[16];
25596 size_t position = 0;
25597 const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
25598
25599 sprintf(offset, "%d", test_case.m_offset);
25600
25601 switch (stage)
25602 {
25603 case Utils::Shader::GEOMETRY:
25604 source = gs_tested;
25605 break;
25606 case Utils::Shader::TESS_EVAL:
25607 source = tes_tested;
25608 break;
25609 case Utils::Shader::VERTEX:
25610 source = vs_tested;
25611 break;
25612 default:
25613 TCU_FAIL("Invalid enum");
25614 }
25615
25616 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25617 position = 0;
25618 Utils::replaceToken("OFFSET", position, offset, source);
25619 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25620
25621 Utils::replaceAllTokens("TYPE", type_name, source);
25622 }
25623 else
25624 {
25625 switch (test_case.m_stage)
25626 {
25627 case Utils::Shader::GEOMETRY:
25628 switch (stage)
25629 {
25630 case Utils::Shader::FRAGMENT:
25631 source = fs;
25632 break;
25633 case Utils::Shader::VERTEX:
25634 source = vs;
25635 break;
25636 default:
25637 source = "";
25638 }
25639 break;
25640 case Utils::Shader::TESS_EVAL:
25641 switch (stage)
25642 {
25643 case Utils::Shader::FRAGMENT:
25644 source = fs;
25645 break;
25646 case Utils::Shader::TESS_CTRL:
25647 source = tcs;
25648 break;
25649 case Utils::Shader::VERTEX:
25650 source = vs;
25651 break;
25652 default:
25653 source = "";
25654 }
25655 break;
25656 case Utils::Shader::VERTEX:
25657 switch (stage)
25658 {
25659 case Utils::Shader::FRAGMENT:
25660 source = fs;
25661 break;
25662 default:
25663 source = "";
25664 }
25665 break;
25666 default:
25667 TCU_FAIL("Invalid enum");
25668 }
25669 }
25670
25671 return source;
25672 }
25673
25674 /** Get description of test case
25675 *
25676 * @param test_case_index Index of test case
25677 *
25678 * @return Test case description
25679 **/
25680 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index)
25681 {
25682 std::stringstream stream;
25683 testCase &test_case = m_test_cases[test_case_index];
25684
25685 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25686 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25687
25688 return stream.str();
25689 }
25690
25691 /** Get number of test cases
25692 *
25693 * @return Number of test cases
25694 **/
25695 GLuint XFBOutputOverlappingTest::getTestCaseNumber()
25696 {
25697 return static_cast<GLuint>(m_test_cases.size());
25698 }
25699
25700 /** Selects if "compute" stage is relevant for test
25701 *
25702 * @param ignored
25703 *
25704 * @return false
25705 **/
25706 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */)
25707 {
25708 return false;
25709 }
25710
25711 /** Prepare all test cases
25712 *
25713 **/
25714 void XFBOutputOverlappingTest::testInit()
25715 {
25716 const GLuint n_types = getTypesNumber();
25717
25718 for (GLuint i = 0; i < n_types; ++i)
25719 {
25720 const Utils::Type &type = getType(i);
25721 const GLuint basic_type_size = Utils::Type::GetTypeSize(type.m_basic_type);
25722
25723 /* Skip scalars, not applicable as:
25724 *
25725 * The offset must be a multiple of the size of the first component of the first
25726 * qualified variable or block member, or a compile-time error results.
25727 */
25728 if ((1 == type.m_n_columns) && (1 == type.m_n_rows))
25729 {
25730 continue;
25731 }
25732
25733 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25734 {
25735 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25736 (Utils::Shader::FRAGMENT == stage))
25737 {
25738 continue;
25739 }
25740
25741 testCase test_case = {basic_type_size /* offset */, (Utils::Shader::STAGES)stage, type};
25742
25743 m_test_cases.push_back(test_case);
25744 }
25745 }
25746 }
25747
25748 /** Constructor
25749 *
25750 * @param context Test framework context
25751 **/
25752 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context &context)
25753 : NegativeTestBase(context, "xfb_invalid_offset_alignment",
25754 "Test verifies that compiler reports error when xfb_offset has invalid alignment")
25755 {
25756 }
25757
25758 /** Source for given test case and stage
25759 *
25760 * @param test_case_index Index of test case
25761 * @param stage Shader stage
25762 *
25763 * @return Shader source
25764 **/
25765 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25766 {
25767 #if DEBUG_NEG_REMOVE_ERROR
25768 static const GLchar *var_definition = "/* layout (xfb_offset = OFFSET) */ out TYPE gohan;\n";
25769 #else
25770 static const GLchar *var_definition = "layout (xfb_offset = OFFSET) out TYPE gohan;\n";
25771 #endif /* DEBUG_NEG_REMOVE_ERROR */
25772 static const GLchar *var_use = " gohan = TYPE(0);\n"
25773 " if (vec4(0) == result)\n"
25774 " {\n"
25775 " gohan = TYPE(1);\n"
25776 " }\n";
25777 static const GLchar *fs = "#version 430 core\n"
25778 "#extension GL_ARB_enhanced_layouts : require\n"
25779 "\n"
25780 "in vec4 any_fs;\n"
25781 "out vec4 fs_out;\n"
25782 "\n"
25783 "void main()\n"
25784 "{\n"
25785 " fs_out = any_fs;\n"
25786 "}\n"
25787 "\n";
25788 static const GLchar *gs_tested = "#version 430 core\n"
25789 "#extension GL_ARB_enhanced_layouts : require\n"
25790 "\n"
25791 "layout(points) in;\n"
25792 "layout(triangle_strip, max_vertices = 4) out;\n"
25793 "\n"
25794 "VAR_DEFINITION"
25795 "\n"
25796 "in vec4 vs_any[];\n"
25797 "out vec4 any_fs;\n"
25798 "\n"
25799 "void main()\n"
25800 "{\n"
25801 " vec4 result = vs_any[0];\n"
25802 "\n"
25803 "VARIABLE_USE"
25804 "\n"
25805 " any_fs = result;\n"
25806 " gl_Position = vec4(-1, -1, 0, 1);\n"
25807 " EmitVertex();\n"
25808 " any_fs = result;\n"
25809 " gl_Position = vec4(-1, 1, 0, 1);\n"
25810 " EmitVertex();\n"
25811 " any_fs = result;\n"
25812 " gl_Position = vec4(1, -1, 0, 1);\n"
25813 " EmitVertex();\n"
25814 " any_fs = result;\n"
25815 " gl_Position = vec4(1, 1, 0, 1);\n"
25816 " EmitVertex();\n"
25817 "}\n"
25818 "\n";
25819 static const GLchar *tcs = "#version 430 core\n"
25820 "#extension GL_ARB_enhanced_layouts : require\n"
25821 "\n"
25822 "layout(vertices = 1) out;\n"
25823 "\n"
25824 "in vec4 vs_any[];\n"
25825 "out vec4 tcs_tes[];\n"
25826 "\n"
25827 "void main()\n"
25828 "{\n"
25829 "\n"
25830 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
25831 "\n"
25832 " gl_TessLevelOuter[0] = 1.0;\n"
25833 " gl_TessLevelOuter[1] = 1.0;\n"
25834 " gl_TessLevelOuter[2] = 1.0;\n"
25835 " gl_TessLevelOuter[3] = 1.0;\n"
25836 " gl_TessLevelInner[0] = 1.0;\n"
25837 " gl_TessLevelInner[1] = 1.0;\n"
25838 "}\n"
25839 "\n";
25840 static const GLchar *tes_tested = "#version 430 core\n"
25841 "#extension GL_ARB_enhanced_layouts : require\n"
25842 "\n"
25843 "layout(isolines, point_mode) in;\n"
25844 "\n"
25845 "VAR_DEFINITION"
25846 "\n"
25847 "in vec4 tcs_tes[];\n"
25848 "out vec4 any_fs;\n"
25849 "\n"
25850 "void main()\n"
25851 "{\n"
25852 " vec4 result = tcs_tes[0];\n"
25853 "\n"
25854 "VARIABLE_USE"
25855 "\n"
25856 " any_fs += result;\n"
25857 "}\n"
25858 "\n";
25859 static const GLchar *vs = "#version 430 core\n"
25860 "#extension GL_ARB_enhanced_layouts : require\n"
25861 "\n"
25862 "in vec4 in_vs;\n"
25863 "out vec4 vs_any;\n"
25864 "\n"
25865 "void main()\n"
25866 "{\n"
25867 " vs_any = in_vs;\n"
25868 "}\n"
25869 "\n";
25870 static const GLchar *vs_tested = "#version 430 core\n"
25871 "#extension GL_ARB_enhanced_layouts : require\n"
25872 "\n"
25873 "VAR_DEFINITION"
25874 "\n"
25875 "in vec4 in_vs;\n"
25876 "out vec4 any_fs;\n"
25877 "\n"
25878 "void main()\n"
25879 "{\n"
25880 " vec4 result = in_vs;\n"
25881 "\n"
25882 "VARIABLE_USE"
25883 "\n"
25884 " any_fs = result;\n"
25885 "}\n"
25886 "\n";
25887
25888 std::string source;
25889 testCase &test_case = m_test_cases[test_case_index];
25890
25891 if (test_case.m_stage == stage)
25892 {
25893 GLchar offset[16];
25894 size_t position = 0;
25895 const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
25896
25897 sprintf(offset, "%d", test_case.m_offset);
25898
25899 switch (stage)
25900 {
25901 case Utils::Shader::GEOMETRY:
25902 source = gs_tested;
25903 break;
25904 case Utils::Shader::TESS_EVAL:
25905 source = tes_tested;
25906 break;
25907 case Utils::Shader::VERTEX:
25908 source = vs_tested;
25909 break;
25910 default:
25911 TCU_FAIL("Invalid enum");
25912 }
25913
25914 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25915 position = 0;
25916 Utils::replaceToken("OFFSET", position, offset, source);
25917 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25918
25919 Utils::replaceAllTokens("TYPE", type_name, source);
25920 }
25921 else
25922 {
25923 switch (test_case.m_stage)
25924 {
25925 case Utils::Shader::GEOMETRY:
25926 switch (stage)
25927 {
25928 case Utils::Shader::FRAGMENT:
25929 source = fs;
25930 break;
25931 case Utils::Shader::VERTEX:
25932 source = vs;
25933 break;
25934 default:
25935 source = "";
25936 }
25937 break;
25938 case Utils::Shader::TESS_EVAL:
25939 switch (stage)
25940 {
25941 case Utils::Shader::FRAGMENT:
25942 source = fs;
25943 break;
25944 case Utils::Shader::TESS_CTRL:
25945 source = tcs;
25946 break;
25947 case Utils::Shader::VERTEX:
25948 source = vs;
25949 break;
25950 default:
25951 source = "";
25952 }
25953 break;
25954 case Utils::Shader::VERTEX:
25955 switch (stage)
25956 {
25957 case Utils::Shader::FRAGMENT:
25958 source = fs;
25959 break;
25960 default:
25961 source = "";
25962 }
25963 break;
25964 default:
25965 TCU_FAIL("Invalid enum");
25966 }
25967 }
25968
25969 return source;
25970 }
25971
25972 /** Get description of test case
25973 *
25974 * @param test_case_index Index of test case
25975 *
25976 * @return Test case description
25977 **/
25978 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
25979 {
25980 std::stringstream stream;
25981 testCase &test_case = m_test_cases[test_case_index];
25982
25983 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25984 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25985
25986 return stream.str();
25987 }
25988
25989 /** Get number of test cases
25990 *
25991 * @return Number of test cases
25992 **/
25993 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber()
25994 {
25995 return static_cast<GLuint>(m_test_cases.size());
25996 }
25997
25998 /** Selects if "compute" stage is relevant for test
25999 *
26000 * @param ignored
26001 *
26002 * @return false
26003 **/
26004 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */)
26005 {
26006 return false;
26007 }
26008
26009 /** Prepare all test cases
26010 *
26011 **/
26012 void XFBInvalidOffsetAlignmentTest::testInit()
26013 {
26014 const GLuint n_types = getTypesNumber();
26015
26016 for (GLuint i = 0; i < n_types; ++i)
26017 {
26018 const Utils::Type &type = getType(i);
26019 const GLuint basic_type_size = Utils::Type::GetTypeSize(type.m_basic_type);
26020
26021 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
26022 {
26023 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
26024 (Utils::Shader::FRAGMENT == stage))
26025 {
26026 continue;
26027 }
26028
26029 for (GLuint offset = basic_type_size + 1; offset < 2 * basic_type_size; ++offset)
26030 {
26031 testCase test_case = {offset, (Utils::Shader::STAGES)stage, type};
26032
26033 m_test_cases.push_back(test_case);
26034 }
26035 }
26036 }
26037 }
26038
26039 /** Constructor
26040 *
26041 * @param context Test context
26042 **/
26043 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context &context)
26044 : BufferTestBase(context, "xfb_capture_inactive_output_variable",
26045 "Test verifies that inactive variables are captured")
26046 {
26047 /* Nothing to be done here */
26048 }
26049
26050 /** Execute drawArrays for single vertex
26051 *
26052 * @param test_case_index
26053 *
26054 * @return true
26055 **/
26056 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26057 {
26058 const Functions &gl = m_context.getRenderContext().getFunctions();
26059 GLenum primitive_type = GL_PATCHES;
26060
26061 if (TEST_VS == test_case_index)
26062 {
26063 primitive_type = GL_POINTS;
26064 }
26065
26066 gl.disable(GL_RASTERIZER_DISCARD);
26067 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26068
26069 gl.beginTransformFeedback(GL_POINTS);
26070 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26071
26072 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26073 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26074
26075 gl.endTransformFeedback();
26076 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26077
26078 return true;
26079 }
26080
26081 /** Get descriptors of buffers necessary for test
26082 *
26083 * @param ignored
26084 * @param out_descriptors Descriptors of buffers used by test
26085 **/
26086 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26087 bufferDescriptor::Vector &out_descriptors)
26088 {
26089 const Utils::Type &type = Utils::Type::vec4;
26090
26091 /* Test needs single uniform and xfb */
26092 out_descriptors.resize(2);
26093
26094 /* Get references */
26095 bufferDescriptor &uniform = out_descriptors[0];
26096 bufferDescriptor &xfb = out_descriptors[1];
26097
26098 /* Index */
26099 uniform.m_index = 0;
26100 xfb.m_index = 0;
26101
26102 /* Target */
26103 uniform.m_target = Utils::Buffer::Uniform;
26104 xfb.m_target = Utils::Buffer::Transform_feedback;
26105
26106 /* Data */
26107 const std::vector<GLubyte> &gohan_data = type.GenerateData();
26108 const std::vector<GLubyte> &goten_data = type.GenerateData();
26109
26110 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26111
26112 /* Uniform data */
26113 uniform.m_initial_data.resize(2 * type_size);
26114 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26115 memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size);
26116
26117 /* XFB data */
26118 xfb.m_initial_data.resize(3 * type_size);
26119 xfb.m_expected_data.resize(3 * type_size);
26120
26121 for (GLuint i = 0; i < 3 * type_size; ++i)
26122 {
26123 xfb.m_initial_data[i] = (glw::GLubyte)i;
26124 xfb.m_expected_data[i] = (glw::GLubyte)i;
26125 }
26126
26127 memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size);
26128 memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size);
26129 }
26130
26131 /** Get body of main function for given shader stage
26132 *
26133 * @param test_case_index Index of test case
26134 * @param stage Shader stage
26135 * @param out_assignments Set to empty
26136 * @param out_calculations Set to empty
26137 **/
26138 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26139 std::string &out_assignments, std::string &out_calculations)
26140 {
26141 out_calculations = "";
26142
26143 static const GLchar *vs_tes_gs = " goten = uni_goten;\n"
26144 " gohan = uni_gohan;\n";
26145 static const GLchar *fs = " fs_out = goku + gohan + goten;\n";
26146
26147 const GLchar *assignments = "";
26148
26149 switch (stage)
26150 {
26151 case Utils::Shader::FRAGMENT:
26152 assignments = fs;
26153 break;
26154
26155 case Utils::Shader::GEOMETRY:
26156 if (TEST_GS == test_case_index)
26157 {
26158 assignments = vs_tes_gs;
26159 }
26160 break;
26161
26162 case Utils::Shader::TESS_CTRL:
26163 break;
26164
26165 case Utils::Shader::TESS_EVAL:
26166 if (TEST_TES == test_case_index)
26167 {
26168 assignments = vs_tes_gs;
26169 }
26170 break;
26171
26172 case Utils::Shader::VERTEX:
26173 if (TEST_VS == test_case_index)
26174 {
26175 assignments = vs_tes_gs;
26176 }
26177 break;
26178
26179 default:
26180 TCU_FAIL("Invalid enum");
26181 }
26182
26183 out_assignments = assignments;
26184 }
26185
26186 /** Get interface of shader
26187 *
26188 * @param test_case_index Index of test case
26189 * @param stage Shader stage
26190 * @param out_interface Set to ""
26191 **/
26192 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26193 std::string &out_interface)
26194 {
26195 static const GLchar *vs_tes_gs = "const uint sizeof_type = 16;\n"
26196 "\n"
26197 "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n"
26198 "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n"
26199 "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n"
26200 "\n"
26201 "layout(binding = 0) uniform block {\n"
26202 " vec4 uni_gohan;\n"
26203 " vec4 uni_goten;\n"
26204 "};\n";
26205 static const GLchar *fs = "in vec4 goku;\n"
26206 "in vec4 gohan;\n"
26207 "in vec4 goten;\n"
26208 "out vec4 fs_out;\n";
26209
26210 const GLchar *interface = "";
26211
26212 switch (stage)
26213 {
26214 case Utils::Shader::FRAGMENT:
26215 interface = fs;
26216 break;
26217
26218 case Utils::Shader::GEOMETRY:
26219 if (TEST_GS == test_case_index)
26220 {
26221 interface = vs_tes_gs;
26222 }
26223 break;
26224
26225 case Utils::Shader::TESS_CTRL:
26226 break;
26227
26228 case Utils::Shader::TESS_EVAL:
26229 if (TEST_TES == test_case_index)
26230 {
26231 interface = vs_tes_gs;
26232 }
26233 break;
26234
26235 case Utils::Shader::VERTEX:
26236 if (TEST_VS == test_case_index)
26237 {
26238 interface = vs_tes_gs;
26239 }
26240 break;
26241
26242 default:
26243 TCU_FAIL("Invalid enum");
26244 }
26245
26246 out_interface = interface;
26247 }
26248
26249 /** Get source code of shader
26250 *
26251 * @param test_case_index Index of test case
26252 * @param stage Shader stage
26253 *
26254 * @return Source
26255 **/
26256 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26257 {
26258 std::string source;
26259
26260 switch (test_case_index)
26261 {
26262 case TEST_VS:
26263 switch (stage)
26264 {
26265 case Utils::Shader::FRAGMENT:
26266 case Utils::Shader::VERTEX:
26267 source = BufferTestBase::getShaderSource(test_case_index, stage);
26268 break;
26269 default:
26270 break;
26271 }
26272 break;
26273
26274 case TEST_TES:
26275 switch (stage)
26276 {
26277 case Utils::Shader::FRAGMENT:
26278 case Utils::Shader::TESS_CTRL:
26279 case Utils::Shader::TESS_EVAL:
26280 case Utils::Shader::VERTEX:
26281 source = BufferTestBase::getShaderSource(test_case_index, stage);
26282 break;
26283 default:
26284 break;
26285 }
26286 break;
26287
26288 case TEST_GS:
26289 source = BufferTestBase::getShaderSource(test_case_index, stage);
26290 break;
26291
26292 default:
26293 TCU_FAIL("Invalid enum");
26294 }
26295
26296 /* */
26297 return source;
26298 }
26299
26300 /** Get name of test case
26301 *
26302 * @param test_case_index Index of test case
26303 *
26304 * @return Name of tested stage
26305 **/
26306 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index)
26307 {
26308 const GLchar *name = 0;
26309
26310 switch (test_case_index)
26311 {
26312 case TEST_VS:
26313 name = "vertex";
26314 break;
26315 case TEST_TES:
26316 name = "tessellation evaluation";
26317 break;
26318 case TEST_GS:
26319 name = "geometry";
26320 break;
26321 default:
26322 TCU_FAIL("Invalid enum");
26323 }
26324
26325 return name;
26326 }
26327
26328 /** Returns number of test cases
26329 *
26330 * @return TEST_MAX
26331 **/
26332 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber()
26333 {
26334 return TEST_MAX;
26335 }
26336
26337 /** Inspects program to check if all resources are as expected
26338 *
26339 * @param ignored
26340 * @param program Program instance
26341 * @param out_stream Error message
26342 *
26343 * @return true if everything is ok, false otherwise
26344 **/
26345 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program &program,
26346 std::stringstream &out_stream)
26347 {
26348 GLint stride = 0;
26349 const Utils::Type &type = Utils::Type::vec4;
26350 const GLuint type_size = type.GetSize();
26351
26352 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
26353 1 /* buf_size */, &stride);
26354
26355 if ((GLint)(3 * type_size) != stride)
26356 {
26357 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
26358
26359 return false;
26360 }
26361
26362 return true;
26363 }
26364
26365 /** Verify contents of buffers
26366 *
26367 * @param buffers Collection of buffers to be verified
26368 *
26369 * @return true if everything is as expected, false otherwise
26370 **/
26371 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection &buffers)
26372 {
26373 bool result = true;
26374
26375 bufferCollection::pair &pair = buffers.m_vector[1] /* xfb */;
26376 Utils::Buffer *buffer = pair.m_buffer;
26377 bufferDescriptor *descriptor = pair.m_descriptor;
26378
26379 /* Get pointer to contents of buffer */
26380 buffer->Bind();
26381 GLubyte *buffer_data = (GLubyte *)buffer->Map(Utils::Buffer::ReadOnly);
26382
26383 /* Get pointer to expected data */
26384 GLubyte *expected_data = (GLubyte *)&descriptor->m_expected_data[0];
26385
26386 /* Compare */
26387 static const GLuint vec4_size = 16;
26388
26389 int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size);
26390 int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size);
26391
26392 if ((0 != res_gohan) || (0 != res_goten))
26393 {
26394 m_context.getTestContext().getLog()
26395 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26396 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26397
26398 result = false;
26399 }
26400
26401 /* Release buffer mapping */
26402 buffer->UnMap();
26403
26404 return result;
26405 }
26406
26407 /** Constructor
26408 *
26409 * @param context Test context
26410 **/
26411 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context &context)
26412 : BufferTestBase(context, "xfb_capture_inactive_output_component",
26413 "Test verifies that inactive components are not modified")
26414 {
26415 /* Nothing to be done here */
26416 }
26417
26418 /** Execute drawArrays for single vertex
26419 *
26420 * @param test_case_index
26421 *
26422 * @return true
26423 **/
26424 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26425 {
26426 const Functions &gl = m_context.getRenderContext().getFunctions();
26427 GLenum primitive_type = GL_PATCHES;
26428
26429 if (TEST_VS == test_case_index)
26430 {
26431 primitive_type = GL_POINTS;
26432 }
26433
26434 gl.disable(GL_RASTERIZER_DISCARD);
26435 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26436
26437 gl.beginTransformFeedback(GL_POINTS);
26438 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26439
26440 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26441 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26442
26443 gl.endTransformFeedback();
26444 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26445
26446 return true;
26447 }
26448
26449 /** Get descriptors of buffers necessary for test
26450 *
26451 * @param ignored
26452 * @param out_descriptors Descriptors of buffers used by test
26453 **/
26454 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26455 bufferDescriptor::Vector &out_descriptors)
26456 {
26457 const Utils::Type &type = Utils::Type::vec4;
26458
26459 /* Test needs single uniform and xfb */
26460 out_descriptors.resize(2);
26461
26462 /* Get references */
26463 bufferDescriptor &uniform = out_descriptors[0];
26464 bufferDescriptor &xfb = out_descriptors[1];
26465
26466 /* Index */
26467 uniform.m_index = 0;
26468 xfb.m_index = 0;
26469
26470 /* Target */
26471 uniform.m_target = Utils::Buffer::Uniform;
26472 xfb.m_target = Utils::Buffer::Transform_feedback;
26473
26474 /* Data */
26475 const std::vector<GLubyte> &goku_data = type.GenerateData();
26476 const std::vector<GLubyte> &gohan_data = type.GenerateData();
26477 const std::vector<GLubyte> &goten_data = type.GenerateData();
26478 const std::vector<GLubyte> &chichi_data = type.GenerateData();
26479 const std::vector<GLubyte> &vegeta_data = type.GenerateData();
26480 const std::vector<GLubyte> &trunks_data = type.GenerateData();
26481 const std::vector<GLubyte> &bra_data = type.GenerateData();
26482 const std::vector<GLubyte> &bulma_data = type.GenerateData();
26483
26484 const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type);
26485 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26486
26487 /* Uniform data */
26488 uniform.m_initial_data.resize(8 * type_size);
26489 memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size);
26490 memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size);
26491 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
26492 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size);
26493 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
26494 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size);
26495 memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size);
26496 memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size);
26497
26498 /* XFB data */
26499 xfb.m_initial_data.resize(8 * type_size);
26500 xfb.m_expected_data.resize(8 * type_size);
26501
26502 for (GLuint i = 0; i < 8 * type_size; ++i)
26503 {
26504 xfb.m_initial_data[i] = (glw::GLubyte)i;
26505 xfb.m_expected_data[i] = (glw::GLubyte)i;
26506 }
26507
26508 /* goku - x, z - 32 */
26509 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size);
26510 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size);
26511
26512 /* gohan - y, w - 0 */
26513 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size);
26514 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size);
26515
26516 /* goten - x, y - 16 */
26517 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size);
26518 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size);
26519
26520 /* chichi - z, w - 48 */
26521 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size);
26522 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size);
26523
26524 /* vegeta - x - 112 */
26525 memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size);
26526
26527 /* trunks - y - 96 */
26528 memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size);
26529
26530 /* bra - z - 80 */
26531 memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size);
26532
26533 /* bulma - w - 64 */
26534 memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size);
26535 }
26536
26537 /** Get body of main function for given shader stage
26538 *
26539 * @param test_case_index Index of test case
26540 * @param stage Shader stage
26541 * @param out_assignments Set to empty
26542 * @param out_calculations Set to empty
26543 **/
26544 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26545 std::string &out_assignments, std::string &out_calculations)
26546 {
26547 out_calculations = "";
26548
26549 static const GLchar *vs_tes_gs = " goku.x = uni_goku.x ;\n"
26550 " goku.z = uni_goku.z ;\n"
26551 " gohan.y = uni_gohan.y ;\n"
26552 " gohan.w = uni_gohan.w ;\n"
26553 " goten.x = uni_goten.x ;\n"
26554 " goten.y = uni_goten.y ;\n"
26555 " chichi.z = uni_chichi.z ;\n"
26556 " chichi.w = uni_chichi.w ;\n"
26557 " vegeta.x = uni_vegeta.x ;\n"
26558 " trunks.y = uni_trunks.y ;\n"
26559 " bra.z = uni_bra.z ;\n"
26560 " bulma.w = uni_bulma.w ;\n";
26561 static const GLchar *fs = " fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n";
26562
26563 const GLchar *assignments = "";
26564
26565 switch (stage)
26566 {
26567 case Utils::Shader::FRAGMENT:
26568 assignments = fs;
26569 break;
26570
26571 case Utils::Shader::GEOMETRY:
26572 if (TEST_GS == test_case_index)
26573 {
26574 assignments = vs_tes_gs;
26575 }
26576 break;
26577
26578 case Utils::Shader::TESS_CTRL:
26579 break;
26580
26581 case Utils::Shader::TESS_EVAL:
26582 if (TEST_TES == test_case_index)
26583 {
26584 assignments = vs_tes_gs;
26585 }
26586 break;
26587
26588 case Utils::Shader::VERTEX:
26589 if (TEST_VS == test_case_index)
26590 {
26591 assignments = vs_tes_gs;
26592 }
26593 break;
26594
26595 default:
26596 TCU_FAIL("Invalid enum");
26597 }
26598
26599 out_assignments = assignments;
26600 }
26601
26602 /** Get interface of shader
26603 *
26604 * @param test_case_index Index of test case
26605 * @param stage Shader stage
26606 * @param out_interface Set to ""
26607 **/
26608 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26609 std::string &out_interface)
26610 {
26611 static const GLchar *vs_tes_gs = "const uint sizeof_type = 16;\n"
26612 "\n"
26613 "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n"
26614 "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n"
26615 "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n"
26616 "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n"
26617 "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n"
26618 "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n"
26619 "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n"
26620 "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n"
26621 "\n"
26622 "layout(binding = 0) uniform block {\n"
26623 " vec4 uni_goku;\n"
26624 " vec4 uni_gohan;\n"
26625 " vec4 uni_goten;\n"
26626 " vec4 uni_chichi;\n"
26627 " vec4 uni_vegeta;\n"
26628 " vec4 uni_trunks;\n"
26629 " vec4 uni_bra;\n"
26630 " vec4 uni_bulma;\n"
26631 "};\n";
26632 static const GLchar *fs = "in vec4 vegeta;\n"
26633 "in vec4 trunks;\n"
26634 "in vec4 bra;\n"
26635 "in vec4 bulma;\n"
26636 "in vec4 goku;\n"
26637 "in vec4 gohan;\n"
26638 "in vec4 goten;\n"
26639 "in vec4 chichi;\n"
26640 "\n"
26641 "out vec4 fs_out;\n";
26642
26643 const GLchar *interface = "";
26644
26645 switch (stage)
26646 {
26647 case Utils::Shader::FRAGMENT:
26648 interface = fs;
26649 break;
26650
26651 case Utils::Shader::GEOMETRY:
26652 if (TEST_GS == test_case_index)
26653 {
26654 interface = vs_tes_gs;
26655 }
26656 break;
26657
26658 case Utils::Shader::TESS_CTRL:
26659 break;
26660
26661 case Utils::Shader::TESS_EVAL:
26662 if (TEST_TES == test_case_index)
26663 {
26664 interface = vs_tes_gs;
26665 }
26666 break;
26667
26668 case Utils::Shader::VERTEX:
26669 if (TEST_VS == test_case_index)
26670 {
26671 interface = vs_tes_gs;
26672 }
26673 break;
26674
26675 default:
26676 TCU_FAIL("Invalid enum");
26677 }
26678
26679 out_interface = interface;
26680 }
26681
26682 /** Get source code of shader
26683 *
26684 * @param test_case_index Index of test case
26685 * @param stage Shader stage
26686 *
26687 * @return Source
26688 **/
26689 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26690 {
26691 std::string source;
26692
26693 switch (test_case_index)
26694 {
26695 case TEST_VS:
26696 switch (stage)
26697 {
26698 case Utils::Shader::FRAGMENT:
26699 case Utils::Shader::VERTEX:
26700 source = BufferTestBase::getShaderSource(test_case_index, stage);
26701 break;
26702 default:
26703 break;
26704 }
26705 break;
26706
26707 case TEST_TES:
26708 switch (stage)
26709 {
26710 case Utils::Shader::FRAGMENT:
26711 case Utils::Shader::TESS_CTRL:
26712 case Utils::Shader::TESS_EVAL:
26713 case Utils::Shader::VERTEX:
26714 source = BufferTestBase::getShaderSource(test_case_index, stage);
26715 break;
26716 default:
26717 break;
26718 }
26719 break;
26720
26721 case TEST_GS:
26722 source = BufferTestBase::getShaderSource(test_case_index, stage);
26723 break;
26724
26725 default:
26726 TCU_FAIL("Invalid enum");
26727 }
26728
26729 /* */
26730 return source;
26731 }
26732
26733 /** Get name of test case
26734 *
26735 * @param test_case_index Index of test case
26736 *
26737 * @return Name of tested stage
26738 **/
26739 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index)
26740 {
26741 const GLchar *name = 0;
26742
26743 switch (test_case_index)
26744 {
26745 case TEST_VS:
26746 name = "vertex";
26747 break;
26748 case TEST_TES:
26749 name = "tessellation evaluation";
26750 break;
26751 case TEST_GS:
26752 name = "geometry";
26753 break;
26754 default:
26755 TCU_FAIL("Invalid enum");
26756 }
26757
26758 return name;
26759 }
26760
26761 /** Returns number of test cases
26762 *
26763 * @return TEST_MAX
26764 **/
26765 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber()
26766 {
26767 return TEST_MAX;
26768 }
26769
26770 /** Verify contents of buffers
26771 *
26772 * @param buffers Collection of buffers to be verified
26773 *
26774 * @return true if everything is as expected, false otherwise
26775 **/
26776 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection &buffers)
26777 {
26778 bool result = true;
26779
26780 bufferCollection::pair &pair = buffers.m_vector[1] /* xfb */;
26781 Utils::Buffer *buffer = pair.m_buffer;
26782 bufferDescriptor *descriptor = pair.m_descriptor;
26783
26784 /* Get pointer to contents of buffer */
26785 buffer->Bind();
26786 GLubyte *buffer_data = (GLubyte *)buffer->Map(Utils::Buffer::ReadOnly);
26787
26788 /* Get pointer to expected data */
26789 GLubyte *expected_data = (GLubyte *)&descriptor->m_expected_data[0];
26790
26791 /* Compare */
26792 static const GLuint comp_size = 4;
26793 static const GLuint vec4_size = 16;
26794
26795 int res_goku_x =
26796 memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size);
26797 int res_goku_z =
26798 memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size);
26799
26800 int res_gohan_y =
26801 memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size);
26802 int res_gohan_w =
26803 memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size);
26804
26805 int res_goten_x =
26806 memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size);
26807 int res_goten_y =
26808 memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size);
26809
26810 int res_chichi_z =
26811 memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size);
26812 int res_chichi_w =
26813 memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size);
26814
26815 int res_vegeta_x =
26816 memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size);
26817
26818 int res_trunks_y =
26819 memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size);
26820
26821 int res_bra_z =
26822 memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size);
26823
26824 int res_bulma_w =
26825 memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size);
26826
26827 if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) ||
26828 (0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) ||
26829 (0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w))
26830 {
26831 m_context.getTestContext().getLog()
26832 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26833 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26834
26835 result = false;
26836 }
26837
26838 /* Release buffer mapping */
26839 buffer->UnMap();
26840
26841 return result;
26842 }
26843
26844 /** Constructor
26845 *
26846 * @param context Test context
26847 **/
26848 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context &context)
26849 : BufferTestBase(context, "xfb_capture_inactive_output_block_member",
26850 "Test verifies that inactive block members are captured")
26851 {
26852 /* Nothing to be done here */
26853 }
26854
26855 /** Execute drawArrays for single vertex
26856 *
26857 * @param test_case_index
26858 *
26859 * @return true
26860 **/
26861 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26862 {
26863 const Functions &gl = m_context.getRenderContext().getFunctions();
26864 GLenum primitive_type = GL_PATCHES;
26865
26866 if (TEST_VS == test_case_index)
26867 {
26868 primitive_type = GL_POINTS;
26869 }
26870
26871 gl.disable(GL_RASTERIZER_DISCARD);
26872 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26873
26874 gl.beginTransformFeedback(GL_POINTS);
26875 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26876
26877 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26878 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26879
26880 gl.endTransformFeedback();
26881 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26882
26883 return true;
26884 }
26885
26886 /** Get descriptors of buffers necessary for test
26887 *
26888 * @param ignored
26889 * @param out_descriptors Descriptors of buffers used by test
26890 **/
26891 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26892 bufferDescriptor::Vector &out_descriptors)
26893 {
26894 const Utils::Type &type = Utils::Type::vec4;
26895
26896 /* Test needs single uniform and xfb */
26897 out_descriptors.resize(2);
26898
26899 /* Get references */
26900 bufferDescriptor &uniform = out_descriptors[0];
26901 bufferDescriptor &xfb = out_descriptors[1];
26902
26903 /* Index */
26904 uniform.m_index = 0;
26905 xfb.m_index = 0;
26906
26907 /* Target */
26908 uniform.m_target = Utils::Buffer::Uniform;
26909 xfb.m_target = Utils::Buffer::Transform_feedback;
26910
26911 /* Data */
26912 const std::vector<GLubyte> &gohan_data = type.GenerateData();
26913 const std::vector<GLubyte> &chichi_data = type.GenerateData();
26914
26915 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26916
26917 /* Uniform data */
26918 uniform.m_initial_data.resize(2 * type_size);
26919 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26920 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26921
26922 /* XFB data */
26923 xfb.m_initial_data.resize(4 * type_size);
26924 xfb.m_expected_data.resize(4 * type_size);
26925
26926 for (GLuint i = 0; i < 4 * type_size; ++i)
26927 {
26928 xfb.m_initial_data[i] = (glw::GLubyte)i;
26929 xfb.m_expected_data[i] = (glw::GLubyte)i;
26930 }
26931
26932 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26933 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
26934 }
26935
26936 /** Get body of main function for given shader stage
26937 *
26938 * @param test_case_index Index of test case
26939 * @param stage Shader stage
26940 * @param out_assignments Set to empty
26941 * @param out_calculations Set to empty
26942 **/
26943 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26944 std::string &out_assignments, std::string &out_calculations)
26945 {
26946 out_calculations = "";
26947
26948 static const GLchar *vs_tes_gs = " chichi = uni_chichi;\n"
26949 " gohan = uni_gohan;\n";
26950 static const GLchar *fs = " fs_out = goten + gohan + chichi;\n";
26951
26952 const GLchar *assignments = "";
26953
26954 switch (stage)
26955 {
26956 case Utils::Shader::FRAGMENT:
26957 assignments = fs;
26958 break;
26959
26960 case Utils::Shader::GEOMETRY:
26961 if (TEST_GS == test_case_index)
26962 {
26963 assignments = vs_tes_gs;
26964 }
26965 break;
26966
26967 case Utils::Shader::TESS_CTRL:
26968 break;
26969
26970 case Utils::Shader::TESS_EVAL:
26971 if (TEST_TES == test_case_index)
26972 {
26973 assignments = vs_tes_gs;
26974 }
26975 break;
26976
26977 case Utils::Shader::VERTEX:
26978 if (TEST_VS == test_case_index)
26979 {
26980 assignments = vs_tes_gs;
26981 }
26982 break;
26983
26984 default:
26985 TCU_FAIL("Invalid enum");
26986 }
26987
26988 out_assignments = assignments;
26989 }
26990
26991 /** Get interface of shader
26992 *
26993 * @param test_case_index Index of test case
26994 * @param stage Shader stage
26995 * @param out_interface Set to ""
26996 **/
26997 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26998 std::string &out_interface)
26999 {
27000 static const GLchar *vs_tes_gs = "const uint sizeof_type = 16;\n"
27001 "\n"
27002 "layout (xfb_offset = 1 * sizeof_type) out Goku {\n"
27003 " vec4 gohan;\n"
27004 " vec4 goten;\n"
27005 " vec4 chichi;\n"
27006 "};\n"
27007 "\n"
27008 "layout(binding = 0) uniform block {\n"
27009 " vec4 uni_gohan;\n"
27010 " vec4 uni_chichi;\n"
27011 "};\n";
27012 static const GLchar *fs = "in Goku {\n"
27013 " vec4 gohan;\n"
27014 " vec4 goten;\n"
27015 " vec4 chichi;\n"
27016 "};\n"
27017 "out vec4 fs_out;\n";
27018
27019 const GLchar *interface = "";
27020
27021 switch (stage)
27022 {
27023 case Utils::Shader::FRAGMENT:
27024 interface = fs;
27025 break;
27026
27027 case Utils::Shader::GEOMETRY:
27028 if (TEST_GS == test_case_index)
27029 {
27030 interface = vs_tes_gs;
27031 }
27032 break;
27033
27034 case Utils::Shader::TESS_CTRL:
27035 break;
27036
27037 case Utils::Shader::TESS_EVAL:
27038 if (TEST_TES == test_case_index)
27039 {
27040 interface = vs_tes_gs;
27041 }
27042 break;
27043
27044 case Utils::Shader::VERTEX:
27045 if (TEST_VS == test_case_index)
27046 {
27047 interface = vs_tes_gs;
27048 }
27049 break;
27050
27051 default:
27052 TCU_FAIL("Invalid enum");
27053 }
27054
27055 out_interface = interface;
27056 }
27057
27058 /** Get source code of shader
27059 *
27060 * @param test_case_index Index of test case
27061 * @param stage Shader stage
27062 *
27063 * @return Source
27064 **/
27065 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint test_case_index,
27066 Utils::Shader::STAGES stage)
27067 {
27068 std::string source;
27069
27070 switch (test_case_index)
27071 {
27072 case TEST_VS:
27073 switch (stage)
27074 {
27075 case Utils::Shader::FRAGMENT:
27076 case Utils::Shader::VERTEX:
27077 source = BufferTestBase::getShaderSource(test_case_index, stage);
27078 break;
27079 default:
27080 break;
27081 }
27082 break;
27083
27084 case TEST_TES:
27085 switch (stage)
27086 {
27087 case Utils::Shader::FRAGMENT:
27088 case Utils::Shader::TESS_CTRL:
27089 case Utils::Shader::TESS_EVAL:
27090 case Utils::Shader::VERTEX:
27091 source = BufferTestBase::getShaderSource(test_case_index, stage);
27092 break;
27093 default:
27094 break;
27095 }
27096 break;
27097
27098 case TEST_GS:
27099 source = BufferTestBase::getShaderSource(test_case_index, stage);
27100 break;
27101
27102 default:
27103 TCU_FAIL("Invalid enum");
27104 }
27105
27106 /* */
27107 return source;
27108 }
27109
27110 /** Get name of test case
27111 *
27112 * @param test_case_index Index of test case
27113 *
27114 * @return Name of tested stage
27115 **/
27116 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index)
27117 {
27118 const GLchar *name = 0;
27119
27120 switch (test_case_index)
27121 {
27122 case TEST_VS:
27123 name = "vertex";
27124 break;
27125 case TEST_TES:
27126 name = "tessellation evaluation";
27127 break;
27128 case TEST_GS:
27129 name = "geometry";
27130 break;
27131 default:
27132 TCU_FAIL("Invalid enum");
27133 }
27134
27135 return name;
27136 }
27137
27138 /** Returns number of test cases
27139 *
27140 * @return TEST_MAX
27141 **/
27142 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber()
27143 {
27144 return TEST_MAX;
27145 }
27146
27147 /** Verify contents of buffers
27148 *
27149 * @param buffers Collection of buffers to be verified
27150 *
27151 * @return true if everything is as expected, false otherwise
27152 **/
27153 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection &buffers)
27154 {
27155 bool result = true;
27156
27157 bufferCollection::pair &pair = buffers.m_vector[1] /* xfb */;
27158 Utils::Buffer *buffer = pair.m_buffer;
27159 bufferDescriptor *descriptor = pair.m_descriptor;
27160
27161 /* Get pointer to contents of buffer */
27162 buffer->Bind();
27163 GLubyte *buffer_data = (GLubyte *)buffer->Map(Utils::Buffer::ReadOnly);
27164
27165 /* Get pointer to expected data */
27166 GLubyte *expected_data = (GLubyte *)&descriptor->m_expected_data[0];
27167
27168 /* Compare */
27169 static const GLuint vec4_size = 16;
27170
27171 int res_before = memcmp(buffer_data, expected_data, vec4_size);
27172 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27173 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27174
27175 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27176 {
27177 m_context.getTestContext().getLog()
27178 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27179 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27180
27181 result = false;
27182 }
27183
27184 /* Release buffer mapping */
27185 buffer->UnMap();
27186
27187 return result;
27188 }
27189
27190 /** Constructor
27191 *
27192 * @param context Test context
27193 **/
27194 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context &context)
27195 : BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured")
27196 {
27197 /* Nothing to be done here */
27198 }
27199
27200 /** Execute drawArrays for single vertex
27201 *
27202 * @param test_case_index
27203 *
27204 * @return true
27205 **/
27206 bool XFBCaptureStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
27207 {
27208 const Functions &gl = m_context.getRenderContext().getFunctions();
27209 GLenum primitive_type = GL_PATCHES;
27210
27211 if (TEST_VS == test_case_index)
27212 {
27213 primitive_type = GL_POINTS;
27214 }
27215
27216 gl.disable(GL_RASTERIZER_DISCARD);
27217 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
27218
27219 gl.beginTransformFeedback(GL_POINTS);
27220 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
27221
27222 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
27223 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
27224
27225 gl.endTransformFeedback();
27226 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
27227
27228 return true;
27229 }
27230
27231 /** Get descriptors of buffers necessary for test
27232 *
27233 * @param ignored
27234 * @param out_descriptors Descriptors of buffers used by test
27235 **/
27236 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
27237 bufferDescriptor::Vector &out_descriptors)
27238 {
27239 const Utils::Type &type = Utils::Type::vec4;
27240
27241 /* Test needs single uniform and xfb */
27242 out_descriptors.resize(2);
27243
27244 /* Get references */
27245 bufferDescriptor &uniform = out_descriptors[0];
27246 bufferDescriptor &xfb = out_descriptors[1];
27247
27248 /* Index */
27249 uniform.m_index = 0;
27250 xfb.m_index = 0;
27251
27252 /* Target */
27253 uniform.m_target = Utils::Buffer::Uniform;
27254 xfb.m_target = Utils::Buffer::Transform_feedback;
27255
27256 /* Data */
27257 const std::vector<GLubyte> &gohan_data = type.GenerateData();
27258 const std::vector<GLubyte> &chichi_data = type.GenerateData();
27259
27260 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
27261
27262 /* Uniform data */
27263 uniform.m_initial_data.resize(2 * type_size);
27264 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
27265 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
27266
27267 /* XFB data */
27268 xfb.m_initial_data.resize(4 * type_size);
27269 xfb.m_expected_data.resize(4 * type_size);
27270
27271 for (GLuint i = 0; i < 4 * type_size; ++i)
27272 {
27273 xfb.m_initial_data[i] = (glw::GLubyte)i;
27274 xfb.m_expected_data[i] = (glw::GLubyte)i;
27275 }
27276
27277 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
27278 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
27279 }
27280
27281 /** Get body of main function for given shader stage
27282 *
27283 * @param test_case_index Index of test case
27284 * @param stage Shader stage
27285 * @param out_assignments Set to empty
27286 * @param out_calculations Set to empty
27287 **/
27288 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27289 std::string &out_assignments, std::string &out_calculations)
27290 {
27291 out_calculations = "";
27292
27293 static const GLchar *vs_tes_gs = " goku.chichi = uni_chichi;\n"
27294 " goku.gohan = uni_gohan;\n";
27295 static const GLchar *fs = " fs_out = goku.goten + goku.gohan + goku.chichi;\n";
27296
27297 const GLchar *assignments = "";
27298
27299 switch (stage)
27300 {
27301 case Utils::Shader::FRAGMENT:
27302 assignments = fs;
27303 break;
27304
27305 case Utils::Shader::GEOMETRY:
27306 if (TEST_GS == test_case_index)
27307 {
27308 assignments = vs_tes_gs;
27309 }
27310 break;
27311
27312 case Utils::Shader::TESS_CTRL:
27313 break;
27314
27315 case Utils::Shader::TESS_EVAL:
27316 if (TEST_TES == test_case_index)
27317 {
27318 assignments = vs_tes_gs;
27319 }
27320 break;
27321
27322 case Utils::Shader::VERTEX:
27323 if (TEST_VS == test_case_index)
27324 {
27325 assignments = vs_tes_gs;
27326 }
27327 break;
27328
27329 default:
27330 TCU_FAIL("Invalid enum");
27331 }
27332
27333 out_assignments = assignments;
27334 }
27335
27336 /** Get interface of shader
27337 *
27338 * @param test_case_index Index of test case
27339 * @param stage Shader stage
27340 * @param out_interface Set to ""
27341 **/
27342 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27343 std::string &out_interface)
27344 {
27345 static const GLchar *vs_tes_gs = "const uint sizeof_type = 16;\n"
27346 "\n"
27347 "struct Goku {\n"
27348 " vec4 gohan;\n"
27349 " vec4 goten;\n"
27350 " vec4 chichi;\n"
27351 "};\n"
27352 "\n"
27353 "layout (xfb_offset = sizeof_type) out Goku goku;\n"
27354 "\n"
27355 "layout(binding = 0, std140) uniform block {\n"
27356 " vec4 uni_gohan;\n"
27357 " vec4 uni_chichi;\n"
27358 "};\n";
27359 static const GLchar *fs = "struct Goku {\n"
27360 " vec4 gohan;\n"
27361 " vec4 goten;\n"
27362 " vec4 chichi;\n"
27363 "};\n"
27364 "\n"
27365 "in Goku goku;\n"
27366 "\n"
27367 "out vec4 fs_out;\n";
27368
27369 const GLchar *interface = "";
27370
27371 switch (stage)
27372 {
27373 case Utils::Shader::FRAGMENT:
27374 interface = fs;
27375 break;
27376
27377 case Utils::Shader::GEOMETRY:
27378 if (TEST_GS == test_case_index)
27379 {
27380 interface = vs_tes_gs;
27381 }
27382 break;
27383
27384 case Utils::Shader::TESS_CTRL:
27385 break;
27386
27387 case Utils::Shader::TESS_EVAL:
27388 if (TEST_TES == test_case_index)
27389 {
27390 interface = vs_tes_gs;
27391 }
27392 break;
27393
27394 case Utils::Shader::VERTEX:
27395 if (TEST_VS == test_case_index)
27396 {
27397 interface = vs_tes_gs;
27398 }
27399 break;
27400
27401 default:
27402 TCU_FAIL("Invalid enum");
27403 }
27404
27405 out_interface = interface;
27406 }
27407
27408 /** Get source code of shader
27409 *
27410 * @param test_case_index Index of test case
27411 * @param stage Shader stage
27412 *
27413 * @return Source
27414 **/
27415 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27416 {
27417 std::string source;
27418
27419 switch (test_case_index)
27420 {
27421 case TEST_VS:
27422 switch (stage)
27423 {
27424 case Utils::Shader::FRAGMENT:
27425 case Utils::Shader::VERTEX:
27426 source = BufferTestBase::getShaderSource(test_case_index, stage);
27427 break;
27428 default:
27429 break;
27430 }
27431 break;
27432
27433 case TEST_TES:
27434 switch (stage)
27435 {
27436 case Utils::Shader::FRAGMENT:
27437 case Utils::Shader::TESS_CTRL:
27438 case Utils::Shader::TESS_EVAL:
27439 case Utils::Shader::VERTEX:
27440 source = BufferTestBase::getShaderSource(test_case_index, stage);
27441 break;
27442 default:
27443 break;
27444 }
27445 break;
27446
27447 case TEST_GS:
27448 source = BufferTestBase::getShaderSource(test_case_index, stage);
27449 break;
27450
27451 default:
27452 TCU_FAIL("Invalid enum");
27453 }
27454
27455 /* */
27456 return source;
27457 }
27458
27459 /** Get name of test case
27460 *
27461 * @param test_case_index Index of test case
27462 *
27463 * @return Name of tested stage
27464 **/
27465 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index)
27466 {
27467 const GLchar *name = 0;
27468
27469 switch (test_case_index)
27470 {
27471 case TEST_VS:
27472 name = "vertex";
27473 break;
27474 case TEST_TES:
27475 name = "tessellation evaluation";
27476 break;
27477 case TEST_GS:
27478 name = "geometry";
27479 break;
27480 default:
27481 TCU_FAIL("Invalid enum");
27482 }
27483
27484 return name;
27485 }
27486
27487 /** Returns number of test cases
27488 *
27489 * @return TEST_MAX
27490 **/
27491 glw::GLuint XFBCaptureStructTest::getTestCaseNumber()
27492 {
27493 return TEST_MAX;
27494 }
27495
27496 /** Verify contents of buffers
27497 *
27498 * @param buffers Collection of buffers to be verified
27499 *
27500 * @return true if everything is as expected, false otherwise
27501 **/
27502 bool XFBCaptureStructTest::verifyBuffers(bufferCollection &buffers)
27503 {
27504 bool result = true;
27505
27506 bufferCollection::pair &pair = buffers.m_vector[1] /* xfb */;
27507 Utils::Buffer *buffer = pair.m_buffer;
27508 bufferDescriptor *descriptor = pair.m_descriptor;
27509
27510 /* Get pointer to contents of buffer */
27511 buffer->Bind();
27512 GLubyte *buffer_data = (GLubyte *)buffer->Map(Utils::Buffer::ReadOnly);
27513
27514 /* Get pointer to expected data */
27515 GLubyte *expected_data = (GLubyte *)&descriptor->m_expected_data[0];
27516
27517 /* Compare */
27518 static const GLuint vec4_size = 16;
27519
27520 int res_before = memcmp(buffer_data, expected_data, vec4_size);
27521 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27522 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27523
27524 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27525 {
27526 m_context.getTestContext().getLog()
27527 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27528 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27529
27530 result = false;
27531 }
27532
27533 /* Release buffer mapping */
27534 buffer->UnMap();
27535
27536 return result;
27537 }
27538
27539 /** Constructor
27540 *
27541 * @param context Test framework context
27542 **/
27543 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context &context)
27544 : NegativeTestBase(context, "xfb_capture_unsized_array",
27545 "Test verifies that compiler reports error when unsized array is qualified with xfb_offset")
27546 {
27547 }
27548
27549 /** Source for given test case and stage
27550 *
27551 * @param test_case_index Index of test case
27552 * @param stage Shader stage
27553 *
27554 * @return Shader source
27555 **/
27556 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27557 {
27558 #if DEBUG_NEG_REMOVE_ERROR
27559 static const GLchar *var_definition = "/* layout (xfb_offset = 0) */ out vec4 goku[];\n";
27560 #else
27561 static const GLchar *var_definition = "layout (xfb_offset = 0) out vec4 goku[];\n";
27562 #endif /* DEBUG_NEG_REMOVE_ERROR */
27563 static const GLchar *var_use = " goku[0] = result / 2;\n";
27564 static const GLchar *fs = "#version 430 core\n"
27565 "#extension GL_ARB_enhanced_layouts : require\n"
27566 "\n"
27567 "in vec4 any_fs;\n"
27568 "out vec4 fs_out;\n"
27569 "\n"
27570 "void main()\n"
27571 "{\n"
27572 " fs_out = any_fs;\n"
27573 "}\n"
27574 "\n";
27575 static const GLchar *vs_tested = "#version 430 core\n"
27576 "#extension GL_ARB_enhanced_layouts : require\n"
27577 "\n"
27578 "VAR_DEFINITION"
27579 "\n"
27580 "in vec4 in_vs;\n"
27581 "out vec4 any_fs;\n"
27582 "\n"
27583 "void main()\n"
27584 "{\n"
27585 " vec4 result = in_vs;\n"
27586 "\n"
27587 "VARIABLE_USE"
27588 "\n"
27589 " any_fs = result;\n"
27590 "}\n"
27591 "\n";
27592
27593 std::string source;
27594 testCase &test_case = m_test_cases[test_case_index];
27595
27596 if (test_case.m_stage == stage)
27597 {
27598 size_t position = 0;
27599
27600 switch (stage)
27601 {
27602 case Utils::Shader::VERTEX:
27603 source = vs_tested;
27604 break;
27605 default:
27606 TCU_FAIL("Invalid enum");
27607 }
27608
27609 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
27610 position = 0;
27611 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
27612 }
27613 else
27614 {
27615 switch (test_case.m_stage)
27616 {
27617 case Utils::Shader::VERTEX:
27618 switch (stage)
27619 {
27620 case Utils::Shader::FRAGMENT:
27621 source = fs;
27622 break;
27623 default:
27624 source = "";
27625 }
27626 break;
27627 default:
27628 TCU_FAIL("Invalid enum");
27629 }
27630 }
27631
27632 return source;
27633 }
27634
27635 /** Get description of test case
27636 *
27637 * @param test_case_index Index of test case
27638 *
27639 * @return Test case description
27640 **/
27641 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index)
27642 {
27643 std::stringstream stream;
27644 testCase &test_case = m_test_cases[test_case_index];
27645
27646 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
27647
27648 return stream.str();
27649 }
27650
27651 /** Get number of test cases
27652 *
27653 * @return Number of test cases
27654 **/
27655 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber()
27656 {
27657 return static_cast<GLuint>(m_test_cases.size());
27658 }
27659
27660 /** Selects if "compute" stage is relevant for test
27661 *
27662 * @param ignored
27663 *
27664 * @return false
27665 **/
27666 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */)
27667 {
27668 return false;
27669 }
27670
27671 /** Prepare all test cases
27672 *
27673 **/
27674 void XFBCaptureUnsizedArrayTest::testInit()
27675 {
27676 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
27677 {
27678 /* Not aplicable for */
27679 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
27680 (Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage) ||
27681 (Utils::Shader::TESS_EVAL == stage))
27682 {
27683 continue;
27684 }
27685
27686 testCase test_case = {(Utils::Shader::STAGES)stage};
27687
27688 m_test_cases.push_back(test_case);
27689 }
27690 }
27691
27692 /** Constructor
27693 *
27694 * @param context Test context
27695 **/
27696 XFBExplicitLocationTest::XFBExplicitLocationTest(deqp::Context &context)
27697 : BufferTestBase(context, "xfb_explicit_location",
27698 "Test verifies that explicit location on matrices and arrays does not impact xfb output")
27699 {
27700 /* Nothing to be done here */
27701 }
27702
27703 /** Execute drawArrays for single vertex
27704 *
27705 * @param test_case_index
27706 *
27707 * @return true
27708 **/
27709 bool XFBExplicitLocationTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
27710 {
27711 const Functions &gl = m_context.getRenderContext().getFunctions();
27712 GLenum primitive_type = GL_PATCHES;
27713 const testCase &test_case = m_test_cases[test_case_index];
27714
27715 if (Utils::Shader::VERTEX == test_case.m_stage)
27716 {
27717 primitive_type = GL_POINTS;
27718 }
27719
27720 gl.disable(GL_RASTERIZER_DISCARD);
27721 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
27722
27723 gl.beginTransformFeedback(GL_POINTS);
27724 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
27725
27726 gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
27727 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
27728
27729 gl.endTransformFeedback();
27730 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
27731
27732 return true;
27733 }
27734
27735 /** Get descriptors of buffers necessary for test
27736 *
27737 * @param test_case_index Index of test case
27738 * @param out_descriptors Descriptors of buffers used by test
27739 **/
27740 void XFBExplicitLocationTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector &out_descriptors)
27741 {
27742 const testCase &test_case = m_test_cases[test_case_index];
27743 const Utils::Type &type = test_case.m_type;
27744
27745 /* Test needs single uniform and xfb */
27746 out_descriptors.resize(2);
27747
27748 /* Get references */
27749 bufferDescriptor &uniform = out_descriptors[0];
27750 bufferDescriptor &xfb = out_descriptors[1];
27751
27752 /* Index */
27753 uniform.m_index = 0;
27754 xfb.m_index = 0;
27755
27756 /* Target */
27757 uniform.m_target = Utils::Buffer::Uniform;
27758 xfb.m_target = Utils::Buffer::Transform_feedback;
27759
27760 /* Data */
27761 const GLuint rand_start = Utils::s_rand;
27762 std::vector<GLubyte> uniform_data;
27763
27764 for (GLuint i = 0; i < std::max(test_case.m_array_size, 1u); i++)
27765 {
27766 const std::vector<GLubyte> &type_uniform_data = type.GenerateData();
27767 /**
27768 * Rule 4 of Section 7.6.2.2:
27769 *
27770 * If the member is an array of scalars or vectors, the base alignment and array stride
27771 * are set to match the base alignment of a single array element, according to rules (1),
27772 * (2), and (3), and rounded up to the base alignment of a vec4.
27773 */
27774 uniform_data.resize(Utils::align((glw::GLuint)uniform_data.size(), 16));
27775 uniform_data.insert(uniform_data.end(), type_uniform_data.begin(), type_uniform_data.end());
27776 }
27777
27778 Utils::s_rand = rand_start;
27779 std::vector<GLubyte> xfb_data;
27780
27781 for (GLuint i = 0; i < std::max(test_case.m_array_size, 1u); i++)
27782 {
27783 const std::vector<GLubyte> &type_xfb_data = type.GenerateDataPacked();
27784 xfb_data.insert(xfb_data.end(), type_xfb_data.begin(), type_xfb_data.end());
27785 }
27786
27787 const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
27788 const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
27789 /*
27790 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
27791 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
27792 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
27793 only one valid data should be initialized in xfb.m_expected_data
27794 */
27795 const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
27796 /* Uniform data */
27797 uniform.m_initial_data.resize(uni_type_size);
27798 memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
27799
27800 /* XFB data */
27801 xfb.m_initial_data.resize(xfb_data_size, 0);
27802 xfb.m_expected_data.resize(xfb_data_size);
27803
27804 if (test_case.m_stage == Utils::Shader::VERTEX)
27805 {
27806 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
27807 }
27808 else
27809 {
27810 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
27811 memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
27812 }
27813 }
27814
27815 /** Get body of main function for given shader stage
27816 *
27817 * @param test_case_index Index of test case
27818 * @param stage Shader stage
27819 * @param out_assignments Set to empty
27820 * @param out_calculations Set to empty
27821 **/
27822 void XFBExplicitLocationTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27823 std::string &out_assignments, std::string &out_calculations)
27824 {
27825 const testCase &test_case = m_test_cases[test_case_index];
27826
27827 out_calculations = "";
27828
27829 static const GLchar *vs_tes_gs = " goku = uni_goku;\n";
27830
27831 const GLchar *assignments = "";
27832
27833 if (test_case.m_stage == stage)
27834 {
27835 switch (stage)
27836 {
27837 case Utils::Shader::GEOMETRY:
27838 assignments = vs_tes_gs;
27839 break;
27840 case Utils::Shader::TESS_EVAL:
27841 assignments = vs_tes_gs;
27842 break;
27843 case Utils::Shader::VERTEX:
27844 assignments = vs_tes_gs;
27845 break;
27846 default:
27847 TCU_FAIL("Invalid enum");
27848 }
27849 }
27850 else
27851 {
27852 switch (stage)
27853 {
27854 case Utils::Shader::FRAGMENT:
27855 assignments = "";
27856 break;
27857 case Utils::Shader::GEOMETRY:
27858 case Utils::Shader::TESS_CTRL:
27859 case Utils::Shader::TESS_EVAL:
27860 case Utils::Shader::VERTEX:
27861 break;
27862 default:
27863 TCU_FAIL("Invalid enum");
27864 }
27865 }
27866
27867 out_assignments = assignments;
27868
27869 if (Utils::Shader::FRAGMENT == stage)
27870 {
27871 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
27872 }
27873 }
27874
27875 /** Get interface of shader
27876 *
27877 * @param test_case_index Index of test case
27878 * @param stage Shader stage
27879 * @param out_interface Set to ""
27880 **/
27881 void XFBExplicitLocationTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27882 std::string &out_interface)
27883 {
27884 static const GLchar *vs_tes_gs = "layout (location = 0, xfb_offset = 0) FLAT out TYPE gokuARRAY;\n"
27885 "\n"
27886 "layout(std140, binding = 0) uniform Goku {\n"
27887 " TYPE uni_gokuARRAY;\n"
27888 "};\n";
27889
27890 const testCase &test_case = m_test_cases[test_case_index];
27891 const GLchar *interface = "";
27892 const GLchar *flat = "";
27893
27894 if (test_case.m_stage == stage)
27895 {
27896 switch (stage)
27897 {
27898 case Utils::Shader::GEOMETRY:
27899 interface = vs_tes_gs;
27900 break;
27901 case Utils::Shader::TESS_EVAL:
27902 interface = vs_tes_gs;
27903 break;
27904 case Utils::Shader::VERTEX:
27905 interface = vs_tes_gs;
27906 break;
27907 default:
27908 TCU_FAIL("Invalid enum");
27909 }
27910 }
27911 else
27912 {
27913 switch (stage)
27914 {
27915 case Utils::Shader::FRAGMENT:
27916 interface = "";
27917 break;
27918 case Utils::Shader::GEOMETRY:
27919 case Utils::Shader::TESS_CTRL:
27920 case Utils::Shader::TESS_EVAL:
27921 case Utils::Shader::VERTEX:
27922 break;
27923 default:
27924 TCU_FAIL("Invalid enum");
27925 }
27926 }
27927
27928 out_interface = interface;
27929
27930 if (Utils::Type::Float != test_case.m_type.m_basic_type)
27931 {
27932 flat = "flat";
27933 }
27934
27935 /* Array size */
27936 if (0 == test_case.m_array_size)
27937 {
27938 Utils::replaceAllTokens("ARRAY", "", out_interface);
27939 }
27940 else
27941 {
27942 char buffer[16];
27943 sprintf(buffer, "[%d]", test_case.m_array_size);
27944
27945 Utils::replaceAllTokens("ARRAY", buffer, out_interface);
27946 }
27947
27948 Utils::replaceAllTokens("FLAT", flat, out_interface);
27949 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
27950 }
27951
27952 /** Get source code of shader
27953 *
27954 * @param test_case_index Index of test case
27955 * @param stage Shader stage
27956 *
27957 * @return Source
27958 **/
27959 std::string XFBExplicitLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27960 {
27961 std::string source;
27962 const testCase &test_case = m_test_cases[test_case_index];
27963
27964 switch (test_case.m_stage)
27965 {
27966 case Utils::Shader::VERTEX:
27967 switch (stage)
27968 {
27969 case Utils::Shader::FRAGMENT:
27970 case Utils::Shader::VERTEX:
27971 source = BufferTestBase::getShaderSource(test_case_index, stage);
27972 break;
27973 default:
27974 break;
27975 }
27976 break;
27977
27978 case Utils::Shader::TESS_EVAL:
27979 switch (stage)
27980 {
27981 case Utils::Shader::FRAGMENT:
27982 case Utils::Shader::TESS_CTRL:
27983 case Utils::Shader::TESS_EVAL:
27984 case Utils::Shader::VERTEX:
27985 source = BufferTestBase::getShaderSource(test_case_index, stage);
27986 break;
27987 default:
27988 break;
27989 }
27990 break;
27991
27992 case Utils::Shader::GEOMETRY:
27993 source = BufferTestBase::getShaderSource(test_case_index, stage);
27994 break;
27995
27996 default:
27997 TCU_FAIL("Invalid enum");
27998 }
27999
28000 /* */
28001 return source;
28002 }
28003
28004 /** Get name of test case
28005 *
28006 * @param test_case_index Index of test case
28007 *
28008 * @return Name of tested stage
28009 **/
28010 std::string XFBExplicitLocationTest::getTestCaseName(glw::GLuint test_case_index)
28011 {
28012 std::stringstream stream;
28013 const testCase &test_case = m_test_cases[test_case_index];
28014
28015 stream << "Type: " << test_case.m_type.GetGLSLTypeName()
28016 << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
28017
28018 return stream.str();
28019 }
28020
28021 /** Returns number of test cases
28022 *
28023 * @return TEST_MAX
28024 **/
28025 glw::GLuint XFBExplicitLocationTest::getTestCaseNumber()
28026 {
28027 return static_cast<GLuint>(m_test_cases.size());
28028 }
28029
28030 /** Prepare all test cases
28031 *
28032 **/
28033 void XFBExplicitLocationTest::testInit()
28034 {
28035 const Functions &gl = m_context.getRenderContext().getFunctions();
28036 GLint max_xfb_int;
28037
28038 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
28039 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
28040
28041 const GLuint n_types = getTypesNumber();
28042
28043 for (GLuint i = 0; i < n_types; ++i)
28044 {
28045 const Utils::Type &type = getType(i);
28046
28047 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
28048 {
28049 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
28050 (Utils::Shader::TESS_CTRL == stage))
28051 {
28052 continue;
28053 }
28054
28055 if (type.m_n_columns > 1)
28056 {
28057 testCase test_case = {(Utils::Shader::STAGES)stage, type, 0};
28058
28059 m_test_cases.push_back(test_case);
28060 }
28061
28062 for (GLuint array_size = 3; array_size > 1; array_size--)
28063 {
28064 if (type.GetNumComponents() * array_size <= GLuint(max_xfb_int))
28065 {
28066 testCase test_case = {(Utils::Shader::STAGES)stage, type, array_size};
28067
28068 m_test_cases.push_back(test_case);
28069
28070 break;
28071 }
28072 }
28073 }
28074 }
28075 }
28076
28077 /** Constructor
28078 *
28079 * @param context Test context
28080 **/
28081 XFBExplicitLocationStructTest::XFBExplicitLocationStructTest(deqp::Context &context)
28082 : BufferTestBase(context, "xfb_struct_explicit_location",
28083 "Test verifies that explicit location on structs does not impact xfb output")
28084 {
28085 /* Nothing to be done here */
28086 }
28087
28088 /** Execute drawArrays for single vertex
28089 *
28090 * @param test_case_index
28091 *
28092 * @return true
28093 **/
28094 bool XFBExplicitLocationStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
28095 {
28096 const Functions &gl = m_context.getRenderContext().getFunctions();
28097 GLenum primitive_type = GL_PATCHES;
28098 const testCase &test_case = m_test_cases[test_case_index];
28099
28100 if (Utils::Shader::VERTEX == test_case.m_stage)
28101 {
28102 primitive_type = GL_POINTS;
28103 }
28104
28105 gl.disable(GL_RASTERIZER_DISCARD);
28106 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
28107
28108 gl.beginTransformFeedback(GL_POINTS);
28109 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
28110
28111 gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
28112 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
28113
28114 gl.endTransformFeedback();
28115 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
28116
28117 return true;
28118 }
28119
28120 /** Get descriptors of buffers necessary for test
28121 *
28122 * @param test_case_index Index of test case
28123 * @param out_descriptors Descriptors of buffers used by test
28124 **/
28125 void XFBExplicitLocationStructTest::getBufferDescriptors(GLuint test_case_index,
28126 bufferDescriptor::Vector &out_descriptors)
28127 {
28128 const testCase &test_case = m_test_cases[test_case_index];
28129
28130 /* Test needs single uniform and xfb */
28131 out_descriptors.resize(2);
28132
28133 /* Get references */
28134 bufferDescriptor &uniform = out_descriptors[0];
28135 bufferDescriptor &xfb = out_descriptors[1];
28136
28137 /* Index */
28138 uniform.m_index = 0;
28139 xfb.m_index = 0;
28140
28141 /* Target */
28142 uniform.m_target = Utils::Buffer::Uniform;
28143 xfb.m_target = Utils::Buffer::Transform_feedback;
28144
28145 /* Data */
28146 const GLuint rand_start = Utils::s_rand;
28147 std::vector<GLubyte> uniform_data;
28148 GLuint max_aligment = 1;
28149
28150 for (const testType &type : test_case.m_types)
28151 {
28152 GLuint base_aligment = type.m_type.GetBaseAlignment(false);
28153 if (type.m_array_size > 0)
28154 {
28155 /**
28156 * Rule 4 of Section 7.6.2.2:
28157 *
28158 * If the member is an array of scalars or vectors, the base alignment and array stride
28159 * are set to match the base alignment of a single array element, according to rules (1),
28160 * (2), and (3), and rounded up to the base alignment of a vec4.
28161 */
28162 base_aligment = Utils::align(base_aligment, Utils::Type::vec4.GetBaseAlignment(false));
28163 }
28164
28165 max_aligment = std::max(base_aligment, max_aligment);
28166
28167 uniform_data.resize(Utils::align((glw::GLuint)uniform_data.size(), base_aligment), 0);
28168
28169 for (GLuint i = 0; i < std::max(type.m_array_size, 1u); i++)
28170 {
28171 const std::vector<GLubyte> &type_uniform_data = type.m_type.GenerateData();
28172 uniform_data.insert(uniform_data.end(), type_uniform_data.begin(), type_uniform_data.end());
28173
28174 if (type.m_array_size > 0)
28175 {
28176 uniform_data.resize(Utils::align((glw::GLuint)uniform_data.size(), base_aligment), 0);
28177 }
28178 }
28179 }
28180
28181 const GLuint struct_aligment = Utils::align(max_aligment, Utils::Type::vec4.GetBaseAlignment(false));
28182
28183 if (test_case.m_nested_struct)
28184 {
28185 uniform_data.resize(Utils::align((glw::GLuint)uniform_data.size(), struct_aligment), 0);
28186
28187 const GLuint old_size = (glw::GLuint)uniform_data.size();
28188 uniform_data.resize(2 * old_size);
28189 std::copy_n(uniform_data.begin(), old_size, uniform_data.begin() + old_size);
28190 }
28191
28192 uniform_data.resize(Utils::align((glw::GLuint)uniform_data.size(), struct_aligment), 0);
28193
28194 Utils::s_rand = rand_start;
28195 std::vector<GLubyte> xfb_data;
28196
28197 GLuint max_type_size = 1;
28198 for (const testType &type : test_case.m_types)
28199 {
28200 const GLuint basic_type_size = Utils::Type::GetTypeSize(type.m_type.m_basic_type);
28201 max_type_size = std::max(max_type_size, basic_type_size);
28202
28203 /* Align per current type's aligment requirements */
28204 xfb_data.resize(Utils::align((glw::GLuint)xfb_data.size(), basic_type_size), 0);
28205
28206 for (GLuint i = 0; i < std::max(type.m_array_size, 1u); i++)
28207 {
28208 const std::vector<GLubyte> &type_xfb_data = type.m_type.GenerateDataPacked();
28209 xfb_data.insert(xfb_data.end(), type_xfb_data.begin(), type_xfb_data.end());
28210 }
28211 }
28212
28213 if (test_case.m_nested_struct)
28214 {
28215 /* Struct has aligment requirement equal to largest requirement of its members */
28216 xfb_data.resize(Utils::align((glw::GLuint)xfb_data.size(), max_type_size), 0);
28217
28218 const GLuint old_size = (glw::GLuint)xfb_data.size();
28219 xfb_data.resize(2 * old_size);
28220 std::copy_n(xfb_data.begin(), old_size, xfb_data.begin() + old_size);
28221 }
28222
28223 xfb_data.resize(Utils::align((glw::GLuint)xfb_data.size(), max_type_size), 0);
28224
28225 const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
28226 const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
28227
28228 /* Do not exceed the minimum value of MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS */
28229 DE_ASSERT(xfb_type_size <= 64 * sizeof(GLuint));
28230
28231 /*
28232 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
28233 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
28234 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
28235 only one valid data should be initialized in xfb.m_expected_data
28236 */
28237 const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
28238 /* Uniform data */
28239 uniform.m_initial_data.resize(uni_type_size);
28240 memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
28241
28242 /* XFB data */
28243 xfb.m_initial_data.resize(xfb_data_size, 0);
28244 xfb.m_expected_data.resize(xfb_data_size);
28245
28246 if (test_case.m_stage == Utils::Shader::VERTEX)
28247 {
28248 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
28249 }
28250 else
28251 {
28252 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
28253 memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
28254 }
28255 }
28256
28257 /** Get body of main function for given shader stage
28258 *
28259 * @param test_case_index Index of test case
28260 * @param stage Shader stage
28261 * @param out_assignments Set to empty
28262 * @param out_calculations Set to empty
28263 **/
28264 void XFBExplicitLocationStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
28265 std::string &out_assignments, std::string &out_calculations)
28266 {
28267 const testCase &test_case = m_test_cases[test_case_index];
28268
28269 out_calculations = "";
28270
28271 static const GLchar *vs_tes_gs = " goku = uni_goku;\n";
28272 static const GLchar *vs_tes_gs_nested = " goku.inner_struct_a = uni_goku;\n"
28273 " goku.inner_struct_b = uni_goku;\n";
28274
28275 const GLchar *assignments = "";
28276
28277 if (test_case.m_stage == stage)
28278 {
28279 switch (stage)
28280 {
28281 case Utils::Shader::GEOMETRY:
28282 case Utils::Shader::TESS_EVAL:
28283 case Utils::Shader::VERTEX:
28284 if (test_case.m_nested_struct)
28285 {
28286 assignments = vs_tes_gs_nested;
28287 }
28288 else
28289 {
28290 assignments = vs_tes_gs;
28291 }
28292 break;
28293 default:
28294 TCU_FAIL("Invalid enum");
28295 }
28296 }
28297 else
28298 {
28299 switch (stage)
28300 {
28301 case Utils::Shader::FRAGMENT:
28302 assignments = "";
28303 break;
28304 case Utils::Shader::GEOMETRY:
28305 case Utils::Shader::TESS_CTRL:
28306 case Utils::Shader::TESS_EVAL:
28307 case Utils::Shader::VERTEX:
28308 break;
28309 default:
28310 TCU_FAIL("Invalid enum");
28311 }
28312 }
28313
28314 out_assignments = assignments;
28315 }
28316
28317 /** Get interface of shader
28318 *
28319 * @param test_case_index Index of test case
28320 * @param stage Shader stage
28321 * @param out_interface Set to ""
28322 **/
28323 void XFBExplicitLocationStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
28324 std::string &out_interface)
28325 {
28326 static const GLchar *vs_tes_gs = "struct TestStruct {\n"
28327 "STRUCT_MEMBERS"
28328 "};\n"
28329 "layout (location = 0, xfb_offset = 0) flat out TestStruct goku;\n"
28330 "\n"
28331 "layout(std140, binding = 0) uniform Goku {\n"
28332 " TestStruct uni_goku;\n"
28333 "};\n";
28334
28335 static const GLchar *vs_tes_gs_nested = "struct TestStruct {\n"
28336 "STRUCT_MEMBERS"
28337 "};\n"
28338 "struct OuterStruct {\n"
28339 " TestStruct inner_struct_a;\n"
28340 " TestStruct inner_struct_b;\n"
28341 "};\n"
28342 "layout (location = 0, xfb_offset = 0) flat out OuterStruct goku;\n"
28343 "\n"
28344 "layout(std140, binding = 0) uniform Goku {\n"
28345 " TestStruct uni_goku;\n"
28346 "};\n";
28347
28348 const testCase &test_case = m_test_cases[test_case_index];
28349 const GLchar *interface = "";
28350
28351 if (test_case.m_stage == stage)
28352 {
28353 switch (stage)
28354 {
28355 case Utils::Shader::GEOMETRY:
28356 case Utils::Shader::TESS_EVAL:
28357 case Utils::Shader::VERTEX:
28358 if (test_case.m_nested_struct)
28359 {
28360 interface = vs_tes_gs_nested;
28361 }
28362 else
28363 {
28364 interface = vs_tes_gs;
28365 }
28366 break;
28367 default:
28368 TCU_FAIL("Invalid enum");
28369 }
28370 }
28371 else
28372 {
28373 switch (stage)
28374 {
28375 case Utils::Shader::FRAGMENT:
28376 interface = "";
28377 break;
28378 case Utils::Shader::GEOMETRY:
28379 case Utils::Shader::TESS_CTRL:
28380 case Utils::Shader::TESS_EVAL:
28381 case Utils::Shader::VERTEX:
28382 break;
28383 default:
28384 TCU_FAIL("Invalid enum");
28385 }
28386 }
28387
28388 out_interface = interface;
28389
28390 std::stringstream stream;
28391
28392 char member_name = 'a';
28393 for (const testType &type : test_case.m_types)
28394 {
28395 stream << " " << type.m_type.GetGLSLTypeName() << " " << member_name++;
28396 if (type.m_array_size > 0)
28397 {
28398 stream << "[" << type.m_array_size << "]";
28399 }
28400 stream << ";\n";
28401 }
28402
28403 Utils::replaceAllTokens("STRUCT_MEMBERS", stream.str().c_str(), out_interface);
28404 }
28405
28406 /** Get source code of shader
28407 *
28408 * @param test_case_index Index of test case
28409 * @param stage Shader stage
28410 *
28411 * @return Source
28412 **/
28413 std::string XFBExplicitLocationStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
28414 {
28415 std::string source;
28416 const testCase &test_case = m_test_cases[test_case_index];
28417
28418 switch (test_case.m_stage)
28419 {
28420 case Utils::Shader::VERTEX:
28421 switch (stage)
28422 {
28423 case Utils::Shader::FRAGMENT:
28424 case Utils::Shader::VERTEX:
28425 source = BufferTestBase::getShaderSource(test_case_index, stage);
28426 break;
28427 default:
28428 break;
28429 }
28430 break;
28431
28432 case Utils::Shader::TESS_EVAL:
28433 switch (stage)
28434 {
28435 case Utils::Shader::FRAGMENT:
28436 case Utils::Shader::TESS_CTRL:
28437 case Utils::Shader::TESS_EVAL:
28438 case Utils::Shader::VERTEX:
28439 source = BufferTestBase::getShaderSource(test_case_index, stage);
28440 break;
28441 default:
28442 break;
28443 }
28444 break;
28445
28446 case Utils::Shader::GEOMETRY:
28447 source = BufferTestBase::getShaderSource(test_case_index, stage);
28448 break;
28449
28450 default:
28451 TCU_FAIL("Invalid enum");
28452 }
28453
28454 /* */
28455 return source;
28456 }
28457
28458 /** Get name of test case
28459 *
28460 * @param test_case_index Index of test case
28461 *
28462 * @return Name of tested stage
28463 **/
28464 std::string XFBExplicitLocationStructTest::getTestCaseName(glw::GLuint test_case_index)
28465 {
28466 std::stringstream stream;
28467 const testCase &test_case = m_test_cases[test_case_index];
28468
28469 stream << "Struct: { ";
28470
28471 for (const testType &type : test_case.m_types)
28472 {
28473 stream << type.m_type.GetGLSLTypeName() << "@" << type.m_array_size << ", ";
28474 }
28475
28476 stream << "}, stage: " << Utils::Shader::GetStageName(test_case.m_stage);
28477
28478 return stream.str();
28479 }
28480
28481 /** Returns number of test cases
28482 *
28483 * @return TEST_MAX
28484 **/
28485 glw::GLuint XFBExplicitLocationStructTest::getTestCaseNumber()
28486 {
28487 return static_cast<GLuint>(m_test_cases.size());
28488 }
28489
28490 /** Prepare all test cases
28491 *
28492 **/
28493 void XFBExplicitLocationStructTest::testInit()
28494 {
28495 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
28496 {
28497 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
28498 (Utils::Shader::TESS_CTRL == stage))
28499 {
28500 continue;
28501 }
28502
28503 const GLuint n_types = getTypesNumber();
28504
28505 for (GLuint i = 0; i < n_types; ++i)
28506 {
28507 const Utils::Type &type = getType(i);
28508
28509 m_test_cases.push_back(
28510 testCase{(Utils::Shader::STAGES)stage, {{Utils::Type::_float, 0}, {type, 0}}, false});
28511 }
28512
28513 for (bool is_nested_struct : {false, true})
28514 {
28515 m_test_cases.push_back(
28516 testCase{(Utils::Shader::STAGES)stage,
28517 {{Utils::Type::_double, 0}, {Utils::Type::dvec2, 0}, {Utils::Type::dmat3, 0}},
28518 is_nested_struct});
28519 m_test_cases.push_back(testCase{
28520 (Utils::Shader::STAGES)stage, {{Utils::Type::_double, 0}, {Utils::Type::vec3, 0}}, is_nested_struct});
28521 m_test_cases.push_back(testCase{
28522 (Utils::Shader::STAGES)stage, {{Utils::Type::dvec3, 0}, {Utils::Type::mat4x3, 0}}, is_nested_struct});
28523 m_test_cases.push_back(testCase{(Utils::Shader::STAGES)stage,
28524 {{Utils::Type::_float, 0},
28525 {Utils::Type::dvec3, 0},
28526 {Utils::Type::_float, 0},
28527 {Utils::Type::_double, 0}},
28528 is_nested_struct});
28529 m_test_cases.push_back(testCase{
28530 (Utils::Shader::STAGES)stage,
28531 {{Utils::Type::vec2, 0}, {Utils::Type::dvec3, 0}, {Utils::Type::_float, 0}, {Utils::Type::_double, 0}},
28532 is_nested_struct});
28533 m_test_cases.push_back(testCase{
28534 (Utils::Shader::STAGES)stage,
28535 {{Utils::Type::_double, 0}, {Utils::Type::_float, 0}, {Utils::Type::dvec2, 0}, {Utils::Type::vec3, 0}},
28536 is_nested_struct});
28537 m_test_cases.push_back(testCase{(Utils::Shader::STAGES)stage,
28538 {{Utils::Type::dmat3x4, 0},
28539 {Utils::Type::_double, 0},
28540 {Utils::Type::_float, 0},
28541 {Utils::Type::dvec2, 0}},
28542 is_nested_struct});
28543
28544 m_test_cases.push_back(
28545 testCase{(Utils::Shader::STAGES)stage,
28546 {{Utils::Type::_float, 3}, {Utils::Type::dvec3, 0}, {Utils::Type::_double, 2}},
28547 is_nested_struct});
28548 m_test_cases.push_back(testCase{(Utils::Shader::STAGES)stage,
28549 {{Utils::Type::_int, 1},
28550 {Utils::Type::_double, 1},
28551 {Utils::Type::_float, 1},
28552 {Utils::Type::dmat2x4, 1}},
28553 is_nested_struct});
28554 m_test_cases.push_back(testCase{
28555 (Utils::Shader::STAGES)stage,
28556 {{Utils::Type::_int, 5}, {Utils::Type::dvec3, 2}, {Utils::Type::uvec3, 0}, {Utils::Type::_double, 1}},
28557 is_nested_struct});
28558 m_test_cases.push_back(
28559 testCase{(Utils::Shader::STAGES)stage,
28560 {{Utils::Type::mat2x3, 3}, {Utils::Type::uvec4, 1}, {Utils::Type::dvec4, 0}},
28561 is_nested_struct});
28562 }
28563
28564 m_test_cases.push_back(testCase{(Utils::Shader::STAGES)stage,
28565 {{Utils::Type::dmat2x3, 2}, {Utils::Type::mat2x3, 2}, {Utils::Type::dvec2, 0}},
28566 false});
28567 }
28568 }
28569 } // namespace EnhancedLayouts
28570
28571 /** Constructor.
28572 *
28573 * @param context Rendering context.
28574 **/
EnhancedLayoutsTests(deqp::Context & context)28575 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context &context)
28576 : TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality")
28577 {
28578 /* Left blank on purpose */
28579 }
28580
28581 /** Initializes a texture_storage_multisample test group.
28582 *
28583 **/
init(void)28584 void EnhancedLayoutsTests::init(void)
28585 {
28586 addChild(new EnhancedLayouts::APIConstantValuesTest(m_context));
28587 addChild(new EnhancedLayouts::APIErrorsTest(m_context));
28588 addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context));
28589 addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context));
28590 addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context));
28591 addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context));
28592 addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context));
28593 addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context));
28594 addChild(new EnhancedLayouts::VaryingInvalidValueComponentTest(m_context));
28595 addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context));
28596 addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context));
28597 addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context));
28598 addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context));
28599 addChild(new EnhancedLayouts::XFBInputTest(m_context));
28600 addChild(new EnhancedLayouts::XFBAllStagesTest(m_context));
28601 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context));
28602 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context));
28603 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context));
28604 addChild(new EnhancedLayouts::XFBStrideTest(m_context));
28605
28606 addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context));
28607 addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context));
28608 addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context));
28609 addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context));
28610 addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context));
28611 addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context));
28612 addChild(new EnhancedLayouts::SSBAlignmentTest(m_context));
28613 addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context));
28614 addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context));
28615 addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context));
28616 addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context));
28617 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context));
28618 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context));
28619 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context));
28620 addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context));
28621 addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context));
28622 addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context));
28623 addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context));
28624 addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context));
28625 addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context));
28626 addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context));
28627 addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context));
28628 addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context));
28629 addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context));
28630 addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context));
28631 addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context));
28632 addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context));
28633 addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context));
28634 addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context));
28635 addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context));
28636 addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context));
28637 addChild(new EnhancedLayouts::VaryingLocationsTest(m_context));
28638 addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context));
28639 addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context));
28640 addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context));
28641 addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context));
28642 addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context));
28643 addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context));
28644 addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context));
28645 addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context));
28646 addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context));
28647 addChild(new EnhancedLayouts::XFBExplicitLocationTest(m_context));
28648 addChild(new EnhancedLayouts::XFBExplicitLocationStructTest(m_context));
28649 addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context));
28650 addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context));
28651 addChild(new EnhancedLayouts::VaryingComponentsTest(m_context));
28652 addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context));
28653 }
28654
28655 } // namespace gl4cts
28656