1 /*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2015-2016 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 */ /*! 20 * \file 21 * \brief 22 */ /*-------------------------------------------------------------------*/ 23 24 /** 25 * \file gl4cEnhancedLayoutsTests.cpp 26 * \brief Implements conformance tests for "Enhanced Layouts" functionality. 27 */ /*-------------------------------------------------------------------*/ 28 29 #include "gl4cEnhancedLayoutsTests.hpp" 30 31 #include "gluContextInfo.hpp" 32 #include "gluDefs.hpp" 33 #include "gluStrUtil.hpp" 34 #include "glwEnums.hpp" 35 #include "glwFunctions.hpp" 36 #include "tcuTestLog.hpp" 37 38 #include <algorithm> 39 #include <iomanip> 40 #include <string> 41 #include <vector> 42 43 /* DEBUG */ 44 #define USE_NSIGHT 0 45 #define DEBUG_ENBALE_MESSAGE_CALLBACK 0 46 #define DEBUG_NEG_LOG_ERROR 0 47 #define DEBUG_REPLACE_TOKEN 0 48 #define DEBUG_REPEAT_TEST_CASE 0 49 #define DEBUG_REPEATED_TEST_CASE 0 50 51 /* Texture test base */ 52 #define DEBUG_TTB_VERIFICATION_SNIPPET_STAGE 0 53 #define DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE 0 54 55 /* Tests */ 56 #define DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE 0 57 58 /* WORKAROUNDS */ 59 #define WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST 0 60 #define WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST 0 61 #define WRKARD_UNIFORMBLOCKALIGNMENT 0 62 #define WRKARD_VARYINGLOCATIONSTEST 0 63 64 using namespace glw; 65 66 namespace gl4cts 67 { 68 namespace EnhancedLayouts 69 { 70 namespace Utils 71 { 72 /** Constants used by "random" generators **/ 73 static const GLuint s_rand_start = 3; 74 static const GLuint s_rand_max = 16; 75 static const GLuint s_rand_max_half = s_rand_max / 2; 76 77 /** Seed used by "random" generators **/ 78 static GLuint s_rand = s_rand_start; 79 80 /** Get "random" unsigned int value 81 * 82 * @return Value 83 **/ 84 static GLuint GetRandUint() 85 { 86 const GLuint rand = s_rand++; 87 88 if (s_rand_max <= s_rand) 89 { 90 s_rand = s_rand_start; 91 } 92 93 return rand; 94 } 95 96 /** Get "random" int value 97 * 98 * @return Value 99 **/ 100 GLint GetRandInt() 101 { 102 const GLint rand = GetRandUint() - s_rand_max_half; 103 104 return rand; 105 } 106 107 /** Get "random" double value 108 * 109 * @return Value 110 **/ 111 GLdouble GetRandDouble() 112 { 113 const GLint rand = GetRandInt(); 114 115 GLdouble result = (GLfloat)rand / (GLdouble)s_rand_max_half; 116 117 return result; 118 } 119 120 /** Get "random" float value 121 * 122 * @return Value 123 **/ 124 GLfloat GetRandFloat() 125 { 126 const GLint rand = GetRandInt(); 127 128 GLfloat result = (GLfloat)rand / (GLfloat)s_rand_max_half; 129 130 return result; 131 } 132 133 /** String used by list routines **/ 134 static const GLchar* const g_list = "LIST"; 135 136 /** Type constants **/ 137 const Type Type::_double = Type::GetType(Type::Double, 1, 1); 138 const Type Type::dmat2 = Type::GetType(Type::Double, 2, 2); 139 const Type Type::dmat2x3 = Type::GetType(Type::Double, 2, 3); 140 const Type Type::dmat2x4 = Type::GetType(Type::Double, 2, 4); 141 const Type Type::dmat3x2 = Type::GetType(Type::Double, 3, 2); 142 const Type Type::dmat3 = Type::GetType(Type::Double, 3, 3); 143 const Type Type::dmat3x4 = Type::GetType(Type::Double, 3, 4); 144 const Type Type::dmat4x2 = Type::GetType(Type::Double, 4, 2); 145 const Type Type::dmat4x3 = Type::GetType(Type::Double, 4, 3); 146 const Type Type::dmat4 = Type::GetType(Type::Double, 4, 4); 147 const Type Type::dvec2 = Type::GetType(Type::Double, 1, 2); 148 const Type Type::dvec3 = Type::GetType(Type::Double, 1, 3); 149 const Type Type::dvec4 = Type::GetType(Type::Double, 1, 4); 150 const Type Type::_int = Type::GetType(Type::Int, 1, 1); 151 const Type Type::ivec2 = Type::GetType(Type::Int, 1, 2); 152 const Type Type::ivec3 = Type::GetType(Type::Int, 1, 3); 153 const Type Type::ivec4 = Type::GetType(Type::Int, 1, 4); 154 const Type Type::_float = Type::GetType(Type::Float, 1, 1); 155 const Type Type::mat2 = Type::GetType(Type::Float, 2, 2); 156 const Type Type::mat2x3 = Type::GetType(Type::Float, 2, 3); 157 const Type Type::mat2x4 = Type::GetType(Type::Float, 2, 4); 158 const Type Type::mat3x2 = Type::GetType(Type::Float, 3, 2); 159 const Type Type::mat3 = Type::GetType(Type::Float, 3, 3); 160 const Type Type::mat3x4 = Type::GetType(Type::Float, 3, 4); 161 const Type Type::mat4x2 = Type::GetType(Type::Float, 4, 2); 162 const Type Type::mat4x3 = Type::GetType(Type::Float, 4, 3); 163 const Type Type::mat4 = Type::GetType(Type::Float, 4, 4); 164 const Type Type::vec2 = Type::GetType(Type::Float, 1, 2); 165 const Type Type::vec3 = Type::GetType(Type::Float, 1, 3); 166 const Type Type::vec4 = Type::GetType(Type::Float, 1, 4); 167 const Type Type::uint = Type::GetType(Type::Uint, 1, 1); 168 const Type Type::uvec2 = Type::GetType(Type::Uint, 1, 2); 169 const Type Type::uvec3 = Type::GetType(Type::Uint, 1, 3); 170 const Type Type::uvec4 = Type::GetType(Type::Uint, 1, 4); 171 172 /** Generate data for type. This routine follows STD140 rules 173 * 174 * @return Vector of bytes filled with data 175 **/ 176 std::vector<GLubyte> Type::GenerateData() const 177 { 178 const GLuint alignment = GetActualAlignment(0, false); 179 180 std::vector<GLubyte> data; 181 data.resize(alignment * m_n_columns); 182 183 for (GLuint column = 0; column < m_n_columns; ++column) 184 { 185 GLvoid* ptr = (GLvoid*)&data[column * alignment]; 186 187 switch (m_basic_type) 188 { 189 case Double: 190 { 191 GLdouble* d_ptr = (GLdouble*)ptr; 192 193 for (GLuint i = 0; i < m_n_rows; ++i) 194 { 195 d_ptr[i] = GetRandDouble(); 196 } 197 } 198 break; 199 case Float: 200 { 201 GLfloat* f_ptr = (GLfloat*)ptr; 202 203 for (GLuint i = 0; i < m_n_rows; ++i) 204 { 205 f_ptr[i] = GetRandFloat(); 206 } 207 } 208 break; 209 case Int: 210 { 211 GLint* i_ptr = (GLint*)ptr; 212 213 for (GLuint i = 0; i < m_n_rows; ++i) 214 { 215 i_ptr[i] = GetRandInt(); 216 } 217 } 218 break; 219 case Uint: 220 { 221 GLuint* ui_ptr = (GLuint*)ptr; 222 223 for (GLuint i = 0; i < m_n_rows; ++i) 224 { 225 ui_ptr[i] = GetRandUint(); 226 } 227 } 228 break; 229 } 230 } 231 232 return data; 233 } 234 235 /** Generate data for type. This routine packs data tightly. 236 * 237 * @return Vector of bytes filled with data 238 **/ 239 std::vector<GLubyte> Type::GenerateDataPacked() const 240 { 241 const GLuint basic_size = GetTypeSize(m_basic_type); 242 const GLuint n_elements = m_n_columns * m_n_rows; 243 const GLuint size = basic_size * n_elements; 244 245 std::vector<GLubyte> data; 246 data.resize(size); 247 248 GLvoid* ptr = (GLvoid*)&data[0]; 249 250 switch (m_basic_type) 251 { 252 case Double: 253 { 254 GLdouble* d_ptr = (GLdouble*)ptr; 255 256 for (GLuint i = 0; i < n_elements; ++i) 257 { 258 d_ptr[i] = GetRandDouble(); 259 } 260 } 261 break; 262 case Float: 263 { 264 GLfloat* f_ptr = (GLfloat*)ptr; 265 266 for (GLuint i = 0; i < n_elements; ++i) 267 { 268 f_ptr[i] = GetRandFloat(); 269 } 270 } 271 break; 272 case Int: 273 { 274 GLint* i_ptr = (GLint*)ptr; 275 276 for (GLuint i = 0; i < n_elements; ++i) 277 { 278 i_ptr[i] = GetRandInt(); 279 } 280 } 281 break; 282 case Uint: 283 { 284 GLuint* ui_ptr = (GLuint*)ptr; 285 286 for (GLuint i = 0; i < n_elements; ++i) 287 { 288 ui_ptr[i] = GetRandUint(); 289 } 290 } 291 break; 292 } 293 294 return data; 295 } 296 297 /** Calculate "actual alignment". It work under assumption that align value is valid 298 * 299 * @param align Requested alignment, eg with "align" qualifier 300 * @param is_array Selects if an array of type or single instance should be considered 301 * 302 * @return Calculated value 303 **/ 304 GLuint Type::GetActualAlignment(GLuint align, bool is_array) const 305 { 306 const GLuint base_alignment = GetBaseAlignment(is_array); 307 308 return std::max(align, base_alignment); 309 } 310 311 /** Align given ofset with specified alignment 312 * 313 * @param offset Offset 314 * @param alignment Alignment 315 * 316 * @return Calculated value 317 **/ 318 GLuint align(GLuint offset, GLuint alignment) 319 { 320 const GLuint rest = offset % alignment; 321 322 if (0 != rest) 323 { 324 GLuint missing = alignment - rest; 325 offset += missing; 326 } 327 328 return offset; 329 } 330 331 /** Calculate "actual offset" 332 * 333 * @param start_offset Requested offset 334 * @param actual_alignment Actual alignemnt 335 * 336 * @return Calculated value 337 **/ 338 GLuint Type::GetActualOffset(GLuint start_offset, GLuint actual_alignment) 339 { 340 GLuint offset = align(start_offset, actual_alignment); 341 342 return offset; 343 } 344 345 /** Calculate "base alignment" for given type 346 * 347 * @param is_array Select if array or single instance should be considered 348 * 349 * @return Calculated value 350 **/ 351 GLuint Type::GetBaseAlignment(bool is_array) const 352 { 353 GLuint elements = 1; 354 355 switch (m_n_rows) 356 { 357 case 2: 358 elements = 2; 359 break; 360 case 3: 361 case 4: 362 elements = 4; 363 break; 364 default: 365 break; 366 } 367 368 GLuint N = GetTypeSize(m_basic_type); 369 GLuint alignment = N * elements; 370 371 if ((true == is_array) || (1 != m_n_columns)) 372 { 373 alignment = align(alignment, 16 /* vec4 alignment */); 374 } 375 376 return alignment; 377 } 378 379 /** Returns string representing GLSL constructor of type with arguments provided in data 380 * 381 * @param data Array of values that will be used as construcotr arguments. 382 * It is interpreted as tightly packed array of type matching this type. 383 * 384 * @return String in form "Type(args)" 385 **/ 386 std::string Type::GetGLSLConstructor(const GLvoid* data) const 387 { 388 const GLchar* type = GetGLSLTypeName(); 389 390 std::stringstream stream; 391 392 stream << type << "("; 393 394 /* Scalar or vector */ 395 if (1 == m_n_columns) 396 { 397 for (GLuint row = 0; row < m_n_rows; ++row) 398 { 399 switch (m_basic_type) 400 { 401 case Double: 402 stream << ((GLdouble*)data)[row]; 403 break; 404 case Float: 405 stream << ((GLfloat*)data)[row]; 406 break; 407 case Int: 408 stream << ((GLint*)data)[row]; 409 break; 410 case Uint: 411 stream << ((GLuint*)data)[row]; 412 break; 413 } 414 415 if (row + 1 != m_n_rows) 416 { 417 stream << ", "; 418 } 419 } 420 } 421 else /* Matrix: mat(vec(), vec() .. ) */ 422 { 423 const GLuint basic_size = GetTypeSize(m_basic_type); 424 // Very indescoverable defect, the column stride should be calculated by rows, such as mat2x3, which is 2, columns 3 rows, its column stride should be 3 * sizeof(float) 425 const GLuint column_stride = m_n_rows * basic_size; 426 const Type column_type = GetType(m_basic_type, 1, m_n_rows); 427 428 for (GLuint column = 0; column < m_n_columns; ++column) 429 { 430 const GLuint column_offset = column * column_stride; 431 const GLvoid* column_data = (GLubyte*)data + column_offset; 432 433 stream << column_type.GetGLSLConstructor(column_data); 434 435 if (column + 1 != m_n_columns) 436 { 437 stream << ", "; 438 } 439 } 440 } 441 442 stream << ")"; 443 444 return stream.str(); 445 } 446 447 /** Get glsl name of the type 448 * 449 * @return Name of glsl type 450 **/ 451 const glw::GLchar* Type::GetGLSLTypeName() const 452 { 453 static const GLchar* float_lut[4][4] = { 454 { "float", "vec2", "vec3", "vec4" }, 455 { 0, "mat2", "mat2x3", "mat2x4" }, 456 { 0, "mat3x2", "mat3", "mat3x4" }, 457 { 0, "mat4x2", "mat4x3", "mat4" }, 458 }; 459 460 static const GLchar* double_lut[4][4] = { 461 { "double", "dvec2", "dvec3", "dvec4" }, 462 { 0, "dmat2", "dmat2x3", "dmat2x4" }, 463 { 0, "dmat3x2", "dmat3", "dmat3x4" }, 464 { 0, "dmat4x2", "dmat4x3", "dmat4" }, 465 }; 466 467 static const GLchar* int_lut[4] = { "int", "ivec2", "ivec3", "ivec4" }; 468 469 static const GLchar* uint_lut[4] = { "uint", "uvec2", "uvec3", "uvec4" }; 470 471 const GLchar* result = 0; 472 473 if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows)) 474 { 475 return 0; 476 } 477 478 switch (m_basic_type) 479 { 480 case Float: 481 result = float_lut[m_n_columns - 1][m_n_rows - 1]; 482 break; 483 case Double: 484 result = double_lut[m_n_columns - 1][m_n_rows - 1]; 485 break; 486 case Int: 487 result = int_lut[m_n_rows - 1]; 488 break; 489 case Uint: 490 result = uint_lut[m_n_rows - 1]; 491 break; 492 default: 493 TCU_FAIL("Invliad enum"); 494 } 495 496 return result; 497 } 498 499 /** Get number of locations required for the type 500 * 501 * @return Number of columns times: 502 * - 2 when type is double with 3 or 4 rows, 503 * - 1 otherwise or if it's a vertex shader input. 504 **/ 505 GLuint Type::GetLocations(bool is_vs_input) const 506 { 507 GLuint n_loc_per_column; 508 509 /* 1 or 2 doubles any for rest */ 510 if ((2 >= m_n_rows) || (Double != m_basic_type) || is_vs_input) 511 { 512 n_loc_per_column = 1; 513 } 514 else 515 { 516 /* 3 and 4 doubles */ 517 n_loc_per_column = 2; 518 } 519 520 return n_loc_per_column * m_n_columns; 521 } 522 523 /** Get size of the type in bytes. 524 * Note that this routine doesn't consider arrays and assumes 525 * column_major matrices. 526 * 527 * @return Formula: 528 * - If std140 packaging and matrix; number of columns * base alignment 529 * - Otherwise; number of elements * sizeof(base_type) 530 **/ 531 GLuint Type::GetSize(const bool is_std140) const 532 { 533 const GLuint basic_type_size = GetTypeSize(m_basic_type); 534 const GLuint n_elements = m_n_columns * m_n_rows; 535 536 if (is_std140 && m_n_columns > 1) 537 { 538 return m_n_columns * GetBaseAlignment(false); 539 } 540 541 return basic_type_size * n_elements; 542 } 543 544 /** Get GLenum representing the type 545 * 546 * @return GLenum 547 **/ 548 GLenum Type::GetTypeGLenum() const 549 { 550 static const GLenum float_lut[4][4] = { 551 { GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 }, 552 { 0, GL_FLOAT_MAT2, GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4 }, 553 { 0, GL_FLOAT_MAT3x2, GL_FLOAT_MAT3, GL_FLOAT_MAT3x4 }, 554 { 0, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3, GL_FLOAT_MAT4 }, 555 }; 556 557 static const GLenum double_lut[4][4] = { 558 { GL_DOUBLE, GL_DOUBLE_VEC2, GL_DOUBLE_VEC3, GL_DOUBLE_VEC4 }, 559 { 0, GL_DOUBLE_MAT2, GL_DOUBLE_MAT2x3, GL_DOUBLE_MAT2x4 }, 560 { 0, GL_DOUBLE_MAT3x2, GL_DOUBLE_MAT3, GL_DOUBLE_MAT3x4 }, 561 { 0, GL_DOUBLE_MAT4x2, GL_DOUBLE_MAT4x3, GL_DOUBLE_MAT4 }, 562 }; 563 564 static const GLenum int_lut[4] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 }; 565 566 static const GLenum uint_lut[4] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, 567 GL_UNSIGNED_INT_VEC4 }; 568 569 GLenum result = 0; 570 571 if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows)) 572 { 573 return 0; 574 } 575 576 switch (m_basic_type) 577 { 578 case Float: 579 result = float_lut[m_n_columns - 1][m_n_rows - 1]; 580 break; 581 case Double: 582 result = double_lut[m_n_columns - 1][m_n_rows - 1]; 583 break; 584 case Int: 585 result = int_lut[m_n_rows - 1]; 586 break; 587 case Uint: 588 result = uint_lut[m_n_rows - 1]; 589 break; 590 default: 591 TCU_FAIL("Invliad enum"); 592 } 593 594 return result; 595 } 596 597 /** Calculate the numbe of components consumed by a type 598 * according to 11.1.2.1 Output Variables 599 * 600 * @return Calculated number of components for the type 601 **/ 602 GLuint Type::GetNumComponents() const 603 { 604 // Rule 3 of Section 7.6.2.2 605 // If the member is a three-component vector with components consuming N 606 // basic machine units, the base alignment is 4N. 607 GLuint num_components = (m_n_rows == 3 ? 4 : m_n_rows) * m_n_columns; 608 609 if (m_basic_type == Double) 610 { 611 num_components *= 2; 612 } 613 614 return num_components; 615 } 616 617 /** Calculate stride for the type according to std140 rules 618 * 619 * @param alignment Alignment of type 620 * @param n_columns Number of columns 621 * @param n_array_elements Number of elements in array 622 * 623 * @return Calculated value 624 **/ 625 GLuint Type::CalculateStd140Stride(GLuint alignment, GLuint n_columns, GLuint n_array_elements) 626 { 627 GLuint stride = alignment * n_columns; 628 if (0 != n_array_elements) 629 { 630 stride *= n_array_elements; 631 } 632 633 return stride; 634 } 635 636 /** Check if glsl support matrices for specific basic type 637 * 638 * @param type Basic type 639 * 640 * @return true if matrices of <type> are supported, false otherwise 641 **/ 642 bool Type::DoesTypeSupportMatrix(TYPES type) 643 { 644 bool result = false; 645 646 switch (type) 647 { 648 case Float: 649 case Double: 650 result = true; 651 break; 652 case Int: 653 case Uint: 654 result = false; 655 break; 656 default: 657 TCU_FAIL("Invliad enum"); 658 } 659 660 return result; 661 } 662 663 /** Creates instance of Type 664 * 665 * @param basic_type Select basic type of instance 666 * @param n_columns Number of columns 667 * @param n_rows Number of rows 668 * 669 * @return Type instance 670 **/ 671 Type Type::GetType(TYPES basic_type, glw::GLuint n_columns, glw::GLuint n_rows) 672 { 673 Type type = { basic_type, n_columns, n_rows }; 674 675 return type; 676 } 677 678 /** Get Size of given type in bytes 679 * 680 * @param type 681 * 682 * @return Size of type 683 **/ 684 GLuint Type::GetTypeSize(TYPES type) 685 { 686 GLuint result = 0; 687 688 switch (type) 689 { 690 case Float: 691 result = sizeof(GLfloat); 692 break; 693 case Double: 694 result = sizeof(GLdouble); 695 break; 696 case Int: 697 result = sizeof(GLint); 698 break; 699 case Uint: 700 result = sizeof(GLuint); 701 break; 702 default: 703 TCU_FAIL("Invalid enum"); 704 } 705 706 return result; 707 } 708 709 /** Get GLenum representing given type 710 * 711 * @param type 712 * 713 * @return GLenum value 714 **/ 715 GLenum Type::GetTypeGLenum(TYPES type) 716 { 717 GLenum result = 0; 718 719 switch (type) 720 { 721 case Float: 722 result = GL_FLOAT; 723 break; 724 case Double: 725 result = GL_DOUBLE; 726 break; 727 case Int: 728 result = GL_INT; 729 break; 730 case Uint: 731 result = GL_UNSIGNED_INT; 732 break; 733 default: 734 TCU_FAIL("Invalid enum"); 735 } 736 737 return result; 738 } 739 740 /** Get proper glUniformNdv routine for vectors with specified number of rows 741 * 742 * @param gl GL functions 743 * @param n_rows Number of rows 744 * 745 * @return Function address 746 **/ 747 uniformNdv getUniformNdv(const glw::Functions& gl, glw::GLuint n_rows) 748 { 749 uniformNdv result = 0; 750 751 switch (n_rows) 752 { 753 case 1: 754 result = gl.uniform1dv; 755 break; 756 case 2: 757 result = gl.uniform2dv; 758 break; 759 case 3: 760 result = gl.uniform3dv; 761 break; 762 case 4: 763 result = gl.uniform4dv; 764 break; 765 default: 766 TCU_FAIL("Invalid number of rows"); 767 } 768 769 return result; 770 } 771 772 /** Get proper glUniformNfv routine for vectors with specified number of rows 773 * 774 * @param gl GL functions 775 * @param n_rows Number of rows 776 * 777 * @return Function address 778 **/ 779 uniformNfv getUniformNfv(const glw::Functions& gl, glw::GLuint n_rows) 780 { 781 uniformNfv result = 0; 782 783 switch (n_rows) 784 { 785 case 1: 786 result = gl.uniform1fv; 787 break; 788 case 2: 789 result = gl.uniform2fv; 790 break; 791 case 3: 792 result = gl.uniform3fv; 793 break; 794 case 4: 795 result = gl.uniform4fv; 796 break; 797 default: 798 TCU_FAIL("Invalid number of rows"); 799 } 800 801 return result; 802 } 803 804 /** Get proper glUniformNiv routine for vectors with specified number of rows 805 * 806 * @param gl GL functions 807 * @param n_rows Number of rows 808 * 809 * @return Function address 810 **/ 811 uniformNiv getUniformNiv(const glw::Functions& gl, glw::GLuint n_rows) 812 { 813 uniformNiv result = 0; 814 815 switch (n_rows) 816 { 817 case 1: 818 result = gl.uniform1iv; 819 break; 820 case 2: 821 result = gl.uniform2iv; 822 break; 823 case 3: 824 result = gl.uniform3iv; 825 break; 826 case 4: 827 result = gl.uniform4iv; 828 break; 829 default: 830 TCU_FAIL("Invalid number of rows"); 831 } 832 833 return result; 834 } 835 836 /** Get proper glUniformNuiv routine for vectors with specified number of rows 837 * 838 * @param gl GL functions 839 * @param n_rows Number of rows 840 * 841 * @return Function address 842 **/ 843 uniformNuiv getUniformNuiv(const glw::Functions& gl, glw::GLuint n_rows) 844 { 845 uniformNuiv result = 0; 846 847 switch (n_rows) 848 { 849 case 1: 850 result = gl.uniform1uiv; 851 break; 852 case 2: 853 result = gl.uniform2uiv; 854 break; 855 case 3: 856 result = gl.uniform3uiv; 857 break; 858 case 4: 859 result = gl.uniform4uiv; 860 break; 861 default: 862 TCU_FAIL("Invalid number of rows"); 863 } 864 865 return result; 866 } 867 868 /** Get proper glUniformMatrixNdv routine for matrix with specified number of columns and rows 869 * 870 * @param gl GL functions 871 * @param n_rows Number of rows 872 * 873 * @return Function address 874 **/ 875 uniformMatrixNdv getUniformMatrixNdv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows) 876 { 877 uniformMatrixNdv result = 0; 878 879 switch (n_columns) 880 { 881 case 2: 882 switch (n_rows) 883 { 884 case 2: 885 result = gl.uniformMatrix2dv; 886 break; 887 case 3: 888 result = gl.uniformMatrix2x3dv; 889 break; 890 case 4: 891 result = gl.uniformMatrix2x4dv; 892 break; 893 default: 894 TCU_FAIL("Invalid number of rows"); 895 } 896 break; 897 case 3: 898 switch (n_rows) 899 { 900 case 2: 901 result = gl.uniformMatrix3x2dv; 902 break; 903 case 3: 904 result = gl.uniformMatrix3dv; 905 break; 906 case 4: 907 result = gl.uniformMatrix3x4dv; 908 break; 909 default: 910 TCU_FAIL("Invalid number of rows"); 911 } 912 break; 913 case 4: 914 switch (n_rows) 915 { 916 case 2: 917 result = gl.uniformMatrix4x2dv; 918 break; 919 case 3: 920 result = gl.uniformMatrix4x3dv; 921 break; 922 case 4: 923 result = gl.uniformMatrix4dv; 924 break; 925 default: 926 TCU_FAIL("Invalid number of rows"); 927 } 928 break; 929 default: 930 TCU_FAIL("Invalid number of columns"); 931 } 932 933 return result; 934 } 935 936 /** Get proper glUniformMatrixNfv routine for vectors with specified number of columns and rows 937 * 938 * @param gl GL functions 939 * @param n_rows Number of rows 940 * 941 * @return Function address 942 **/ 943 uniformMatrixNfv getUniformMatrixNfv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows) 944 { 945 uniformMatrixNfv result = 0; 946 947 switch (n_columns) 948 { 949 case 2: 950 switch (n_rows) 951 { 952 case 2: 953 result = gl.uniformMatrix2fv; 954 break; 955 case 3: 956 result = gl.uniformMatrix2x3fv; 957 break; 958 case 4: 959 result = gl.uniformMatrix2x4fv; 960 break; 961 default: 962 TCU_FAIL("Invalid number of rows"); 963 } 964 break; 965 case 3: 966 switch (n_rows) 967 { 968 case 2: 969 result = gl.uniformMatrix3x2fv; 970 break; 971 case 3: 972 result = gl.uniformMatrix3fv; 973 break; 974 case 4: 975 result = gl.uniformMatrix3x4fv; 976 break; 977 default: 978 TCU_FAIL("Invalid number of rows"); 979 } 980 break; 981 case 4: 982 switch (n_rows) 983 { 984 case 2: 985 result = gl.uniformMatrix4x2fv; 986 break; 987 case 3: 988 result = gl.uniformMatrix4x3fv; 989 break; 990 case 4: 991 result = gl.uniformMatrix4fv; 992 break; 993 default: 994 TCU_FAIL("Invalid number of rows"); 995 } 996 break; 997 default: 998 TCU_FAIL("Invalid number of columns"); 999 } 1000 1001 return result; 1002 } 1003 1004 bool verifyVarying(Program& program, const std::string& parent_name, const Variable::Descriptor& desc, 1005 std::stringstream& stream, bool is_input) 1006 { 1007 GLint component = 0; 1008 GLuint index = 0; 1009 GLenum interface = GL_PROGRAM_INPUT; 1010 GLint location = 0; 1011 1012 if (false == is_input) 1013 { 1014 interface = GL_PROGRAM_OUTPUT; 1015 } 1016 1017 const std::string& name = Utils::Variable::GetReference(parent_name, desc, Utils::Variable::BASIC, 0); 1018 1019 try 1020 { 1021 index = program.GetResourceIndex(name, interface); 1022 1023 program.GetResource(interface, index, GL_LOCATION, 1 /* size */, &location); 1024 program.GetResource(interface, index, GL_LOCATION_COMPONENT, 1 /* size */, &component); 1025 } 1026 catch (std::exception& exc) 1027 { 1028 stream << "Failed to query program for varying: " << desc.m_name << ". Reason: " << exc.what() << "\n"; 1029 1030 return false; 1031 } 1032 1033 bool result = true; 1034 1035 if (location != desc.m_expected_location) 1036 { 1037 stream << "Attribute: " << desc.m_name << " - invalid location: " << location 1038 << " expected: " << desc.m_expected_location << std::endl; 1039 result = false; 1040 } 1041 if (component != desc.m_expected_component) 1042 { 1043 stream << "Attribute: " << desc.m_name << " - invalid component: " << component 1044 << " expected: " << desc.m_expected_component << std::endl; 1045 result = false; 1046 } 1047 1048 return result; 1049 } 1050 1051 /** Query program resource for given variable and verify that everything is as expected 1052 * 1053 * @param program Program object 1054 * @param variable Variable object 1055 * @param stream Stream that will be used to log any error 1056 * @param is_input Selects if varying is input or output 1057 * 1058 * @return true if verification is positive, false otherwise 1059 **/ 1060 bool checkVarying(Program& program, Shader::STAGES stage, const Variable& variable, std::stringstream& stream, bool is_input) 1061 { 1062 bool result = true; 1063 1064 if (variable.IsBlock()) 1065 { 1066 Utils::Interface* interface = variable.m_descriptor.m_interface; 1067 const size_t n_members = interface->m_members.size(); 1068 1069 for (size_t i = 0; i < n_members; ++i) 1070 { 1071 const Variable::Descriptor& member = interface->m_members[i]; 1072 bool member_result = verifyVarying(program, interface->m_name, member, stream, is_input); 1073 1074 if (false == member_result) 1075 { 1076 result = false; 1077 } 1078 } 1079 } 1080 /* 1081 To query the the location of struct member by glGetProgramResource, we need pass the variable name "gs_fs_output[0].single", 1082 but in original implementation, the test pass the name "Data.single", which can't get any valid result. 1083 struct Data { 1084 dmat2 single; 1085 dmat2 array[1]; 1086 }; 1087 layout (location = 0) in Data gs_fs_output[1]; 1088 */ 1089 else if (variable.IsStruct()) 1090 { 1091 Utils::Interface* interface = variable.m_descriptor.m_interface; 1092 const size_t n_members = interface->m_members.size(); 1093 std::string structVariable = variable.m_descriptor.m_name; 1094 1095 switch (Variable::GetFlavour(stage, is_input ? Variable::INPUT : Variable::OUTPUT)) 1096 { 1097 case Variable::ARRAY: 1098 case Variable::INDEXED_BY_INVOCATION_ID: 1099 structVariable.append("[0]"); 1100 break; 1101 default: 1102 break; 1103 } 1104 1105 // If struct variable is an array 1106 if (0 != variable.m_descriptor.m_n_array_elements) 1107 { 1108 for (GLuint i = 0; i < variable.m_descriptor.m_n_array_elements; i++) 1109 { 1110 GLchar buffer[16]; 1111 sprintf(buffer, "%d", i); 1112 structVariable.append("["); 1113 structVariable.append(buffer); 1114 structVariable.append("]"); 1115 for (size_t j = 0; j < n_members; ++j) 1116 { 1117 const Variable::Descriptor& member = interface->m_members[j]; 1118 bool member_result = verifyVarying(program, structVariable, member, stream, is_input); 1119 1120 if (false == member_result) 1121 { 1122 result = false; 1123 } 1124 } 1125 } 1126 } 1127 else 1128 { 1129 for (GLuint i = 0; i < n_members; ++i) 1130 { 1131 const Variable::Descriptor& member = interface->m_members[i]; 1132 bool member_result = verifyVarying(program, structVariable, member, stream, is_input); 1133 1134 if (false == member_result) 1135 { 1136 result = false; 1137 } 1138 } 1139 } 1140 } 1141 else 1142 { 1143 result = verifyVarying(program, "", variable.m_descriptor, stream, is_input); 1144 } 1145 return result; 1146 } 1147 1148 /** Query program resource for given variable and verify that everything is as expected 1149 * 1150 * @param program Program object 1151 * @param variable Variable object 1152 * @param stream Stream that will be used to log any error 1153 * 1154 * @return true if verification is positive, false otherwise 1155 **/ 1156 bool checkUniform(Program& program, const Utils::Variable& variable, std::stringstream& stream) 1157 { 1158 bool result = true; 1159 1160 if (false == variable.IsBlock()) 1161 { 1162 TCU_FAIL("Not implemented"); 1163 } 1164 else 1165 { 1166 Utils::Interface* interface = variable.m_descriptor.m_interface; 1167 1168 size_t size = interface->m_members.size(); 1169 1170 std::vector<GLuint> indices; 1171 std::vector<const char*> names; 1172 std::vector<std::string> names_str; 1173 std::vector<GLint> offsets; 1174 1175 indices.resize(size); 1176 names.resize(size); 1177 names_str.resize(size); 1178 offsets.resize(size); 1179 1180 for (size_t i = 0; i < size; ++i) 1181 { 1182 indices[i] = 0; 1183 offsets[i] = 0; 1184 1185 const std::string& name = 1186 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0); 1187 1188 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type) 1189 { 1190 const std::string& member_name = Utils::Variable::GetReference( 1191 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0); 1192 1193 names_str[i] = member_name; 1194 } 1195 else 1196 { 1197 names_str[i] = name; 1198 } 1199 1200 names[i] = names_str[i].c_str(); 1201 } 1202 1203 try 1204 { 1205 program.GetUniformIndices(static_cast<glw::GLsizei>(size), &names[0], &indices[0]); 1206 program.GetActiveUniformsiv(static_cast<glw::GLsizei>(size), &indices[0], GL_UNIFORM_OFFSET, &offsets[0]); 1207 } 1208 catch (std::exception& exc) 1209 { 1210 stream << "Failed to query program for uniforms in block: " << variable.m_descriptor.m_name 1211 << ". Reason: " << exc.what() << "\n"; 1212 1213 return false; 1214 } 1215 1216 for (size_t i = 0; i < size; ++i) 1217 { 1218 Utils::Variable::Descriptor& desc = interface->m_members[i]; 1219 1220 if (offsets[i] != (GLint)desc.m_offset) 1221 { 1222 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offsets[i] 1223 << " expected: " << desc.m_offset << std::endl; 1224 result = false; 1225 } 1226 } 1227 } 1228 1229 return result; 1230 } 1231 1232 /** Query program resource for given variable and verify that everything is as expected 1233 * 1234 * @param program Program object 1235 * @param variable Variable object 1236 * @param stream Stream that will be used to log any error 1237 * 1238 * @return true if verification is positive, false otherwise 1239 **/ 1240 bool checkSSB(Program& program, const Utils::Variable& variable, std::stringstream& stream) 1241 { 1242 bool result = true; 1243 1244 if (false == variable.IsBlock()) 1245 { 1246 TCU_FAIL("Not implemented"); 1247 } 1248 else 1249 { 1250 Utils::Interface* interface = variable.m_descriptor.m_interface; 1251 1252 size_t size = interface->m_members.size(); 1253 1254 for (size_t i = 0; i < size; ++i) 1255 { 1256 GLuint index = 0; 1257 std::string name_str = ""; 1258 GLint offset = 0; 1259 1260 const std::string& name = 1261 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0); 1262 1263 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type) 1264 { 1265 const std::string& member_name = Utils::Variable::GetReference( 1266 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0); 1267 1268 name_str = member_name; 1269 } 1270 else 1271 { 1272 name_str = name; 1273 } 1274 1275 try 1276 { 1277 index = program.GetResourceIndex(name_str, GL_BUFFER_VARIABLE); 1278 1279 program.GetResource(GL_BUFFER_VARIABLE, index, GL_OFFSET, 1, &offset); 1280 } 1281 catch (std::exception& exc) 1282 { 1283 stream << "Failed to query program for buffer variable: " << variable.m_descriptor.m_name 1284 << ". Reason: " << exc.what() << "\n"; 1285 1286 return false; 1287 } 1288 1289 Utils::Variable::Descriptor& desc = interface->m_members[i]; 1290 1291 if (offset != (GLint)desc.m_offset) 1292 { 1293 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offset 1294 << " expected: " << desc.m_offset << std::endl; 1295 result = false; 1296 } 1297 } 1298 } 1299 1300 return result; 1301 } 1302 1303 /** Query program resources at given stage and verifies results 1304 * 1305 * @param program Program object 1306 * @param program_interface Definition of program interface 1307 * @param stage Stage to be verified 1308 * @param check_inputs Select if inputs should be verified 1309 * @param check_outputs Select if output should be verified 1310 * @param check_uniforms Select if uniforms should be verified 1311 * @param check_ssbs Select if buffers should be verified 1312 * @param stream Stream that will be used to log any error 1313 * 1314 * @return true if verification is positive, false otherwise 1315 **/ 1316 bool checkProgramStage(Program& program, const ProgramInterface& program_interface, Utils::Shader::STAGES stage, 1317 bool check_inputs, bool check_outputs, bool check_uniforms, bool check_ssbs, 1318 std::stringstream& stream) 1319 { 1320 typedef Variable::PtrVector::const_iterator const_iterator; 1321 1322 const ShaderInterface& interface = program_interface.GetShaderInterface(stage); 1323 1324 bool result = true; 1325 1326 /* Inputs */ 1327 if (true == check_inputs) 1328 { 1329 const Variable::PtrVector& inputs = interface.m_inputs; 1330 1331 for (const_iterator it = inputs.begin(); it != inputs.end(); ++it) 1332 { 1333 if (false == checkVarying(program, stage, **it, stream, true)) 1334 { 1335 result = false; 1336 } 1337 } 1338 } 1339 1340 /* Outputs */ 1341 if (true == check_outputs) 1342 { 1343 const Variable::PtrVector& outputs = interface.m_outputs; 1344 1345 for (const_iterator it = outputs.begin(); it != outputs.end(); ++it) 1346 { 1347 if (false == checkVarying(program, stage, **it, stream, false)) 1348 { 1349 result = false; 1350 } 1351 } 1352 } 1353 1354 /* Uniforms */ 1355 if (true == check_uniforms) 1356 { 1357 const Variable::PtrVector& uniforms = interface.m_uniforms; 1358 1359 for (const_iterator it = uniforms.begin(); it != uniforms.end(); ++it) 1360 { 1361 if (false == checkUniform(program, **it, stream)) 1362 { 1363 result = false; 1364 } 1365 } 1366 } 1367 1368 /* SSBs */ 1369 if (true == check_ssbs) 1370 { 1371 const Variable::PtrVector& ssbs = interface.m_ssb_blocks; 1372 1373 for (const_iterator it = ssbs.begin(); it != ssbs.end(); ++it) 1374 { 1375 if (false == checkSSB(program, **it, stream)) 1376 { 1377 result = false; 1378 } 1379 } 1380 } 1381 1382 return result; 1383 } 1384 1385 /** Query resources of monolithic compute program and verifies results 1386 * 1387 * @param program Program object 1388 * @param program_interface Definition of program interface 1389 * @param stream Stream that will be used to log any error 1390 * 1391 * @return true if verification is positive, false otherwise 1392 **/ 1393 bool checkMonolithicComputeProgramInterface(Program& program, const ProgramInterface& program_interface, 1394 std::stringstream& stream) 1395 { 1396 bool result = true; 1397 1398 if (false == checkProgramStage(program, program_interface, Shader::COMPUTE, false, false, true, true, stream)) 1399 { 1400 result = false; 1401 } 1402 1403 /* Done */ 1404 return result; 1405 } 1406 1407 /** Query resources of monolithic draw program and verifies results 1408 * 1409 * @param program Program object 1410 * @param program_interface Definition of program interface 1411 * @param stream Stream that will be used to log any error 1412 * 1413 * @return true if verification is positive, false otherwise 1414 **/ 1415 bool checkMonolithicDrawProgramInterface(Program& program, const ProgramInterface& program_interface, 1416 std::stringstream& stream) 1417 { 1418 bool result = true; 1419 1420 if (false == checkProgramStage(program, program_interface, Shader::VERTEX, true, false, true, true, stream)) 1421 { 1422 result = false; 1423 } 1424 1425 /* Done */ 1426 return result; 1427 } 1428 1429 /** Query resources of separable draw program and verifies results 1430 * 1431 * @param program Program object 1432 * @param program_interface Definition of program interface 1433 * @param stream Stream that will be used to log any error 1434 * 1435 * @return true if verification is positive, false otherwise 1436 **/ 1437 bool checkSeparableDrawProgramInterface(Program& program, const ProgramInterface& program_interface, 1438 Utils::Shader::STAGES stage, std::stringstream& stream) 1439 { 1440 bool result = true; 1441 1442 if (false == checkProgramStage(program, program_interface, stage, true, true, true, true, stream)) 1443 { 1444 result = false; 1445 } 1446 1447 /* Done */ 1448 return result; 1449 } 1450 1451 /** Check if extension is supported 1452 * 1453 * @param context Test context 1454 * @param extension_name Name of extension 1455 * 1456 * @return true if extension is supported, false otherwise 1457 **/ 1458 bool isExtensionSupported(deqp::Context& context, const GLchar* extension_name) 1459 { 1460 const std::vector<std::string>& extensions = context.getContextInfo().getExtensions(); 1461 1462 if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end()) 1463 { 1464 return false; 1465 } 1466 1467 return true; 1468 } 1469 1470 /** Check if GL context meets version requirements 1471 * 1472 * @param gl Functions 1473 * @param required_major Minimum required MAJOR_VERSION 1474 * @param required_minor Minimum required MINOR_VERSION 1475 * 1476 * @return true if GL context version is at least as requested, false otherwise 1477 **/ 1478 bool isGLVersionAtLeast(const Functions& gl, GLint required_major, GLint required_minor) 1479 { 1480 glw::GLint major = 0; 1481 glw::GLint minor = 0; 1482 1483 gl.getIntegerv(GL_MAJOR_VERSION, &major); 1484 gl.getIntegerv(GL_MINOR_VERSION, &minor); 1485 1486 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 1487 1488 if (major > required_major) 1489 { 1490 /* Major is higher than required one */ 1491 return true; 1492 } 1493 else if (major == required_major) 1494 { 1495 if (minor >= required_minor) 1496 { 1497 /* Major is equal to required one */ 1498 /* Minor is higher than or equal to required one */ 1499 return true; 1500 } 1501 else 1502 { 1503 /* Major is equal to required one */ 1504 /* Minor is lower than required one */ 1505 return false; 1506 } 1507 } 1508 else 1509 { 1510 /* Major is lower than required one */ 1511 return false; 1512 } 1513 } 1514 1515 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion> 1516 * 1517 * @param token Token string 1518 * @param search_position Position at which find will start, it is updated to position at which replaced text ends 1519 * @param text String that will be used as replacement for <token> 1520 * @param string String to work on 1521 **/ 1522 void replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string) 1523 { 1524 const size_t text_length = strlen(text); 1525 const size_t token_length = strlen(token); 1526 const size_t token_position = string.find(token, search_position); 1527 1528 #if DEBUG_REPLACE_TOKEN 1529 if (std::string::npos == token_position) 1530 { 1531 string.append("\n\nInvalid token: "); 1532 string.append(token); 1533 1534 TCU_FAIL(string.c_str()); 1535 } 1536 #endif /* DEBUG_REPLACE_TOKEN */ 1537 1538 string.replace(token_position, token_length, text, text_length); 1539 1540 search_position = token_position + text_length; 1541 } 1542 1543 /** Replace all occurances of <token> with <text> in <string> 1544 * 1545 * @param token Token string 1546 * @param text String that will be used as replacement for <token> 1547 * @param string String to work on 1548 **/ 1549 void replaceAllTokens(const GLchar* token, const GLchar* text, std::string& string) 1550 { 1551 const size_t text_length = strlen(text); 1552 const size_t token_length = strlen(token); 1553 1554 size_t search_position = 0; 1555 1556 while (1) 1557 { 1558 const size_t token_position = string.find(token, search_position); 1559 1560 if (std::string::npos == token_position) 1561 { 1562 break; 1563 } 1564 1565 search_position = token_position + text_length; 1566 1567 string.replace(token_position, token_length, text, text_length); 1568 } 1569 } 1570 1571 /** Rounds up the value to the next power of 2. 1572 * This routine does not work for 0, see the url for explanations. 1573 * 1574 * @param value Starting point 1575 * 1576 * @return Calculated value 1577 **/ 1578 glw::GLuint roundUpToPowerOf2(glw::GLuint value) 1579 { 1580 /* Taken from: graphics.stanford.edu/~seander/bithacks.html */ 1581 --value; 1582 1583 value |= value >> 1; 1584 value |= value >> 2; 1585 value |= value >> 4; 1586 value |= value >> 8; 1587 value |= value >> 16; 1588 1589 ++value; 1590 1591 return value; 1592 } 1593 1594 /** Insert elements of list into string. 1595 * List in string is represented either by token "LIST" or "SEPARATORLIST". 1596 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>. 1597 * LIST is replaced with <element>SEPARATORLIST 1598 * 1599 * @param element Element to be inserted 1600 * @param separator Separator inserted between elements 1601 * @param search_position Position in string, where search for list should start 1602 * @param string String 1603 **/ 1604 void insertElementOfList(const GLchar* element, const GLchar* separator, size_t& search_position, std::string& string) 1605 { 1606 static const char* list = g_list; 1607 static const char* sep_list = "SEPARATORLIST"; 1608 1609 /* Try to get "list" positions */ 1610 const size_t list_position = string.find(list, search_position); 1611 const size_t sep_list_position = string.find(sep_list, search_position); 1612 1613 /* There is no list in string */ 1614 if (std::string::npos == list_position) 1615 { 1616 return; 1617 } 1618 1619 if (9 /* strlen(SEPARATOR) */ == list_position - sep_list_position) 1620 { 1621 replaceToken("SEPARATOR", search_position, separator, string); 1622 } 1623 1624 /* Save search_position */ 1625 const size_t start_position = search_position; 1626 1627 /* Prepare new element */ 1628 replaceToken("LIST", search_position, "ELEMENTSEPARATORLIST", string); 1629 1630 /* Restore search_position */ 1631 search_position = start_position; 1632 1633 /* Replace element and separator */ 1634 replaceToken("ELEMENT", search_position, element, string); 1635 } 1636 1637 /** Close list in string. 1638 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator> 1639 * LIST is replaced with "" 1640 * 1641 * @param separator Separator inserted between elements 1642 * @param search_position Position in string, where search for list should start 1643 * @param string String 1644 **/ 1645 void endList(const glw::GLchar* separator, size_t& search_position, std::string& string) 1646 { 1647 const size_t sep_position = string.find("SEPARATOR", search_position); 1648 if (std::string::npos != sep_position) 1649 { 1650 replaceToken("SEPARATOR", search_position, separator, string); 1651 } 1652 1653 replaceToken("LIST", search_position, "", string); 1654 } 1655 1656 /* Buffer constants */ 1657 const GLuint Buffer::m_invalid_id = -1; 1658 1659 /** Constructor. 1660 * 1661 * @param context CTS context. 1662 **/ 1663 Buffer::Buffer(deqp::Context& context) : m_id(m_invalid_id), m_buffer(Array), m_context(context) 1664 { 1665 } 1666 1667 /** Destructor 1668 * 1669 **/ 1670 Buffer::~Buffer() 1671 { 1672 Release(); 1673 } 1674 1675 /** Initialize buffer instance 1676 * 1677 * @param buffer Buffer type 1678 * @param usage Buffer usage enum 1679 * @param size <size> parameter 1680 * @param data <data> parameter 1681 **/ 1682 void Buffer::Init(BUFFERS buffer, USAGE usage, GLsizeiptr size, GLvoid* data) 1683 { 1684 /* Delete previous buffer instance */ 1685 Release(); 1686 1687 m_buffer = buffer; 1688 1689 const Functions& gl = m_context.getRenderContext().getFunctions(); 1690 1691 Generate(gl, m_id); 1692 Bind(gl, m_id, m_buffer); 1693 Data(gl, m_buffer, usage, size, data); 1694 } 1695 1696 /** Release buffer instance 1697 * 1698 **/ 1699 void Buffer::Release() 1700 { 1701 if (m_invalid_id != m_id) 1702 { 1703 const Functions& gl = m_context.getRenderContext().getFunctions(); 1704 1705 gl.deleteBuffers(1, &m_id); 1706 m_id = m_invalid_id; 1707 } 1708 } 1709 1710 /** Binds buffer to its target 1711 * 1712 **/ 1713 void Buffer::Bind() const 1714 { 1715 const Functions& gl = m_context.getRenderContext().getFunctions(); 1716 1717 Bind(gl, m_id, m_buffer); 1718 } 1719 1720 /** Binds indexed buffer 1721 * 1722 * @param index <index> parameter 1723 **/ 1724 void Buffer::BindBase(GLuint index) const 1725 { 1726 const Functions& gl = m_context.getRenderContext().getFunctions(); 1727 1728 BindBase(gl, m_id, m_buffer, index); 1729 } 1730 1731 /** Binds range of buffer 1732 * 1733 * @param index <index> parameter 1734 * @param offset <offset> parameter 1735 * @param size <size> parameter 1736 **/ 1737 void Buffer::BindRange(GLuint index, GLintptr offset, GLsizeiptr size) const 1738 { 1739 const Functions& gl = m_context.getRenderContext().getFunctions(); 1740 1741 BindRange(gl, m_id, m_buffer, index, offset, size); 1742 } 1743 1744 /** Allocate memory for buffer and sends initial content 1745 * 1746 * @param usage Buffer usage enum 1747 * @param size <size> parameter 1748 * @param data <data> parameter 1749 **/ 1750 void Buffer::Data(USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data) 1751 { 1752 const Functions& gl = m_context.getRenderContext().getFunctions(); 1753 1754 Data(gl, m_buffer, usage, size, data); 1755 } 1756 1757 /** Maps contents of buffer into CPU space 1758 * 1759 * @param access Requested access 1760 * 1761 * @return Pointer to memory region available for CPU 1762 **/ 1763 GLvoid* Buffer::Map(ACCESS access) 1764 { 1765 const Functions& gl = m_context.getRenderContext().getFunctions(); 1766 1767 return Map(gl, m_buffer, access); 1768 } 1769 1770 /** Allocate memory for buffer and sends initial content 1771 * 1772 * @param offset Offset in buffer 1773 * @param size <size> parameter 1774 * @param data <data> parameter 1775 **/ 1776 void Buffer::SubData(glw::GLintptr offset, glw::GLsizeiptr size, glw::GLvoid* data) 1777 { 1778 const Functions& gl = m_context.getRenderContext().getFunctions(); 1779 1780 SubData(gl, m_buffer, offset, size, data); 1781 } 1782 1783 /** Maps contents of buffer into CPU space 1784 **/ 1785 void Buffer::UnMap() 1786 { 1787 const Functions& gl = m_context.getRenderContext().getFunctions(); 1788 1789 return UnMap(gl, m_buffer); 1790 } 1791 1792 /** Bind buffer to given target 1793 * 1794 * @param gl GL functions 1795 * @param id Id of buffer 1796 * @param buffer Buffer enum 1797 **/ 1798 void Buffer::Bind(const Functions& gl, GLuint id, BUFFERS buffer) 1799 { 1800 GLenum target = GetBufferGLenum(buffer); 1801 1802 gl.bindBuffer(target, id); 1803 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer"); 1804 } 1805 1806 /** Binds indexed buffer 1807 * 1808 * @param gl GL functions 1809 * @param id Id of buffer 1810 * @param buffer Buffer enum 1811 * @param index <index> parameter 1812 **/ 1813 void Buffer::BindBase(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index) 1814 { 1815 GLenum target = GetBufferGLenum(buffer); 1816 1817 gl.bindBufferBase(target, index, id); 1818 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase"); 1819 } 1820 1821 /** Binds buffer range 1822 * 1823 * @param gl GL functions 1824 * @param id Id of buffer 1825 * @param buffer Buffer enum 1826 * @param index <index> parameter 1827 * @param offset <offset> parameter 1828 * @param size <size> parameter 1829 **/ 1830 void Buffer::BindRange(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index, GLintptr offset, GLsizeiptr size) 1831 { 1832 GLenum target = GetBufferGLenum(buffer); 1833 1834 gl.bindBufferRange(target, index, id, offset, size); 1835 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange"); 1836 } 1837 1838 /** Allocate memory for buffer and sends initial content 1839 * 1840 * @param gl GL functions 1841 * @param buffer Buffer enum 1842 * @param usage Buffer usage enum 1843 * @param size <size> parameter 1844 * @param data <data> parameter 1845 **/ 1846 void Buffer::Data(const glw::Functions& gl, BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data) 1847 { 1848 GLenum target = GetBufferGLenum(buffer); 1849 GLenum gl_usage = GetUsageGLenum(usage); 1850 1851 gl.bufferData(target, size, data, gl_usage); 1852 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData"); 1853 } 1854 1855 /** Allocate memory for buffer and sends initial content 1856 * 1857 * @param gl GL functions 1858 * @param buffer Buffer enum 1859 * @param offset Offset in buffer 1860 * @param size <size> parameter 1861 * @param data <data> parameter 1862 **/ 1863 void Buffer::SubData(const glw::Functions& gl, BUFFERS buffer, glw::GLintptr offset, glw::GLsizeiptr size, 1864 glw::GLvoid* data) 1865 { 1866 GLenum target = GetBufferGLenum(buffer); 1867 1868 gl.bufferSubData(target, offset, size, data); 1869 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData"); 1870 } 1871 1872 /** Generate buffer 1873 * 1874 * @param gl GL functions 1875 * @param out_id Id of buffer 1876 **/ 1877 void Buffer::Generate(const Functions& gl, GLuint& out_id) 1878 { 1879 GLuint id = m_invalid_id; 1880 1881 gl.genBuffers(1, &id); 1882 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers"); 1883 1884 if (m_invalid_id == id) 1885 { 1886 TCU_FAIL("Got invalid id"); 1887 } 1888 1889 out_id = id; 1890 } 1891 1892 /** Maps buffer content 1893 * 1894 * @param gl GL functions 1895 * @param buffer Buffer enum 1896 * @param access Access rights for mapped region 1897 * 1898 * @return Mapped memory 1899 **/ 1900 void* Buffer::Map(const Functions& gl, BUFFERS buffer, ACCESS access) 1901 { 1902 GLenum target = GetBufferGLenum(buffer); 1903 GLenum gl_access = GetAccessGLenum(access); 1904 1905 void* result = gl.mapBuffer(target, gl_access); 1906 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 1907 1908 return result; 1909 } 1910 1911 /** Unmaps buffer 1912 * 1913 **/ 1914 void Buffer::UnMap(const Functions& gl, BUFFERS buffer) 1915 { 1916 GLenum target = GetBufferGLenum(buffer); 1917 1918 gl.unmapBuffer(target); 1919 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 1920 } 1921 1922 /** Return GLenum representation of requested access 1923 * 1924 * @param access Requested access 1925 * 1926 * @return GLenum value 1927 **/ 1928 GLenum Buffer::GetAccessGLenum(ACCESS access) 1929 { 1930 GLenum result = 0; 1931 1932 switch (access) 1933 { 1934 case ReadOnly: 1935 result = GL_READ_ONLY; 1936 break; 1937 case WriteOnly: 1938 result = GL_WRITE_ONLY; 1939 break; 1940 case ReadWrite: 1941 result = GL_READ_WRITE; 1942 break; 1943 default: 1944 TCU_FAIL("Invalid enum"); 1945 } 1946 1947 return result; 1948 } 1949 1950 /** Return GLenum representation of requested buffer type 1951 * 1952 * @param buffer Requested buffer type 1953 * 1954 * @return GLenum value 1955 **/ 1956 GLenum Buffer::GetBufferGLenum(BUFFERS buffer) 1957 { 1958 GLenum result = 0; 1959 1960 switch (buffer) 1961 { 1962 case Array: 1963 result = GL_ARRAY_BUFFER; 1964 break; 1965 case Element: 1966 result = GL_ELEMENT_ARRAY_BUFFER; 1967 break; 1968 case Shader_Storage: 1969 result = GL_SHADER_STORAGE_BUFFER; 1970 break; 1971 case Texture: 1972 result = GL_TEXTURE_BUFFER; 1973 break; 1974 case Transform_feedback: 1975 result = GL_TRANSFORM_FEEDBACK_BUFFER; 1976 break; 1977 case Uniform: 1978 result = GL_UNIFORM_BUFFER; 1979 break; 1980 default: 1981 TCU_FAIL("Invalid enum"); 1982 } 1983 1984 return result; 1985 } 1986 1987 /** Return GLenum representation of requested usage 1988 * 1989 * @param usage Requested usage 1990 * 1991 * @return GLenum value 1992 **/ 1993 GLenum Buffer::GetUsageGLenum(USAGE usage) 1994 { 1995 GLenum result = 0; 1996 1997 switch (usage) 1998 { 1999 case DynamicCopy: 2000 result = GL_DYNAMIC_COPY; 2001 break; 2002 case DynamicDraw: 2003 result = GL_DYNAMIC_DRAW; 2004 break; 2005 case DynamicRead: 2006 result = GL_DYNAMIC_READ; 2007 break; 2008 case StaticCopy: 2009 result = GL_STATIC_COPY; 2010 break; 2011 case StaticDraw: 2012 result = GL_STATIC_DRAW; 2013 break; 2014 case StaticRead: 2015 result = GL_STATIC_READ; 2016 break; 2017 case StreamCopy: 2018 result = GL_STREAM_COPY; 2019 break; 2020 case StreamDraw: 2021 result = GL_STREAM_DRAW; 2022 break; 2023 case StreamRead: 2024 result = GL_STREAM_READ; 2025 break; 2026 default: 2027 TCU_FAIL("Invalid enum"); 2028 } 2029 2030 return result; 2031 } 2032 2033 /** Returns name of buffer target 2034 * 2035 * @param buffer Target enum 2036 * 2037 * @return Name of target 2038 **/ 2039 const GLchar* Buffer::GetBufferName(BUFFERS buffer) 2040 { 2041 const GLchar* name = 0; 2042 2043 switch (buffer) 2044 { 2045 case Array: 2046 name = "Array"; 2047 break; 2048 case Element: 2049 name = "Element"; 2050 break; 2051 case Shader_Storage: 2052 name = "Shader_Storage"; 2053 break; 2054 case Texture: 2055 name = "Texture"; 2056 break; 2057 case Transform_feedback: 2058 name = "Transform_feedback"; 2059 break; 2060 case Uniform: 2061 name = "Uniform"; 2062 break; 2063 default: 2064 TCU_FAIL("Invalid enum"); 2065 } 2066 2067 return name; 2068 } 2069 2070 /* Framebuffer constants */ 2071 const GLuint Framebuffer::m_invalid_id = -1; 2072 2073 /** Constructor 2074 * 2075 * @param context CTS context 2076 **/ 2077 Framebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 2078 { 2079 /* Nothing to be done here */ 2080 } 2081 2082 /** Destructor 2083 * 2084 **/ 2085 Framebuffer::~Framebuffer() 2086 { 2087 Release(); 2088 } 2089 2090 /** Initialize framebuffer instance 2091 * 2092 **/ 2093 void Framebuffer::Init() 2094 { 2095 /* Delete previous instance */ 2096 Release(); 2097 2098 const Functions& gl = m_context.getRenderContext().getFunctions(); 2099 2100 Generate(gl, m_id); 2101 } 2102 2103 /** Release framebuffer instance 2104 * 2105 **/ 2106 void Framebuffer::Release() 2107 { 2108 if (m_invalid_id != m_id) 2109 { 2110 const Functions& gl = m_context.getRenderContext().getFunctions(); 2111 2112 gl.deleteFramebuffers(1, &m_id); 2113 m_id = m_invalid_id; 2114 } 2115 } 2116 2117 /** Attach texture to specified attachment 2118 * 2119 * @param attachment Attachment 2120 * @param texture_id Texture id 2121 * @param width Texture width 2122 * @param height Texture height 2123 **/ 2124 void Framebuffer::AttachTexture(GLenum attachment, GLuint texture_id, GLuint width, GLuint height) 2125 { 2126 const Functions& gl = m_context.getRenderContext().getFunctions(); 2127 2128 AttachTexture(gl, attachment, texture_id, width, height); 2129 } 2130 2131 /** Binds framebuffer to DRAW_FRAMEBUFFER 2132 * 2133 **/ 2134 void Framebuffer::Bind() 2135 { 2136 const Functions& gl = m_context.getRenderContext().getFunctions(); 2137 2138 Bind(gl, m_id); 2139 } 2140 2141 /** Clear framebuffer 2142 * 2143 * @param mask <mask> parameter of glClear. Decides which shall be cleared 2144 **/ 2145 void Framebuffer::Clear(GLenum mask) 2146 { 2147 const Functions& gl = m_context.getRenderContext().getFunctions(); 2148 2149 Clear(gl, mask); 2150 } 2151 2152 /** Specifies clear color 2153 * 2154 * @param red Red channel 2155 * @param green Green channel 2156 * @param blue Blue channel 2157 * @param alpha Alpha channel 2158 **/ 2159 void Framebuffer::ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) 2160 { 2161 const Functions& gl = m_context.getRenderContext().getFunctions(); 2162 2163 ClearColor(gl, red, green, blue, alpha); 2164 } 2165 2166 /** Attach texture to specified attachment 2167 * 2168 * @param gl GL functions 2169 * @param attachment Attachment 2170 * @param texture_id Texture id 2171 * @param width Texture width 2172 * @param height Texture height 2173 **/ 2174 void Framebuffer::AttachTexture(const Functions& gl, GLenum attachment, GLuint texture_id, GLuint width, GLuint height) 2175 { 2176 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */); 2177 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture"); 2178 2179 gl.viewport(0 /* x */, 0 /* y */, width, height); 2180 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport"); 2181 } 2182 2183 /** Binds framebuffer to DRAW_FRAMEBUFFER 2184 * 2185 * @param gl GL functions 2186 * @param id ID of framebuffer 2187 **/ 2188 void Framebuffer::Bind(const Functions& gl, GLuint id) 2189 { 2190 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, id); 2191 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer"); 2192 } 2193 2194 /** Clear framebuffer 2195 * 2196 * @param gl GL functions 2197 * @param mask <mask> parameter of glClear. Decides which shall be cleared 2198 **/ 2199 void Framebuffer::Clear(const Functions& gl, GLenum mask) 2200 { 2201 gl.clear(mask); 2202 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear"); 2203 } 2204 2205 /** Specifies clear color 2206 * 2207 * @param gl GL functions 2208 * @param red Red channel 2209 * @param green Green channel 2210 * @param blue Blue channel 2211 * @param alpha Alpha channel 2212 **/ 2213 void Framebuffer::ClearColor(const Functions& gl, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) 2214 { 2215 gl.clearColor(red, green, blue, alpha); 2216 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor"); 2217 } 2218 2219 /** Generate framebuffer 2220 * 2221 **/ 2222 void Framebuffer::Generate(const Functions& gl, GLuint& out_id) 2223 { 2224 GLuint id = m_invalid_id; 2225 2226 gl.genFramebuffers(1, &id); 2227 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers"); 2228 2229 if (m_invalid_id == id) 2230 { 2231 TCU_FAIL("Invalid id"); 2232 } 2233 2234 out_id = id; 2235 } 2236 2237 /* Shader's constants */ 2238 const GLuint Shader::m_invalid_id = 0; 2239 2240 /** Constructor. 2241 * 2242 * @param context CTS context. 2243 **/ 2244 Shader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 2245 { 2246 /* Nothing to be done here */ 2247 } 2248 2249 /** Destructor 2250 * 2251 **/ 2252 Shader::~Shader() 2253 { 2254 Release(); 2255 } 2256 2257 /** Initialize shader instance 2258 * 2259 * @param stage Shader stage 2260 * @param source Source code 2261 **/ 2262 void Shader::Init(STAGES stage, const std::string& source) 2263 { 2264 if (true == source.empty()) 2265 { 2266 /* No source == no shader */ 2267 return; 2268 } 2269 2270 /* Delete any previous shader */ 2271 Release(); 2272 2273 /* Create, set source and compile */ 2274 const Functions& gl = m_context.getRenderContext().getFunctions(); 2275 2276 Create(gl, stage, m_id); 2277 Source(gl, m_id, source); 2278 2279 try 2280 { 2281 Compile(gl, m_id); 2282 } 2283 catch (const CompilationException& exc) 2284 { 2285 throw InvalidSourceException(exc.what(), source, stage); 2286 } 2287 } 2288 2289 /** Release shader instance 2290 * 2291 **/ 2292 void Shader::Release() 2293 { 2294 if (m_invalid_id != m_id) 2295 { 2296 const Functions& gl = m_context.getRenderContext().getFunctions(); 2297 2298 gl.deleteShader(m_id); 2299 m_id = m_invalid_id; 2300 } 2301 } 2302 2303 /** Compile shader 2304 * 2305 * @param gl GL functions 2306 * @param id Shader id 2307 **/ 2308 void Shader::Compile(const Functions& gl, GLuint id) 2309 { 2310 GLint status = GL_FALSE; 2311 2312 /* Compile */ 2313 gl.compileShader(id); 2314 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader"); 2315 2316 /* Get compilation status */ 2317 gl.getShaderiv(id, GL_COMPILE_STATUS, &status); 2318 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 2319 2320 /* Log compilation error */ 2321 if (GL_TRUE != status) 2322 { 2323 glw::GLint length = 0; 2324 std::string message; 2325 2326 /* Error log length */ 2327 gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length); 2328 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 2329 2330 /* Prepare storage */ 2331 message.resize(length, 0); 2332 2333 /* Get error log */ 2334 gl.getShaderInfoLog(id, length, 0, &message[0]); 2335 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog"); 2336 2337 throw CompilationException(message.c_str()); 2338 } 2339 } 2340 2341 /** Create shader 2342 * 2343 * @param gl GL functions 2344 * @param stage Shader stage 2345 * @param out_id Shader id 2346 **/ 2347 void Shader::Create(const Functions& gl, STAGES stage, GLuint& out_id) 2348 { 2349 const GLenum shaderType = GetShaderStageGLenum(stage); 2350 const GLuint id = gl.createShader(shaderType); 2351 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 2352 2353 if (m_invalid_id == id) 2354 { 2355 TCU_FAIL("Failed to create shader"); 2356 } 2357 2358 out_id = id; 2359 } 2360 2361 /** Set shader's source code 2362 * 2363 * @param gl GL functions 2364 * @param id Shader id 2365 * @param source Shader source code 2366 **/ 2367 void Shader::Source(const Functions& gl, GLuint id, const std::string& source) 2368 { 2369 const GLchar* code = source.c_str(); 2370 2371 gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */); 2372 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource"); 2373 } 2374 2375 /** Get GLenum repesenting shader stage 2376 * 2377 * @param stage Shader stage 2378 * 2379 * @return GLenum 2380 **/ 2381 GLenum Shader::GetShaderStageGLenum(STAGES stage) 2382 { 2383 GLenum result = 0; 2384 2385 switch (stage) 2386 { 2387 case COMPUTE: 2388 result = GL_COMPUTE_SHADER; 2389 break; 2390 case FRAGMENT: 2391 result = GL_FRAGMENT_SHADER; 2392 break; 2393 case GEOMETRY: 2394 result = GL_GEOMETRY_SHADER; 2395 break; 2396 case TESS_CTRL: 2397 result = GL_TESS_CONTROL_SHADER; 2398 break; 2399 case TESS_EVAL: 2400 result = GL_TESS_EVALUATION_SHADER; 2401 break; 2402 case VERTEX: 2403 result = GL_VERTEX_SHADER; 2404 break; 2405 default: 2406 TCU_FAIL("Invalid enum"); 2407 } 2408 2409 return result; 2410 } 2411 2412 /** Get string representing name of shader stage 2413 * 2414 * @param stage Shader stage 2415 * 2416 * @return String with name of shader stage 2417 **/ 2418 const glw::GLchar* Shader::GetStageName(STAGES stage) 2419 { 2420 const GLchar* result = 0; 2421 2422 switch (stage) 2423 { 2424 case COMPUTE: 2425 result = "compute"; 2426 break; 2427 case VERTEX: 2428 result = "vertex"; 2429 break; 2430 case TESS_CTRL: 2431 result = "tessellation control"; 2432 break; 2433 case TESS_EVAL: 2434 result = "tessellation evaluation"; 2435 break; 2436 case GEOMETRY: 2437 result = "geometry"; 2438 break; 2439 case FRAGMENT: 2440 result = "fragment"; 2441 break; 2442 default: 2443 TCU_FAIL("Invalid enum"); 2444 } 2445 2446 return result; 2447 } 2448 2449 /** Logs shader source 2450 * 2451 * @param context CTS context 2452 * @param source Source of shader 2453 * @param stage Shader stage 2454 **/ 2455 void Shader::LogSource(deqp::Context& context, const std::string& source, STAGES stage) 2456 { 2457 /* Skip empty shaders */ 2458 if (true == source.empty()) 2459 { 2460 return; 2461 } 2462 2463 context.getTestContext().getLog() << tcu::TestLog::Message 2464 << "Shader source. Stage: " << Shader::GetStageName(stage) 2465 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(source); 2466 } 2467 2468 /** Constructor 2469 * 2470 * @param message Compilation error message 2471 **/ 2472 Shader::CompilationException::CompilationException(const GLchar* message) 2473 { 2474 m_message = message; 2475 } 2476 2477 /** Returns error messages 2478 * 2479 * @return Compilation error message 2480 **/ 2481 const char* Shader::CompilationException::what() const throw() 2482 { 2483 return m_message.c_str(); 2484 } 2485 2486 /** Constructor 2487 * 2488 * @param message Compilation error message 2489 **/ 2490 Shader::InvalidSourceException::InvalidSourceException(const GLchar* error_message, const std::string& source, 2491 STAGES stage) 2492 : m_message(error_message), m_source(source), m_stage(stage) 2493 { 2494 } 2495 2496 /** Returns error messages 2497 * 2498 * @return Compilation error message 2499 **/ 2500 const char* Shader::InvalidSourceException::what() const throw() 2501 { 2502 return "Compilation error"; 2503 } 2504 2505 /** Logs error message and shader sources **/ 2506 void Shader::InvalidSourceException::log(deqp::Context& context) const 2507 { 2508 context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader: " << m_message.c_str() 2509 << tcu::TestLog::EndMessage; 2510 2511 LogSource(context, m_source, m_stage); 2512 } 2513 2514 /* Program constants */ 2515 const GLuint Pipeline::m_invalid_id = 0; 2516 2517 /** Constructor. 2518 * 2519 * @param context CTS context. 2520 **/ 2521 Pipeline::Pipeline(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 2522 { 2523 /* Nothing to be done here */ 2524 } 2525 2526 /** Destructor 2527 * 2528 **/ 2529 Pipeline::~Pipeline() 2530 { 2531 Release(); 2532 } 2533 2534 /** Initialize pipline object 2535 * 2536 **/ 2537 void Pipeline::Init() 2538 { 2539 Release(); 2540 2541 const Functions& gl = m_context.getRenderContext().getFunctions(); 2542 2543 /* Generate */ 2544 gl.genProgramPipelines(1, &m_id); 2545 GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines"); 2546 } 2547 2548 /** Release pipeline object 2549 * 2550 **/ 2551 void Pipeline::Release() 2552 { 2553 if (m_invalid_id != m_id) 2554 { 2555 const Functions& gl = m_context.getRenderContext().getFunctions(); 2556 2557 /* Generate */ 2558 gl.deleteProgramPipelines(1, &m_id); 2559 GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteProgramPipelines"); 2560 2561 m_id = m_invalid_id; 2562 } 2563 } 2564 2565 /** Bind pipeline 2566 * 2567 **/ 2568 void Pipeline::Bind() 2569 { 2570 const Functions& gl = m_context.getRenderContext().getFunctions(); 2571 2572 Bind(gl, m_id); 2573 } 2574 2575 /** Set which stages should be active 2576 * 2577 * @param program_id Id of program 2578 * @param stages Logical combination of enums representing stages 2579 **/ 2580 void Pipeline::UseProgramStages(GLuint program_id, GLenum stages) 2581 { 2582 const Functions& gl = m_context.getRenderContext().getFunctions(); 2583 2584 UseProgramStages(gl, m_id, program_id, stages); 2585 } 2586 2587 /** Bind pipeline 2588 * 2589 * @param gl Functiions 2590 * @param id Pipeline id 2591 **/ 2592 void Pipeline::Bind(const Functions& gl, GLuint id) 2593 { 2594 gl.bindProgramPipeline(id); 2595 GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline"); 2596 } 2597 2598 /** Set which stages should be active 2599 * 2600 * @param gl Functiions 2601 * @param id Pipeline id 2602 * @param program_id Id of program 2603 * @param stages Logical combination of enums representing stages 2604 **/ 2605 void Pipeline::UseProgramStages(const Functions& gl, GLuint id, GLuint program_id, GLenum stages) 2606 { 2607 gl.useProgramStages(id, stages, program_id); 2608 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages"); 2609 } 2610 2611 /* Program constants */ 2612 const GLuint Program::m_invalid_id = 0; 2613 2614 /** Constructor. 2615 * 2616 * @param context CTS context. 2617 **/ 2618 Program::Program(deqp::Context& context) 2619 : m_id(m_invalid_id) 2620 , m_compute(context) 2621 , m_fragment(context) 2622 , m_geometry(context) 2623 , m_tess_ctrl(context) 2624 , m_tess_eval(context) 2625 , m_vertex(context) 2626 , m_context(context) 2627 { 2628 /* Nothing to be done here */ 2629 } 2630 2631 /** Destructor 2632 * 2633 **/ 2634 Program::~Program() 2635 { 2636 Release(); 2637 } 2638 2639 /** Initialize program instance 2640 * 2641 * @param compute_shader Compute shader source code 2642 * @param fragment_shader Fragment shader source code 2643 * @param geometry_shader Geometry shader source code 2644 * @param tessellation_control_shader Tessellation control shader source code 2645 * @param tessellation_evaluation_shader Tessellation evaluation shader source code 2646 * @param vertex_shader Vertex shader source code 2647 * @param captured_varyings Vector of variables to be captured with transfrom feedback 2648 * @param capture_interleaved Select mode of transform feedback (separate or interleaved) 2649 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false 2650 **/ 2651 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader, 2652 const std::string& geometry_shader, const std::string& tessellation_control_shader, 2653 const std::string& tessellation_evaluation_shader, const std::string& vertex_shader, 2654 const NameVector& captured_varyings, bool capture_interleaved, bool is_separable) 2655 { 2656 /* Delete previous program */ 2657 Release(); 2658 2659 /* GL entry points */ 2660 const Functions& gl = m_context.getRenderContext().getFunctions(); 2661 2662 /* Initialize shaders */ 2663 m_compute.Init(Shader::COMPUTE, compute_shader); 2664 m_fragment.Init(Shader::FRAGMENT, fragment_shader); 2665 m_geometry.Init(Shader::GEOMETRY, geometry_shader); 2666 m_tess_ctrl.Init(Shader::TESS_CTRL, tessellation_control_shader); 2667 m_tess_eval.Init(Shader::TESS_EVAL, tessellation_evaluation_shader); 2668 m_vertex.Init(Shader::VERTEX, vertex_shader); 2669 2670 /* Create program, set up transform feedback and attach shaders */ 2671 Create(gl, m_id); 2672 Capture(gl, m_id, captured_varyings, capture_interleaved); 2673 Attach(gl, m_id, m_compute.m_id); 2674 Attach(gl, m_id, m_fragment.m_id); 2675 Attach(gl, m_id, m_geometry.m_id); 2676 Attach(gl, m_id, m_tess_ctrl.m_id); 2677 Attach(gl, m_id, m_tess_eval.m_id); 2678 Attach(gl, m_id, m_vertex.m_id); 2679 2680 /* Set separable parameter */ 2681 if (true == is_separable) 2682 { 2683 gl.programParameteri(m_id, GL_PROGRAM_SEPARABLE, GL_TRUE); 2684 GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri"); 2685 } 2686 2687 try 2688 { 2689 /* Link program */ 2690 Link(gl, m_id); 2691 } 2692 catch (const LinkageException& exc) 2693 { 2694 throw BuildException(exc.what(), compute_shader, fragment_shader, geometry_shader, tessellation_control_shader, 2695 tessellation_evaluation_shader, vertex_shader); 2696 } 2697 } 2698 2699 /** Initialize program instance 2700 * 2701 * @param compute_shader Compute shader source code 2702 * @param fragment_shader Fragment shader source code 2703 * @param geometry_shader Geometry shader source code 2704 * @param tessellation_control_shader Tessellation control shader source code 2705 * @param tessellation_evaluation_shader Tessellation evaluation shader source code 2706 * @param vertex_shader Vertex shader source code 2707 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false 2708 **/ 2709 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader, 2710 const std::string& geometry_shader, const std::string& tessellation_control_shader, 2711 const std::string& tessellation_evaluation_shader, const std::string& vertex_shader, 2712 bool is_separable) 2713 { 2714 NameVector captured_varying; 2715 2716 Init(compute_shader, fragment_shader, geometry_shader, tessellation_control_shader, tessellation_evaluation_shader, 2717 vertex_shader, captured_varying, true, is_separable); 2718 } 2719 2720 /** Release program instance 2721 * 2722 **/ 2723 void Program::Release() 2724 { 2725 const Functions& gl = m_context.getRenderContext().getFunctions(); 2726 2727 if (m_invalid_id != m_id) 2728 { 2729 Use(gl, m_invalid_id); 2730 2731 gl.deleteProgram(m_id); 2732 m_id = m_invalid_id; 2733 } 2734 2735 m_compute.Release(); 2736 m_fragment.Release(); 2737 m_geometry.Release(); 2738 m_tess_ctrl.Release(); 2739 m_tess_eval.Release(); 2740 m_vertex.Release(); 2741 } 2742 2743 /** Get <pname> for a set of active uniforms 2744 * 2745 * @param count Number of indices 2746 * @param indices Indices of uniforms 2747 * @param pname Queired pname 2748 * @param params Array that will be filled with values of parameters 2749 **/ 2750 void Program::GetActiveUniformsiv(GLsizei count, const GLuint* indices, GLenum pname, GLint* params) const 2751 { 2752 const Functions& gl = m_context.getRenderContext().getFunctions(); 2753 2754 GetActiveUniformsiv(gl, m_id, count, indices, pname, params); 2755 } 2756 2757 /** Get location of attribute 2758 * 2759 * @param name Name of attribute 2760 * 2761 * @return Result of query 2762 **/ 2763 glw::GLint Program::GetAttribLocation(const std::string& name) const 2764 { 2765 const Functions& gl = m_context.getRenderContext().getFunctions(); 2766 2767 return GetAttribLocation(gl, m_id, name); 2768 } 2769 2770 /** Query resource 2771 * 2772 * @param interface Interface to be queried 2773 * @param index Index of resource 2774 * @param property Property to be queried 2775 * @param buf_size Size of <params> buffer 2776 * @param params Results of query 2777 **/ 2778 void Program::GetResource(GLenum interface, GLuint index, GLenum property, GLsizei buf_size, GLint* params) const 2779 { 2780 const Functions& gl = m_context.getRenderContext().getFunctions(); 2781 2782 GetResource(gl, m_id, interface, index, property, buf_size, params); 2783 } 2784 2785 /** Query for index of resource 2786 * 2787 * @param name Name of resource 2788 * @param interface Interface to be queried 2789 * 2790 * @return Result of query 2791 **/ 2792 glw::GLuint Program::GetResourceIndex(const std::string& name, GLenum interface) const 2793 { 2794 const Functions& gl = m_context.getRenderContext().getFunctions(); 2795 2796 return GetResourceIndex(gl, m_id, name, interface); 2797 } 2798 2799 /** Get indices for a set of uniforms 2800 * 2801 * @param count Count number of uniforms 2802 * @param names Names of uniforms 2803 * @param indices Buffer that will be filled with indices 2804 **/ 2805 void Program::GetUniformIndices(GLsizei count, const GLchar** names, GLuint* indices) const 2806 { 2807 const Functions& gl = m_context.getRenderContext().getFunctions(); 2808 2809 GetUniformIndices(gl, m_id, count, names, indices); 2810 } 2811 2812 /** Get uniform location 2813 * 2814 * @param name Name of uniform 2815 * 2816 * @return Results of query 2817 **/ 2818 glw::GLint Program::GetUniformLocation(const std::string& name) const 2819 { 2820 const Functions& gl = m_context.getRenderContext().getFunctions(); 2821 2822 return GetUniformLocation(gl, m_id, name); 2823 } 2824 2825 /** Set program as active 2826 * 2827 **/ 2828 void Program::Use() const 2829 { 2830 const Functions& gl = m_context.getRenderContext().getFunctions(); 2831 2832 Use(gl, m_id); 2833 } 2834 2835 /** Attach shader to program 2836 * 2837 * @param gl GL functions 2838 * @param program_id Id of program 2839 * @param shader_id Id of shader 2840 **/ 2841 void Program::Attach(const Functions& gl, GLuint program_id, GLuint shader_id) 2842 { 2843 /* Sanity checks */ 2844 if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id)) 2845 { 2846 return; 2847 } 2848 2849 gl.attachShader(program_id, shader_id); 2850 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 2851 } 2852 2853 /** Set up captured varyings 2854 * 2855 * @param gl GL functions 2856 * @param id Id of program 2857 * @param captured_varyings Vector of varyings 2858 * @param capture_interleaved Selects if interleaved or separate mode should be used 2859 **/ 2860 void Program::Capture(const Functions& gl, GLuint id, const NameVector& captured_varyings, bool capture_interleaved) 2861 { 2862 const size_t n_varyings = captured_varyings.size(); 2863 2864 if (0 == n_varyings) 2865 { 2866 /* empty list, skip */ 2867 return; 2868 } 2869 2870 std::vector<const GLchar*> varying_names; 2871 varying_names.resize(n_varyings); 2872 2873 for (size_t i = 0; i < n_varyings; ++i) 2874 { 2875 varying_names[i] = captured_varyings[i].c_str(); 2876 } 2877 2878 GLenum mode = 0; 2879 if (true == capture_interleaved) 2880 { 2881 mode = GL_INTERLEAVED_ATTRIBS; 2882 } 2883 else 2884 { 2885 mode = GL_SEPARATE_ATTRIBS; 2886 } 2887 2888 gl.transformFeedbackVaryings(id, static_cast<GLsizei>(n_varyings), &varying_names[0], mode); 2889 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings"); 2890 } 2891 2892 /** Create program instance 2893 * 2894 * @param gl GL functions 2895 * @param out_id Id of program 2896 **/ 2897 void Program::Create(const Functions& gl, GLuint& out_id) 2898 { 2899 const GLuint id = gl.createProgram(); 2900 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram"); 2901 2902 if (m_invalid_id == id) 2903 { 2904 TCU_FAIL("Failed to create program"); 2905 } 2906 2907 out_id = id; 2908 } 2909 2910 /** Get <pname> for a set of active uniforms 2911 * 2912 * @param gl Functions 2913 * @param program_id Id of program 2914 * @param count Number of indices 2915 * @param indices Indices of uniforms 2916 * @param pname Queired pname 2917 * @param params Array that will be filled with values of parameters 2918 **/ 2919 void Program::GetActiveUniformsiv(const Functions& gl, GLuint program_id, GLsizei count, const GLuint* indices, 2920 GLenum pname, GLint* params) 2921 { 2922 gl.getActiveUniformsiv(program_id, count, indices, pname, params); 2923 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv"); 2924 } 2925 2926 /** Get indices for a set of uniforms 2927 * 2928 * @param gl Functions 2929 * @param program_id Id of program 2930 * @param count Count number of uniforms 2931 * @param names Names of uniforms 2932 * @param indices Buffer that will be filled with indices 2933 **/ 2934 void Program::GetUniformIndices(const Functions& gl, GLuint program_id, GLsizei count, const GLchar** names, 2935 GLuint* indices) 2936 { 2937 gl.getUniformIndices(program_id, count, names, indices); 2938 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices"); 2939 } 2940 2941 /** Link program 2942 * 2943 * @param gl GL functions 2944 * @param id Id of program 2945 **/ 2946 void Program::Link(const Functions& gl, GLuint id) 2947 { 2948 GLint status = GL_FALSE; 2949 2950 gl.linkProgram(id); 2951 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram"); 2952 2953 /* Get link status */ 2954 gl.getProgramiv(id, GL_LINK_STATUS, &status); 2955 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 2956 2957 /* Log link error */ 2958 if (GL_TRUE != status) 2959 { 2960 glw::GLint length = 0; 2961 std::string message; 2962 2963 /* Get error log length */ 2964 gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length); 2965 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 2966 2967 message.resize(length, 0); 2968 2969 /* Get error log */ 2970 gl.getProgramInfoLog(id, length, 0, &message[0]); 2971 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog"); 2972 2973 throw LinkageException(message.c_str()); 2974 } 2975 } 2976 2977 /** Set generic uniform 2978 * 2979 * @param gl Functions 2980 * @param type Type of uniform 2981 * @param count Length of array 2982 * @param location Location of uniform 2983 * @param data Data that will be used 2984 **/ 2985 void Program::Uniform(const Functions& gl, const Type& type, GLsizei count, GLint location, const GLvoid* data) 2986 { 2987 if (-1 == location) 2988 { 2989 TCU_FAIL("Uniform is inactive"); 2990 } 2991 2992 switch (type.m_basic_type) 2993 { 2994 case Type::Double: 2995 if (1 == type.m_n_columns) 2996 { 2997 getUniformNdv(gl, type.m_n_rows)(location, count, (const GLdouble*)data); 2998 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNdv"); 2999 } 3000 else 3001 { 3002 getUniformMatrixNdv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLdouble*)data); 3003 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNdv"); 3004 } 3005 break; 3006 case Type::Float: 3007 if (1 == type.m_n_columns) 3008 { 3009 getUniformNfv(gl, type.m_n_rows)(location, count, (const GLfloat*)data); 3010 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNfv"); 3011 } 3012 else 3013 { 3014 getUniformMatrixNfv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLfloat*)data); 3015 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNfv"); 3016 } 3017 break; 3018 case Type::Int: 3019 getUniformNiv(gl, type.m_n_rows)(location, count, (const GLint*)data); 3020 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNiv"); 3021 break; 3022 case Type::Uint: 3023 getUniformNuiv(gl, type.m_n_rows)(location, count, (const GLuint*)data); 3024 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNuiv"); 3025 break; 3026 default: 3027 TCU_FAIL("Invalid enum"); 3028 } 3029 } 3030 3031 /** Use program 3032 * 3033 * @param gl GL functions 3034 * @param id Id of program 3035 **/ 3036 void Program::Use(const Functions& gl, GLuint id) 3037 { 3038 gl.useProgram(id); 3039 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram"); 3040 } 3041 3042 /** Get location of attribute 3043 * 3044 * @param gl GL functions 3045 * @param id Id of program 3046 * @param name Name of attribute 3047 * 3048 * @return Location of attribute 3049 **/ 3050 GLint Program::GetAttribLocation(const Functions& gl, GLuint id, const std::string& name) 3051 { 3052 GLint location = gl.getAttribLocation(id, name.c_str()); 3053 GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation"); 3054 3055 return location; 3056 } 3057 3058 /** Query resource 3059 * 3060 * @param gl GL functions 3061 * @param id Id of program 3062 * @param interface Interface to be queried 3063 * @param index Index of resource 3064 * @param property Property to be queried 3065 * @param buf_size Size of <params> buffer 3066 * @param params Results of query 3067 **/ 3068 void Program::GetResource(const Functions& gl, GLuint id, GLenum interface, GLuint index, GLenum property, 3069 GLsizei buf_size, GLint* params) 3070 { 3071 gl.getProgramResourceiv(id, interface, index, 1 /* propCount */, &property, buf_size /* bufSize */, 0 /* length */, 3072 params); 3073 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv"); 3074 } 3075 3076 /** Get index of resource 3077 * 3078 * @param gl GL functions 3079 * @param id Id of program 3080 * @param name Name of resource 3081 * @param interface Program interface to queried 3082 * 3083 * @return Location of attribute 3084 **/ 3085 GLuint Program::GetResourceIndex(const Functions& gl, GLuint id, const std::string& name, GLenum interface) 3086 { 3087 GLuint index = gl.getProgramResourceIndex(id, interface, name.c_str()); 3088 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex"); 3089 3090 return index; 3091 } 3092 3093 /** Get location of attribute 3094 * 3095 * @param gl GL functions 3096 * @param id Id of program 3097 * @param name Name of attribute 3098 * 3099 * @return Location of uniform 3100 **/ 3101 GLint Program::GetUniformLocation(const Functions& gl, GLuint id, const std::string& name) 3102 { 3103 GLint location = gl.getUniformLocation(id, name.c_str()); 3104 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation"); 3105 3106 return location; 3107 } 3108 3109 /** Constructor 3110 * 3111 * @param error_message Error message 3112 * @param compute_shader Source code for compute stage 3113 * @param fragment_shader Source code for fragment stage 3114 * @param geometry_shader Source code for geometry stage 3115 * @param tess_ctrl_shader Source code for tessellation control stage 3116 * @param tess_eval_shader Source code for tessellation evaluation stage 3117 * @param vertex_shader Source code for vertex stage 3118 **/ 3119 Program::BuildException::BuildException(const glw::GLchar* error_message, const std::string compute_shader, 3120 const std::string fragment_shader, const std::string geometry_shader, 3121 const std::string tess_ctrl_shader, const std::string tess_eval_shader, 3122 const std::string vertex_shader) 3123 : m_error_message(error_message) 3124 , m_compute_shader(compute_shader) 3125 , m_fragment_shader(fragment_shader) 3126 , m_geometry_shader(geometry_shader) 3127 , m_tess_ctrl_shader(tess_ctrl_shader) 3128 , m_tess_eval_shader(tess_eval_shader) 3129 , m_vertex_shader(vertex_shader) 3130 { 3131 } 3132 3133 /** Overwrites std::exception::what method 3134 * 3135 * @return Message compossed from error message and shader sources 3136 **/ 3137 const char* Program::BuildException::what() const throw() 3138 { 3139 return "Failed to link program"; 3140 } 3141 3142 /** Logs error message and shader sources **/ 3143 void Program::BuildException::log(deqp::Context& context) const 3144 { 3145 context.getTestContext().getLog() << tcu::TestLog::Message << "Link failure: " << m_error_message 3146 << tcu::TestLog::EndMessage; 3147 3148 Shader::LogSource(context, m_vertex_shader, Shader::VERTEX); 3149 Shader::LogSource(context, m_tess_ctrl_shader, Shader::TESS_CTRL); 3150 Shader::LogSource(context, m_tess_eval_shader, Shader::TESS_EVAL); 3151 Shader::LogSource(context, m_geometry_shader, Shader::GEOMETRY); 3152 Shader::LogSource(context, m_fragment_shader, Shader::FRAGMENT); 3153 Shader::LogSource(context, m_compute_shader, Shader::COMPUTE); 3154 } 3155 3156 /** Constructor 3157 * 3158 * @param message Linking error message 3159 **/ 3160 Program::LinkageException::LinkageException(const glw::GLchar* message) : m_error_message(message) 3161 { 3162 /* Nothing to be done */ 3163 } 3164 3165 /** Returns error messages 3166 * 3167 * @return Linking error message 3168 **/ 3169 const char* Program::LinkageException::what() const throw() 3170 { 3171 return m_error_message.c_str(); 3172 } 3173 3174 /* Texture constants */ 3175 const GLuint Texture::m_invalid_id = -1; 3176 3177 /** Constructor. 3178 * 3179 * @param context CTS context. 3180 **/ 3181 Texture::Texture(deqp::Context& context) : m_id(m_invalid_id), m_context(context), m_type(TEX_2D) 3182 { 3183 /* Nothing to done here */ 3184 } 3185 3186 /** Destructor 3187 * 3188 **/ 3189 Texture::~Texture() 3190 { 3191 Release(); 3192 } 3193 3194 /** Initialize texture instance 3195 * 3196 * @param tex_type Type of texture 3197 * @param width Width of texture 3198 * @param height Height of texture 3199 * @param depth Depth of texture 3200 * @param internal_format Internal format of texture 3201 * @param format Format of texture data 3202 * @param type Type of texture data 3203 * @param data Texture data 3204 **/ 3205 void Texture::Init(TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum internal_format, GLenum format, 3206 GLenum type, GLvoid* data) 3207 { 3208 const Functions& gl = m_context.getRenderContext().getFunctions(); 3209 3210 /* Delete previous texture */ 3211 Release(); 3212 3213 m_type = tex_type; 3214 3215 /* Generate, bind, allocate storage and upload data */ 3216 Generate(gl, m_id); 3217 Bind(gl, m_id, tex_type); 3218 Storage(gl, tex_type, width, height, depth, internal_format); 3219 Update(gl, tex_type, width, height, depth, format, type, data); 3220 } 3221 3222 /** Initialize buffer texture 3223 * 3224 * @param internal_format Internal format of texture 3225 * @param buffer_id Id of buffer that will be used as data source 3226 **/ 3227 void Texture::Init(GLenum internal_format, GLuint buffer_id) 3228 { 3229 const Functions& gl = m_context.getRenderContext().getFunctions(); 3230 3231 /* Delete previous texture */ 3232 Release(); 3233 3234 m_type = TEX_BUFFER; 3235 3236 /* Generate, bind and attach buffer */ 3237 Generate(gl, m_id); 3238 Bind(gl, m_id, TEX_BUFFER); 3239 TexBuffer(gl, buffer_id, internal_format); 3240 } 3241 3242 /** Release texture instance 3243 * 3244 **/ 3245 void Texture::Release() 3246 { 3247 if (m_invalid_id != m_id) 3248 { 3249 const Functions& gl = m_context.getRenderContext().getFunctions(); 3250 3251 gl.deleteTextures(1, &m_id); 3252 m_id = m_invalid_id; 3253 } 3254 } 3255 3256 /** Bind texture to its target 3257 * 3258 **/ 3259 void Texture::Bind() const 3260 { 3261 const Functions& gl = m_context.getRenderContext().getFunctions(); 3262 3263 Bind(gl, m_id, m_type); 3264 } 3265 3266 /** Get texture data 3267 * 3268 * @param format Format of data 3269 * @param type Type of data 3270 * @param out_data Buffer for data 3271 **/ 3272 void Texture::Get(GLenum format, GLenum type, GLvoid* out_data) const 3273 { 3274 const Functions& gl = m_context.getRenderContext().getFunctions(); 3275 3276 Bind(gl, m_id, m_type); 3277 Get(gl, m_type, format, type, out_data); 3278 } 3279 3280 /** Bind texture to target 3281 * 3282 * @param gl GL functions 3283 * @param id Id of texture 3284 * @param tex_type Type of texture 3285 **/ 3286 void Texture::Bind(const Functions& gl, GLuint id, TYPES tex_type) 3287 { 3288 GLenum target = GetTargetGLenum(tex_type); 3289 3290 gl.bindTexture(target, id); 3291 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 3292 } 3293 3294 /** Generate texture instance 3295 * 3296 * @param gl GL functions 3297 * @param out_id Id of texture 3298 **/ 3299 void Texture::Generate(const Functions& gl, GLuint& out_id) 3300 { 3301 GLuint id = m_invalid_id; 3302 3303 gl.genTextures(1, &id); 3304 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures"); 3305 3306 if (m_invalid_id == id) 3307 { 3308 TCU_FAIL("Invalid id"); 3309 } 3310 3311 out_id = id; 3312 } 3313 3314 /** Get texture data 3315 * 3316 * @param gl GL functions 3317 * @param format Format of data 3318 * @param type Type of data 3319 * @param out_data Buffer for data 3320 **/ 3321 void Texture::Get(const Functions& gl, TYPES tex_type, GLenum format, GLenum type, GLvoid* out_data) 3322 { 3323 GLenum target = GetTargetGLenum(tex_type); 3324 3325 if (TEX_CUBE != tex_type) 3326 { 3327 gl.getTexImage(target, 0 /* level */, format, type, out_data); 3328 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage"); 3329 } 3330 else 3331 { 3332 GLint width; 3333 GLint height; 3334 3335 if ((GL_RGBA != format) && (GL_UNSIGNED_BYTE != type)) 3336 { 3337 TCU_FAIL("Not implemented"); 3338 } 3339 3340 GLuint texel_size = 4; 3341 3342 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_WIDTH, &width); 3343 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv"); 3344 3345 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_HEIGHT, &height); 3346 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv"); 3347 3348 const GLuint image_size = width * height * texel_size; 3349 3350 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, format, type, 3351 (GLvoid*)((GLchar*)out_data + (image_size * 0))); 3352 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0 /* level */, format, type, 3353 (GLvoid*)((GLchar*)out_data + (image_size * 1))); 3354 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0 /* level */, format, type, 3355 (GLvoid*)((GLchar*)out_data + (image_size * 2))); 3356 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0 /* level */, format, type, 3357 (GLvoid*)((GLchar*)out_data + (image_size * 3))); 3358 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0 /* level */, format, type, 3359 (GLvoid*)((GLchar*)out_data + (image_size * 4))); 3360 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0 /* level */, format, type, 3361 (GLvoid*)((GLchar*)out_data + (image_size * 5))); 3362 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage"); 3363 } 3364 } 3365 3366 /** Allocate storage for texture 3367 * 3368 * @param gl GL functions 3369 * @param tex_type Type of texture 3370 * @param width Width of texture 3371 * @param height Height of texture 3372 * @param depth Depth of texture 3373 * @param internal_format Internal format of texture 3374 **/ 3375 void Texture::Storage(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, 3376 GLenum internal_format) 3377 { 3378 static const GLuint levels = 1; 3379 3380 GLenum target = GetTargetGLenum(tex_type); 3381 3382 switch (tex_type) 3383 { 3384 case TEX_1D: 3385 gl.texStorage1D(target, levels, internal_format, width); 3386 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D"); 3387 break; 3388 case TEX_2D: 3389 case TEX_1D_ARRAY: 3390 case TEX_2D_RECT: 3391 case TEX_CUBE: 3392 gl.texStorage2D(target, levels, internal_format, width, height); 3393 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D"); 3394 break; 3395 case TEX_3D: 3396 case TEX_2D_ARRAY: 3397 gl.texStorage3D(target, levels, internal_format, width, height, depth); 3398 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D"); 3399 break; 3400 default: 3401 TCU_FAIL("Invliad enum"); 3402 break; 3403 } 3404 } 3405 3406 /** Attach buffer as source of texture buffer data 3407 * 3408 * @param gl GL functions 3409 * @param internal_format Internal format of texture 3410 * @param buffer_id Id of buffer that will be used as data source 3411 **/ 3412 void Texture::TexBuffer(const Functions& gl, GLenum internal_format, GLuint& buffer_id) 3413 { 3414 gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id); 3415 GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer"); 3416 } 3417 3418 /** Update contents of texture 3419 * 3420 * @param gl GL functions 3421 * @param tex_type Type of texture 3422 * @param width Width of texture 3423 * @param height Height of texture 3424 * @param format Format of data 3425 * @param type Type of data 3426 * @param data Buffer with image data 3427 **/ 3428 void Texture::Update(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum format, 3429 GLenum type, GLvoid* data) 3430 { 3431 static const GLuint level = 0; 3432 3433 GLenum target = GetTargetGLenum(tex_type); 3434 3435 switch (tex_type) 3436 { 3437 case TEX_1D: 3438 gl.texSubImage1D(target, level, 0 /* x */, width, format, type, data); 3439 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D"); 3440 break; 3441 case TEX_2D: 3442 case TEX_1D_ARRAY: 3443 case TEX_2D_RECT: 3444 gl.texSubImage2D(target, level, 0 /* x */, 0 /* y */, width, height, format, type, data); 3445 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D"); 3446 break; 3447 case TEX_CUBE: 3448 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type, 3449 data); 3450 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type, 3451 data); 3452 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type, 3453 data); 3454 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type, 3455 data); 3456 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type, 3457 data); 3458 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type, 3459 data); 3460 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D"); 3461 break; 3462 case TEX_3D: 3463 case TEX_2D_ARRAY: 3464 gl.texSubImage3D(target, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format, type, data); 3465 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D"); 3466 break; 3467 default: 3468 TCU_FAIL("Invliad enum"); 3469 break; 3470 } 3471 } 3472 3473 /** Get target for given texture type 3474 * 3475 * @param type Type of texture 3476 * 3477 * @return Target 3478 **/ 3479 GLenum Texture::GetTargetGLenum(TYPES type) 3480 { 3481 GLenum result = 0; 3482 3483 switch (type) 3484 { 3485 case TEX_BUFFER: 3486 result = GL_TEXTURE_BUFFER; 3487 break; 3488 case TEX_2D: 3489 result = GL_TEXTURE_2D; 3490 break; 3491 case TEX_2D_RECT: 3492 result = GL_TEXTURE_RECTANGLE; 3493 break; 3494 case TEX_2D_ARRAY: 3495 result = GL_TEXTURE_2D_ARRAY; 3496 break; 3497 case TEX_3D: 3498 result = GL_TEXTURE_3D; 3499 break; 3500 case TEX_CUBE: 3501 result = GL_TEXTURE_CUBE_MAP; 3502 break; 3503 case TEX_1D: 3504 result = GL_TEXTURE_1D; 3505 break; 3506 case TEX_1D_ARRAY: 3507 result = GL_TEXTURE_1D_ARRAY; 3508 break; 3509 } 3510 3511 return result; 3512 } 3513 3514 /* VertexArray constants */ 3515 const GLuint VertexArray::m_invalid_id = -1; 3516 3517 /** Constructor. 3518 * 3519 * @param context CTS context. 3520 **/ 3521 VertexArray::VertexArray(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 3522 { 3523 } 3524 3525 /** Destructor 3526 * 3527 **/ 3528 VertexArray::~VertexArray() 3529 { 3530 Release(); 3531 } 3532 3533 /** Initialize vertex array instance 3534 * 3535 **/ 3536 void VertexArray::Init() 3537 { 3538 /* Delete previous instance */ 3539 Release(); 3540 3541 const Functions& gl = m_context.getRenderContext().getFunctions(); 3542 3543 Generate(gl, m_id); 3544 } 3545 3546 /** Release vertex array object instance 3547 * 3548 **/ 3549 void VertexArray::Release() 3550 { 3551 if (m_invalid_id != m_id) 3552 { 3553 const Functions& gl = m_context.getRenderContext().getFunctions(); 3554 3555 gl.deleteVertexArrays(1, &m_id); 3556 3557 m_id = m_invalid_id; 3558 } 3559 } 3560 3561 /** Set attribute in VAO 3562 * 3563 * @param index Index of attribute 3564 * @param type Type of attribute 3565 * @param n_array_elements Arary length 3566 * @param normalized Selectis if values should be normalized 3567 * @param stride Stride 3568 * @param pointer Pointer to data, or offset in buffer 3569 **/ 3570 void VertexArray::Attribute(GLuint index, const Type& type, GLuint n_array_elements, GLboolean normalized, 3571 GLsizei stride, const GLvoid* pointer) 3572 { 3573 const Functions& gl = m_context.getRenderContext().getFunctions(); 3574 3575 AttribPointer(gl, index, type, n_array_elements, normalized, stride, pointer); 3576 Enable(gl, index, type, n_array_elements); 3577 } 3578 3579 /** Binds Vertex array object 3580 * 3581 **/ 3582 void VertexArray::Bind() 3583 { 3584 const Functions& gl = m_context.getRenderContext().getFunctions(); 3585 3586 Bind(gl, m_id); 3587 } 3588 3589 /** Set attribute in VAO 3590 * 3591 * @param gl Functions 3592 * @param index Index of attribute 3593 * @param type Type of attribute 3594 * @param n_array_elements Arary length 3595 * @param normalized Selectis if values should be normalized 3596 * @param stride Stride 3597 * @param pointer Pointer to data, or offset in buffer 3598 **/ 3599 void VertexArray::AttribPointer(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements, 3600 GLboolean normalized, GLsizei stride, const GLvoid* pointer) 3601 { 3602 const GLuint basic_type_size = Type::GetTypeSize(type.m_basic_type); 3603 const GLint size = (GLint)type.m_n_rows; 3604 const GLuint column_size = (GLuint)size * basic_type_size; 3605 const GLenum gl_type = Type::GetTypeGLenum(type.m_basic_type); 3606 3607 GLuint offset = 0; 3608 3609 /* If attribute is not an array */ 3610 if (0 == n_array_elements) 3611 { 3612 n_array_elements = 1; 3613 } 3614 3615 /* For each element in array */ 3616 for (GLuint element = 0; element < n_array_elements; ++element) 3617 { 3618 /* For each column in matrix */ 3619 for (GLuint column = 1; column <= type.m_n_columns; ++column) 3620 { 3621 /* Calculate offset */ 3622 const GLvoid* ptr = (GLubyte*)pointer + offset; 3623 3624 /* Set up attribute */ 3625 switch (type.m_basic_type) 3626 { 3627 case Type::Float: 3628 gl.vertexAttribPointer(index, size, gl_type, normalized, stride, ptr); 3629 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribPointer"); 3630 break; 3631 case Type::Int: 3632 case Type::Uint: 3633 gl.vertexAttribIPointer(index, size, gl_type, stride, ptr); 3634 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribIPointer"); 3635 break; 3636 case Type::Double: 3637 gl.vertexAttribLPointer(index, size, gl_type, stride, ptr); 3638 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribLPointer"); 3639 break; 3640 default: 3641 TCU_FAIL("Invalid enum"); 3642 } 3643 3644 /* Next location */ 3645 offset += column_size; 3646 index += 1; 3647 } 3648 } 3649 } 3650 3651 /** Binds Vertex array object 3652 * 3653 * @param gl GL functions 3654 * @param id ID of vertex array object 3655 **/ 3656 void VertexArray::Bind(const glw::Functions& gl, glw::GLuint id) 3657 { 3658 gl.bindVertexArray(id); 3659 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray"); 3660 } 3661 3662 /** Disable attribute in VAO 3663 * 3664 * @param gl Functions 3665 * @param index Index of attribute 3666 * @param type Type of attribute 3667 * @param n_array_elements Arary length 3668 **/ 3669 void VertexArray::Disable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements) 3670 { 3671 /* If attribute is not an array */ 3672 if (0 == n_array_elements) 3673 { 3674 n_array_elements = 1; 3675 } 3676 3677 /* For each element in array */ 3678 for (GLuint element = 0; element < n_array_elements; ++element) 3679 { 3680 /* For each column in matrix */ 3681 for (GLuint column = 1; column <= type.m_n_columns; ++column) 3682 { 3683 /* Enable attribute array */ 3684 gl.disableVertexAttribArray(index); 3685 GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray"); 3686 3687 /* Next location */ 3688 index += 1; 3689 } 3690 } 3691 } 3692 3693 /** Set divisor for attribute 3694 * 3695 * @param gl Functions 3696 * @param index Index of attribute 3697 * @param divisor New divisor value 3698 **/ 3699 void VertexArray::Divisor(const Functions& gl, GLuint index, GLuint divisor) 3700 { 3701 gl.vertexAttribDivisor(index, divisor); 3702 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribDivisor"); 3703 } 3704 3705 /** Enables attribute in VAO 3706 * 3707 * @param gl Functions 3708 * @param index Index of attribute 3709 * @param type Type of attribute 3710 * @param n_array_elements Arary length 3711 **/ 3712 void VertexArray::Enable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements) 3713 { 3714 /* If attribute is not an array */ 3715 if (0 == n_array_elements) 3716 { 3717 n_array_elements = 1; 3718 } 3719 3720 /* For each element in array */ 3721 for (GLuint element = 0; element < n_array_elements; ++element) 3722 { 3723 /* For each column in matrix */ 3724 for (GLuint column = 1; column <= type.m_n_columns; ++column) 3725 { 3726 /* Enable attribute array */ 3727 gl.enableVertexAttribArray(index); 3728 GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray"); 3729 3730 /* Next location */ 3731 index += 1; 3732 } 3733 } 3734 } 3735 3736 /** Generates Vertex array object 3737 * 3738 * @param gl GL functions 3739 * @param out_id ID of vertex array object 3740 **/ 3741 void VertexArray::Generate(const glw::Functions& gl, glw::GLuint& out_id) 3742 { 3743 GLuint id = m_invalid_id; 3744 3745 gl.genVertexArrays(1, &id); 3746 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays"); 3747 3748 if (m_invalid_id == id) 3749 { 3750 TCU_FAIL("Invalid id"); 3751 } 3752 3753 out_id = id; 3754 } 3755 3756 /* Constatns used by Variable */ 3757 const GLint Variable::m_automatic_location = -1; 3758 3759 /** Copy constructor 3760 * 3761 **/ 3762 Variable::Variable(const Variable& var) 3763 : m_data(var.m_data) 3764 , m_data_size(var.m_data_size) 3765 , m_descriptor(var.m_descriptor.m_name.c_str(), var.m_descriptor.m_qualifiers.c_str(), 3766 var.m_descriptor.m_expected_component, var.m_descriptor.m_expected_location, 3767 var.m_descriptor.m_builtin, var.m_descriptor.m_normalized, var.m_descriptor.m_n_array_elements, 3768 var.m_descriptor.m_expected_stride_of_element, var.m_descriptor.m_offset) 3769 , m_storage(var.m_storage) 3770 { 3771 m_descriptor.m_type = var.m_descriptor.m_type; 3772 3773 if (BUILTIN != var.m_descriptor.m_type) 3774 { 3775 m_descriptor.m_interface = var.m_descriptor.m_interface; 3776 } 3777 } 3778 3779 /** Get code that defines variable 3780 * 3781 * @param flavour Provides info if variable is array or not 3782 * 3783 * @return String with code 3784 **/ 3785 std::string Variable::GetDefinition(FLAVOUR flavour) const 3786 { 3787 return m_descriptor.GetDefinition(flavour, m_storage); 3788 } 3789 3790 /** Calcualtes stride of variable 3791 * 3792 * @return Calculated value 3793 **/ 3794 GLuint Variable::GetStride() const 3795 { 3796 GLint variable_stride = 0; 3797 3798 if (0 == m_descriptor.m_n_array_elements) 3799 { 3800 variable_stride = m_descriptor.m_expected_stride_of_element; 3801 } 3802 else 3803 { 3804 variable_stride = m_descriptor.m_expected_stride_of_element * m_descriptor.m_n_array_elements; 3805 } 3806 3807 return variable_stride; 3808 } 3809 3810 /** Check if variable is block 3811 * 3812 * @return true if variable type is block, false otherwise 3813 **/ 3814 bool Variable::IsBlock() const 3815 { 3816 if (BUILTIN == m_descriptor.m_type) 3817 { 3818 return false; 3819 } 3820 3821 const Interface* interface = m_descriptor.m_interface; 3822 if (0 == interface) 3823 { 3824 TCU_FAIL("Nullptr"); 3825 } 3826 3827 return (Interface::BLOCK == interface->m_type); 3828 } 3829 3830 /** Check if variable is struct 3831 * 3832 * @return true if variable type is struct, false otherwise 3833 **/ 3834 bool Variable::IsStruct() const 3835 { 3836 if (BUILTIN == m_descriptor.m_type) 3837 { 3838 return false; 3839 } 3840 3841 const Interface* interface = m_descriptor.m_interface; 3842 if (0 == interface) 3843 { 3844 TCU_FAIL("Nullptr"); 3845 } 3846 3847 return (Interface::STRUCT == interface->m_type); 3848 } 3849 /** Get code that reference variable 3850 * 3851 * @param parent_name Name of parent 3852 * @param variable Descriptor of variable 3853 * @param flavour Provides info about how variable should be referenced 3854 * @param array_index Index of array, ignored when variable is not array 3855 * 3856 * @return String with code 3857 **/ 3858 std::string Variable::GetReference(const std::string& parent_name, const Descriptor& variable, FLAVOUR flavour, 3859 GLuint array_index) 3860 { 3861 std::string name; 3862 3863 /* Prepare name */ 3864 if (false == parent_name.empty()) 3865 { 3866 name = parent_name; 3867 name.append("."); 3868 name.append(variable.m_name); 3869 } 3870 else 3871 { 3872 name = variable.m_name; 3873 } 3874 3875 /* */ 3876 switch (flavour) 3877 { 3878 case Utils::Variable::BASIC: 3879 break; 3880 3881 case Utils::Variable::ARRAY: 3882 name.append("[0]"); 3883 break; 3884 3885 case Utils::Variable::INDEXED_BY_INVOCATION_ID: 3886 name.append("[gl_InvocationID]"); 3887 break; 3888 } 3889 3890 /* Assumption that both variables have same lengths */ 3891 if (0 != variable.m_n_array_elements) 3892 { 3893 GLchar buffer[16]; 3894 sprintf(buffer, "%d", array_index); 3895 name.append("["); 3896 name.append(buffer); 3897 name.append("]"); 3898 } 3899 3900 return name; 3901 } 3902 3903 /** Get "flavour" of varying 3904 * 3905 * @param stage Stage of shader 3906 * @param direction Selects if varying is in or out 3907 * 3908 * @return Flavour 3909 **/ 3910 Variable::FLAVOUR Variable::GetFlavour(Shader::STAGES stage, VARYING_DIRECTION direction) 3911 { 3912 FLAVOUR result = BASIC; 3913 3914 switch (stage) 3915 { 3916 case Shader::GEOMETRY: 3917 case Shader::TESS_EVAL: 3918 if (INPUT == direction) 3919 { 3920 result = ARRAY; 3921 } 3922 break; 3923 case Shader::TESS_CTRL: 3924 result = INDEXED_BY_INVOCATION_ID; 3925 break; 3926 default: 3927 break; 3928 } 3929 3930 return result; 3931 } 3932 3933 /** Constructor, for built-in types 3934 * 3935 * @param name Name 3936 * @param qualifiers Qualifiers 3937 * @param expected_component Expected component of variable 3938 * @param expected_location Expected location 3939 * @param type Type 3940 * @param normalized Selects if data should be normalized 3941 * @param n_array_elements Length of array 3942 * @param expected_stride_of_element Expected stride of element 3943 * @param offset Offset 3944 **/ 3945 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_component, 3946 GLint expected_location, const Type& type, GLboolean normalized, 3947 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset) 3948 : m_expected_component(expected_component) 3949 , m_expected_location(expected_location) 3950 , m_expected_stride_of_element(expected_stride_of_element) 3951 , m_n_array_elements(n_array_elements) 3952 , m_name(name) 3953 , m_normalized(normalized) 3954 , m_offset(offset) 3955 , m_qualifiers(qualifiers) 3956 , m_type(BUILTIN) 3957 , m_builtin(type) 3958 { 3959 } 3960 3961 /** Constructor, for interface types 3962 * 3963 * @param name Name 3964 * @param qualifiers Qualifiers 3965 * @param expected_component Expected component of variable 3966 * @param expected_location Expected location 3967 * @param interface Interface of variable 3968 * @param n_array_elements Length of array 3969 * @param expected_stride_of_element Expected stride of element 3970 * @param offset Offset 3971 **/ 3972 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_componenet, 3973 GLint expected_location, Interface* interface, GLuint n_array_elements, 3974 GLint expected_stride_of_element, GLuint offset) 3975 : m_expected_component(expected_componenet) 3976 , m_expected_location(expected_location) 3977 , m_expected_stride_of_element(expected_stride_of_element) 3978 , m_n_array_elements(n_array_elements) 3979 , m_name(name) 3980 , m_normalized(GL_FALSE) 3981 , m_offset(offset) 3982 , m_qualifiers(qualifiers) 3983 , m_type(INTERFACE) 3984 , m_interface(interface) 3985 { 3986 } 3987 3988 /** Get definition of variable 3989 * 3990 * @param flavour Flavour of variable 3991 * @param storage Storage used for variable 3992 * 3993 * @return code with defintion 3994 **/ 3995 std::string Variable::Descriptor::GetDefinition(FLAVOUR flavour, STORAGE storage) const 3996 { 3997 static const GLchar* basic_template = "QUALIFIERS STORAGETYPE NAMEARRAY;"; 3998 static const GLchar* array_template = "QUALIFIERS STORAGETYPE NAME[]ARRAY;"; 3999 const GLchar* storage_str = 0; 4000 4001 std::string definition; 4002 size_t position = 0; 4003 4004 /* Select definition template */ 4005 switch (flavour) 4006 { 4007 case BASIC: 4008 definition = basic_template; 4009 break; 4010 case ARRAY: 4011 case INDEXED_BY_INVOCATION_ID: 4012 definition = array_template; 4013 break; 4014 default: 4015 TCU_FAIL("Invliad enum"); 4016 break; 4017 } 4018 4019 if (BUILTIN != m_type) 4020 { 4021 if (0 == m_interface) 4022 { 4023 TCU_FAIL("Nullptr"); 4024 } 4025 } 4026 4027 /* Qualifiers */ 4028 if (true == m_qualifiers.empty()) 4029 { 4030 replaceToken("QUALIFIERS ", position, "", definition); 4031 } 4032 else 4033 { 4034 replaceToken("QUALIFIERS", position, m_qualifiers.c_str(), definition); 4035 } 4036 4037 // According to spec: int, uint, and double type must always be declared with flat qualifier 4038 bool flat_qualifier = false; 4039 if (m_type != BUILTIN && m_interface != NULL) 4040 { 4041 if (m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Int || 4042 m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Uint || 4043 m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Double) 4044 { 4045 flat_qualifier = true; 4046 } 4047 } 4048 /* Storage */ 4049 switch (storage) 4050 { 4051 case VARYING_INPUT: 4052 storage_str = flat_qualifier ? "flat in " : "in "; 4053 break; 4054 case VARYING_OUTPUT: 4055 storage_str = "out "; 4056 break; 4057 case UNIFORM: 4058 storage_str = "uniform "; 4059 break; 4060 case SSB: 4061 storage_str = "buffer "; 4062 break; 4063 case MEMBER: 4064 storage_str = ""; 4065 break; 4066 default: 4067 TCU_FAIL("Invalid enum"); 4068 break; 4069 } 4070 4071 replaceToken("STORAGE", position, storage_str, definition); 4072 4073 /* Type */ 4074 if (BUILTIN == m_type) 4075 { 4076 replaceToken("TYPE", position, m_builtin.GetGLSLTypeName(), definition); 4077 } 4078 else 4079 { 4080 if (Interface::STRUCT == m_interface->m_type) 4081 { 4082 replaceToken("TYPE", position, m_interface->m_name.c_str(), definition); 4083 } 4084 else 4085 { 4086 const std::string& block_definition = m_interface->GetDefinition(); 4087 4088 replaceToken("TYPE", position, block_definition.c_str(), definition); 4089 } 4090 } 4091 4092 /* Name */ 4093 replaceToken("NAME", position, m_name.c_str(), definition); 4094 4095 /* Array size */ 4096 if (0 == m_n_array_elements) 4097 { 4098 replaceToken("ARRAY", position, "", definition); 4099 } 4100 else 4101 { 4102 char buffer[16]; 4103 sprintf(buffer, "[%d]", m_n_array_elements); 4104 4105 replaceToken("ARRAY", position, buffer, definition); 4106 } 4107 4108 /* Done */ 4109 return definition; 4110 } 4111 4112 /** Get definitions for variables collected in vector 4113 * 4114 * @param vector Collection of variables 4115 * @param flavour Flavour of variables 4116 * 4117 * @return Code with definitions 4118 **/ 4119 std::string GetDefinitions(const Variable::PtrVector& vector, Variable::FLAVOUR flavour) 4120 { 4121 std::string list = Utils::g_list; 4122 size_t position = 0; 4123 4124 for (GLuint i = 0; i < vector.size(); ++i) 4125 { 4126 Utils::insertElementOfList(vector[i]->GetDefinition(flavour).c_str(), "\n", position, list); 4127 } 4128 4129 Utils::endList("", position, list); 4130 4131 return list; 4132 } 4133 4134 /** Get definitions for interfaces collected in vector 4135 * 4136 * @param vector Collection of interfaces 4137 * 4138 * @return Code with definitions 4139 **/ 4140 std::string GetDefinitions(const Interface::PtrVector& vector) 4141 { 4142 std::string list = Utils::g_list; 4143 size_t position = 0; 4144 4145 for (GLuint i = 0; i < vector.size(); ++i) 4146 { 4147 Utils::insertElementOfList(vector[i]->GetDefinition().c_str(), "\n", position, list); 4148 } 4149 4150 Utils::endList("", position, list); 4151 4152 return list; 4153 } 4154 4155 /** Constructor 4156 * 4157 * @param name Name 4158 * @param type Type of interface 4159 **/ 4160 Interface::Interface(const GLchar* name, Interface::TYPE type) : m_name(name), m_type(type) 4161 { 4162 } 4163 4164 /** Adds member to interface 4165 * 4166 * @param member Descriptor of new member 4167 * 4168 * @return Pointer to just created member 4169 **/ 4170 Variable::Descriptor* Interface::AddMember(const Variable::Descriptor& member) 4171 { 4172 m_members.push_back(member); 4173 4174 return &m_members.back(); 4175 } 4176 4177 /** Get definition of interface 4178 * 4179 * @param Code with definition 4180 **/ 4181 std::string Interface::GetDefinition() const 4182 { 4183 std::string definition; 4184 size_t position = 0; 4185 4186 const GLchar* member_list = " MEMBER_DEFINITION\nMEMBER_LIST"; 4187 4188 if (STRUCT == m_type) 4189 { 4190 definition = "struct NAME {\nMEMBER_LIST};"; 4191 } 4192 else 4193 { 4194 definition = "NAME {\nMEMBER_LIST}"; 4195 } 4196 4197 /* Name */ 4198 replaceToken("NAME", position, m_name.c_str(), definition); 4199 4200 /* Member list */ 4201 for (GLuint i = 0; i < m_members.size(); ++i) 4202 { 4203 const size_t start_position = position; 4204 const std::string& member_definition = m_members[i].GetDefinition(Variable::BASIC, Variable::MEMBER); 4205 4206 /* Member list */ 4207 replaceToken("MEMBER_LIST", position, member_list, definition); 4208 4209 /* Move back position */ 4210 position = start_position; 4211 4212 /* Member definition */ 4213 replaceToken("MEMBER_DEFINITION", position, member_definition.c_str(), definition); 4214 } 4215 4216 /* Remove last member list */ 4217 replaceToken("MEMBER_LIST", position, "", definition); 4218 4219 /* Done */ 4220 return definition; 4221 } 4222 4223 /** Adds member of built-in type to interface 4224 * 4225 * @param name Name 4226 * @param qualifiers Qualifiers 4227 * @param expected_component Expected component of variable 4228 * @param expected_location Expected location 4229 * @param type Type 4230 * @param normalized Selects if data should be normalized 4231 * @param n_array_elements Length of array 4232 * @param expected_stride_of_element Expected stride of element 4233 * @param offset Offset 4234 * 4235 * @return Pointer to just created member 4236 **/ 4237 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component, 4238 GLint expected_location, const Type& type, GLboolean normalized, 4239 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset) 4240 { 4241 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, type, normalized, 4242 n_array_elements, expected_stride_of_element, offset)); 4243 } 4244 4245 /** Adds member of interface type to interface 4246 * 4247 * @param name Name 4248 * @param qualifiers Qualifiers 4249 * @param expected_component Expected component of variable 4250 * @param expected_location Expected location 4251 * @param type Type 4252 * @param normalized Selects if data should be normalized 4253 * @param n_array_elements Length of array 4254 * @param expected_stride_of_element Expected stride of element 4255 * @param offset Offset 4256 * 4257 * @return Pointer to just created member 4258 **/ 4259 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component, 4260 GLint expected_location, Interface* nterface, GLuint n_array_elements, 4261 GLint expected_stride_of_element, GLuint offset) 4262 { 4263 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, nterface, 4264 n_array_elements, expected_stride_of_element, offset)); 4265 } 4266 4267 /** Clears contents of vector of pointers 4268 * 4269 * @tparam T Type of elements 4270 * 4271 * @param vector Collection to be cleared 4272 **/ 4273 template <typename T> 4274 void clearPtrVector(std::vector<T*>& vector) 4275 { 4276 for (size_t i = 0; i < vector.size(); ++i) 4277 { 4278 T* t = vector[i]; 4279 4280 vector[i] = 0; 4281 4282 if (0 != t) 4283 { 4284 delete t; 4285 } 4286 } 4287 4288 vector.clear(); 4289 } 4290 4291 /** Constructor 4292 * 4293 * @param stage Stage described by that interface 4294 **/ 4295 ShaderInterface::ShaderInterface(Shader::STAGES stage) : m_stage(stage) 4296 { 4297 /* Nothing to be done */ 4298 } 4299 4300 /** Get definitions of globals 4301 * 4302 * @return Code with definitions 4303 **/ 4304 std::string ShaderInterface::GetDefinitionsGlobals() const 4305 { 4306 return m_globals; 4307 } 4308 4309 /** Get definitions of inputs 4310 * 4311 * @return Code with definitions 4312 **/ 4313 std::string ShaderInterface::GetDefinitionsInputs() const 4314 { 4315 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::INPUT); 4316 4317 return GetDefinitions(m_inputs, flavour); 4318 } 4319 4320 /** Get definitions of outputs 4321 * 4322 * @return Code with definitions 4323 **/ 4324 std::string ShaderInterface::GetDefinitionsOutputs() const 4325 { 4326 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::OUTPUT); 4327 4328 return GetDefinitions(m_outputs, flavour); 4329 } 4330 4331 /** Get definitions of buffers 4332 * 4333 * @return Code with definitions 4334 **/ 4335 std::string ShaderInterface::GetDefinitionsSSBs() const 4336 { 4337 return GetDefinitions(m_ssb_blocks, Variable::BASIC); 4338 } 4339 4340 /** Get definitions of uniforms 4341 * 4342 * @return Code with definitions 4343 **/ 4344 std::string ShaderInterface::GetDefinitionsUniforms() const 4345 { 4346 return GetDefinitions(m_uniforms, Variable::BASIC); 4347 } 4348 4349 /** Constructor 4350 * 4351 * @param in Input variable 4352 * @param out Output variable 4353 **/ 4354 VaryingConnection::VaryingConnection(Variable* in, Variable* out) : m_in(in), m_out(out) 4355 { 4356 /* NBothing to be done here */ 4357 } 4358 4359 /** Adds new varying connection to given stage 4360 * 4361 * @param stage Shader stage 4362 * @param in In varying 4363 * @param out Out varying 4364 **/ 4365 void VaryingPassthrough::Add(Shader::STAGES stage, Variable* in, Variable* out) 4366 { 4367 VaryingConnection::Vector& vector = Get(stage); 4368 4369 vector.push_back(VaryingConnection(in, out)); 4370 } 4371 4372 /** Get all passthrough connections for given stage 4373 * 4374 * @param stage Shader stage 4375 * 4376 * @return Vector of connections 4377 **/ 4378 VaryingConnection::Vector& VaryingPassthrough::Get(Shader::STAGES stage) 4379 { 4380 VaryingConnection::Vector* result = 0; 4381 4382 switch (stage) 4383 { 4384 case Shader::FRAGMENT: 4385 result = &m_fragment; 4386 break; 4387 case Shader::GEOMETRY: 4388 result = &m_geometry; 4389 break; 4390 case Shader::TESS_CTRL: 4391 result = &m_tess_ctrl; 4392 break; 4393 case Shader::TESS_EVAL: 4394 result = &m_tess_eval; 4395 break; 4396 case Shader::VERTEX: 4397 result = &m_vertex; 4398 break; 4399 default: 4400 TCU_FAIL("Invalid enum"); 4401 } 4402 4403 return *result; 4404 } 4405 4406 /** Constructor 4407 * 4408 **/ 4409 ProgramInterface::ProgramInterface() 4410 : m_compute(Shader::COMPUTE) 4411 , m_vertex(Shader::VERTEX) 4412 , m_tess_ctrl(Shader::TESS_CTRL) 4413 , m_tess_eval(Shader::TESS_EVAL) 4414 , m_geometry(Shader::GEOMETRY) 4415 , m_fragment(Shader::FRAGMENT) 4416 { 4417 } 4418 4419 /** Destructor 4420 * 4421 **/ 4422 ProgramInterface::~ProgramInterface() 4423 { 4424 clearPtrVector(m_blocks); 4425 clearPtrVector(m_structures); 4426 } 4427 4428 /** Adds new interface 4429 * 4430 * @param name 4431 * @param type 4432 * 4433 * @return Pointer to created interface 4434 **/ 4435 Interface* ProgramInterface::AddInterface(const GLchar* name, Interface::TYPE type) 4436 { 4437 Interface* interface = 0; 4438 4439 if (Interface::STRUCT == type) 4440 { 4441 interface = new Interface(name, type); 4442 4443 m_structures.push_back(interface); 4444 } 4445 else 4446 { 4447 interface = new Interface(name, type); 4448 4449 m_blocks.push_back(interface); 4450 } 4451 4452 return interface; 4453 } 4454 4455 /** Adds new block interface 4456 * 4457 * @param name 4458 * 4459 * @return Pointer to created interface 4460 **/ 4461 Interface* ProgramInterface::Block(const GLchar* name) 4462 { 4463 return AddInterface(name, Interface::BLOCK); 4464 } 4465 4466 /** Get interface of given shader stage 4467 * 4468 * @param stage Shader stage 4469 * 4470 * @return Reference to stage interface 4471 **/ 4472 ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage) 4473 { 4474 ShaderInterface* interface = 0; 4475 4476 switch (stage) 4477 { 4478 case Shader::COMPUTE: 4479 interface = &m_compute; 4480 break; 4481 case Shader::FRAGMENT: 4482 interface = &m_fragment; 4483 break; 4484 case Shader::GEOMETRY: 4485 interface = &m_geometry; 4486 break; 4487 case Shader::TESS_CTRL: 4488 interface = &m_tess_ctrl; 4489 break; 4490 case Shader::TESS_EVAL: 4491 interface = &m_tess_eval; 4492 break; 4493 case Shader::VERTEX: 4494 interface = &m_vertex; 4495 break; 4496 default: 4497 TCU_FAIL("Invalid enum"); 4498 } 4499 4500 return *interface; 4501 } 4502 4503 /** Get interface of given shader stage 4504 * 4505 * @param stage Shader stage 4506 * 4507 * @return Reference to stage interface 4508 **/ 4509 const ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage) const 4510 { 4511 const ShaderInterface* interface = 0; 4512 4513 switch (stage) 4514 { 4515 case Shader::COMPUTE: 4516 interface = &m_compute; 4517 break; 4518 case Shader::FRAGMENT: 4519 interface = &m_fragment; 4520 break; 4521 case Shader::GEOMETRY: 4522 interface = &m_geometry; 4523 break; 4524 case Shader::TESS_CTRL: 4525 interface = &m_tess_ctrl; 4526 break; 4527 case Shader::TESS_EVAL: 4528 interface = &m_tess_eval; 4529 break; 4530 case Shader::VERTEX: 4531 interface = &m_vertex; 4532 break; 4533 default: 4534 TCU_FAIL("Invalid enum"); 4535 } 4536 4537 return *interface; 4538 } 4539 4540 /** Clone interface of Vertex shader stage to other stages 4541 * It creates matching inputs, outputs, uniforms and buffers in other stages. 4542 * There are no additional outputs for FRAGMENT shader generated. 4543 * 4544 * @param varying_passthrough Collection of varyings connections 4545 **/ 4546 void ProgramInterface::CloneVertexInterface(VaryingPassthrough& varying_passthrough) 4547 { 4548 /* VS outputs >> TCS inputs >> TCS outputs >> .. >> FS inputs */ 4549 for (size_t i = 0; i < m_vertex.m_outputs.size(); ++i) 4550 { 4551 const Variable& vs_var = *m_vertex.m_outputs[i]; 4552 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage); 4553 4554 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough); 4555 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough); 4556 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough); 4557 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough); 4558 } 4559 4560 /* Copy uniforms from VS to other stages */ 4561 for (size_t i = 0; i < m_vertex.m_uniforms.size(); ++i) 4562 { 4563 Variable& vs_var = *m_vertex.m_uniforms[i]; 4564 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage); 4565 4566 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough); 4567 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough); 4568 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough); 4569 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough); 4570 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough); 4571 4572 /* Uniform blocks needs unique binding */ 4573 if (true == vs_var.IsBlock()) 4574 { 4575 replaceBinding(vs_var, Shader::VERTEX); 4576 } 4577 } 4578 4579 /* Copy SSBs from VS to other stages */ 4580 for (size_t i = 0; i < m_vertex.m_ssb_blocks.size(); ++i) 4581 { 4582 Variable& vs_var = *m_vertex.m_ssb_blocks[i]; 4583 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage); 4584 4585 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough); 4586 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough); 4587 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough); 4588 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough); 4589 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough); 4590 4591 /* SSBs blocks needs unique binding */ 4592 if (true == vs_var.IsBlock()) 4593 { 4594 replaceBinding(vs_var, Shader::VERTEX); 4595 } 4596 } 4597 4598 m_compute.m_globals = m_vertex.m_globals; 4599 m_fragment.m_globals = m_vertex.m_globals; 4600 m_geometry.m_globals = m_vertex.m_globals; 4601 m_tess_ctrl.m_globals = m_vertex.m_globals; 4602 m_tess_eval.m_globals = m_vertex.m_globals; 4603 } 4604 4605 /** Clone variable for specific stage 4606 * 4607 * @param variable Variable 4608 * @param stage Requested stage 4609 * @param prefix Prefix used in variable name that is specific for original stage 4610 * @param varying_passthrough Collection of varyings connections 4611 **/ 4612 void ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage, const GLchar* prefix, 4613 VaryingPassthrough& varying_passthrough) 4614 { 4615 switch (variable.m_storage) 4616 { 4617 case Variable::VARYING_OUTPUT: 4618 { 4619 Variable* in = cloneVariableForStage(variable, stage, Variable::VARYING_INPUT, prefix); 4620 4621 if (Shader::FRAGMENT != stage) 4622 { 4623 Variable* out = cloneVariableForStage(variable, stage, Variable::VARYING_OUTPUT, prefix); 4624 varying_passthrough.Add(stage, in, out); 4625 } 4626 } 4627 break; 4628 case Variable::UNIFORM: 4629 case Variable::SSB: 4630 cloneVariableForStage(variable, stage, variable.m_storage, prefix); 4631 break; 4632 default: 4633 TCU_FAIL("Invalid enum"); 4634 break; 4635 } 4636 } 4637 4638 /** Clone variable for specific stage 4639 * 4640 * @param variable Variable 4641 * @param stage Requested stage 4642 * @param storage Storage used by variable 4643 * @param prefix Prefix used in variable name that is specific for original stage 4644 * 4645 * @return New variable 4646 **/ 4647 Variable* ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage, 4648 Variable::STORAGE storage, const GLchar* prefix) 4649 { 4650 /* Initialize with original variable */ 4651 Variable* var = new Variable(variable); 4652 if (0 == var) 4653 { 4654 TCU_FAIL("Memory allocation"); 4655 } 4656 4657 /* Set up storage */ 4658 var->m_storage = storage; 4659 4660 /* Get name */ 4661 std::string name = variable.m_descriptor.m_name; 4662 4663 /* Prefix name with stage ID, empty means default block */ 4664 if (false == name.empty()) 4665 { 4666 size_t position = 0; 4667 const GLchar* stage_prefix = GetStagePrefix(stage, storage); 4668 Utils::replaceToken(prefix, position, stage_prefix, name); 4669 } 4670 var->m_descriptor.m_name = name; 4671 4672 /* Clone block */ 4673 const bool is_block = variable.IsBlock(); 4674 if (true == is_block) 4675 { 4676 const Interface* interface = variable.m_descriptor.m_interface; 4677 4678 Interface* block = CloneBlockForStage(*interface, stage, storage, prefix); 4679 4680 var->m_descriptor.m_interface = block; 4681 } 4682 4683 /* Store variable */ 4684 ShaderInterface& si = GetShaderInterface(stage); 4685 Variable* result = 0; 4686 4687 switch (storage) 4688 { 4689 case Variable::VARYING_INPUT: 4690 si.m_inputs.push_back(var); 4691 result = si.m_inputs.back(); 4692 break; 4693 case Variable::VARYING_OUTPUT: 4694 si.m_outputs.push_back(var); 4695 result = si.m_outputs.back(); 4696 break; 4697 case Variable::UNIFORM: 4698 /* Uniform blocks needs unique binding */ 4699 if (true == is_block) 4700 { 4701 replaceBinding(*var, stage); 4702 } 4703 4704 si.m_uniforms.push_back(var); 4705 result = si.m_uniforms.back(); 4706 break; 4707 case Variable::SSB: 4708 /* SSBs needs unique binding */ 4709 if (true == is_block) 4710 { 4711 replaceBinding(*var, stage); 4712 } 4713 4714 si.m_ssb_blocks.push_back(var); 4715 result = si.m_ssb_blocks.back(); 4716 break; 4717 default: 4718 TCU_FAIL("Invalid enum"); 4719 break; 4720 } 4721 4722 return result; 4723 } 4724 4725 /** clone block to specific stage 4726 * 4727 * @param block Block to be copied 4728 * @param stage Specific stage 4729 * @param storage Storage used by block 4730 * @param prefix Prefix used in block name 4731 * 4732 * @return New interface 4733 **/ 4734 Interface* ProgramInterface::CloneBlockForStage(const Interface& block, Shader::STAGES stage, Variable::STORAGE storage, 4735 const GLchar* prefix) 4736 { 4737 /* Get name */ 4738 std::string name = block.m_name; 4739 4740 /* Prefix name with stage ID */ 4741 size_t position = 0; 4742 const GLchar* stage_prefix = GetStagePrefix(stage, storage); 4743 Utils::replaceToken(prefix, position, stage_prefix, name); 4744 4745 Interface* ptr = GetBlock(name.c_str()); 4746 4747 if (0 == ptr) 4748 { 4749 ptr = AddInterface(name.c_str(), Interface::BLOCK); 4750 } 4751 4752 ptr->m_members = block.m_members; 4753 4754 return ptr; 4755 } 4756 4757 /** Get stage specific prefix used in names 4758 * 4759 * @param stage Stage 4760 * @param storage Storage class 4761 * 4762 * @return String 4763 **/ 4764 const GLchar* ProgramInterface::GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage) 4765 { 4766 static const GLchar* lut[Shader::STAGE_MAX][Variable::STORAGE_MAX] = { 4767 /* IN OUT UNIFORM SSB MEMBER */ 4768 /* CS */ { 0, 0, "cs_uni_", "cs_buf_", "" }, 4769 /* VS */ { "in_vs_", "vs_tcs_", "vs_uni_", "vs_buf_", "" }, 4770 /* TCS */ { "vs_tcs_", "tcs_tes_", "tcs_uni_", "tcs_buf_", "" }, 4771 /* TES */ { "tcs_tes_", "tes_gs_", "tes_uni_", "tes_buf_", "" }, 4772 /* GS */ { "tes_gs_", "gs_fs_", "gs_uni_", "gs_buf_", "" }, 4773 /* FS */ { "gs_fs_", "fs_out_", "fs_uni_", "fs_buf_", "" }, 4774 }; 4775 4776 const GLchar* result = 0; 4777 4778 result = lut[stage][storage]; 4779 4780 return result; 4781 } 4782 4783 /** Get definitions of all structures used in program interface 4784 * 4785 * @return String with code 4786 **/ 4787 std::string ProgramInterface::GetDefinitionsStructures() const 4788 { 4789 return GetDefinitions(m_structures); 4790 } 4791 4792 /** Get interface code for stage 4793 * 4794 * @param stage Specific stage 4795 * 4796 * @return String with code 4797 **/ 4798 std::string ProgramInterface::GetInterfaceForStage(Shader::STAGES stage) const 4799 { 4800 size_t position = 0; 4801 std::string interface = "/* Globals */\n" 4802 "GLOBALS\n" 4803 "\n" 4804 "/* Structures */\n" 4805 "STRUCTURES\n" 4806 "\n" 4807 "/* Uniforms */\n" 4808 "UNIFORMS\n" 4809 "\n" 4810 "/* Inputs */\n" 4811 "INPUTS\n" 4812 "\n" 4813 "/* Outputs */\n" 4814 "OUTPUTS\n" 4815 "\n" 4816 "/* Storage */\n" 4817 "STORAGE\n"; 4818 4819 const ShaderInterface& si = GetShaderInterface(stage); 4820 4821 const std::string& structures = GetDefinitionsStructures(); 4822 4823 const std::string& globals = si.GetDefinitionsGlobals(); 4824 const std::string& inputs = si.GetDefinitionsInputs(); 4825 const std::string& outputs = si.GetDefinitionsOutputs(); 4826 const std::string& uniforms = si.GetDefinitionsUniforms(); 4827 const std::string& ssbs = si.GetDefinitionsSSBs(); 4828 4829 replaceToken("GLOBALS", position, globals.c_str(), interface); 4830 replaceToken("STRUCTURES", position, structures.c_str(), interface); 4831 replaceToken("UNIFORMS", position, uniforms.c_str(), interface); 4832 replaceToken("INPUTS", position, inputs.c_str(), interface); 4833 replaceToken("OUTPUTS", position, outputs.c_str(), interface); 4834 replaceToken("STORAGE", position, ssbs.c_str(), interface); 4835 4836 return interface; 4837 } 4838 4839 /** Functional object used in find_if algorithm, in search for interface of given name 4840 * 4841 **/ 4842 struct matchInterfaceName 4843 { 4844 matchInterfaceName(const GLchar* name) : m_name(name) 4845 { 4846 } 4847 4848 bool operator()(const Interface* interface) 4849 { 4850 return 0 == interface->m_name.compare(m_name); 4851 } 4852 4853 const GLchar* m_name; 4854 }; 4855 4856 /** Finds interface of given name in given vector of interfaces 4857 * 4858 * @param vector Collection of interfaces 4859 * @param name Requested name 4860 * 4861 * @return Pointer to interface if available, 0 otherwise 4862 **/ 4863 static Interface* findInterfaceByName(Interface::PtrVector& vector, const GLchar* name) 4864 { 4865 Interface::PtrVector::iterator it = std::find_if(vector.begin(), vector.end(), matchInterfaceName(name)); 4866 4867 if (vector.end() != it) 4868 { 4869 return *it; 4870 } 4871 else 4872 { 4873 return 0; 4874 } 4875 } 4876 4877 /** Search for block of given name 4878 * 4879 * @param name Name of block 4880 * 4881 * @return Pointer to block or 0 4882 **/ 4883 Interface* ProgramInterface::GetBlock(const GLchar* name) 4884 { 4885 return findInterfaceByName(m_blocks, name); 4886 } 4887 4888 /** Search for structure of given name 4889 * 4890 * @param name Name of structure 4891 * 4892 * @return Pointer to structure or 0 4893 **/ 4894 Interface* ProgramInterface::GetStructure(const GLchar* name) 4895 { 4896 return findInterfaceByName(m_structures, name); 4897 } 4898 4899 /** Adds new sturcture to interface 4900 * 4901 * @param name Name of structure 4902 * 4903 * @return Created structure 4904 **/ 4905 Interface* ProgramInterface::Structure(const GLchar* name) 4906 { 4907 return AddInterface(name, Interface::STRUCT); 4908 } 4909 4910 /** Replace "BINDING" token in qualifiers string to value specific for given stage 4911 * 4912 * @param variable Variable to modify 4913 * @param stage Requested stage 4914 **/ 4915 void ProgramInterface::replaceBinding(Variable& variable, Shader::STAGES stage) 4916 { 4917 GLchar binding[16]; 4918 sprintf(binding, "%d", stage); 4919 replaceAllTokens("BINDING", binding, variable.m_descriptor.m_qualifiers); 4920 } 4921 } /* Utils namespace */ 4922 4923 /** Debuging procedure. Logs parameters. 4924 * 4925 * @param source As specified in GL spec. 4926 * @param type As specified in GL spec. 4927 * @param id As specified in GL spec. 4928 * @param severity As specified in GL spec. 4929 * @param ignored 4930 * @param message As specified in GL spec. 4931 * @param info Pointer to instance of Context used by test. 4932 */ 4933 void GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */, 4934 const GLchar* message, void* info) 4935 { 4936 deqp::Context* ctx = (deqp::Context*)info; 4937 4938 const GLchar* source_str = "Unknown"; 4939 const GLchar* type_str = "Unknown"; 4940 const GLchar* severity_str = "Unknown"; 4941 4942 switch (source) 4943 { 4944 case GL_DEBUG_SOURCE_API: 4945 source_str = "API"; 4946 break; 4947 case GL_DEBUG_SOURCE_APPLICATION: 4948 source_str = "APP"; 4949 break; 4950 case GL_DEBUG_SOURCE_OTHER: 4951 source_str = "OTR"; 4952 break; 4953 case GL_DEBUG_SOURCE_SHADER_COMPILER: 4954 source_str = "COM"; 4955 break; 4956 case GL_DEBUG_SOURCE_THIRD_PARTY: 4957 source_str = "3RD"; 4958 break; 4959 case GL_DEBUG_SOURCE_WINDOW_SYSTEM: 4960 source_str = "WS"; 4961 break; 4962 default: 4963 break; 4964 } 4965 4966 switch (type) 4967 { 4968 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: 4969 type_str = "DEPRECATED_BEHAVIOR"; 4970 break; 4971 case GL_DEBUG_TYPE_ERROR: 4972 type_str = "ERROR"; 4973 break; 4974 case GL_DEBUG_TYPE_MARKER: 4975 type_str = "MARKER"; 4976 break; 4977 case GL_DEBUG_TYPE_OTHER: 4978 type_str = "OTHER"; 4979 break; 4980 case GL_DEBUG_TYPE_PERFORMANCE: 4981 type_str = "PERFORMANCE"; 4982 break; 4983 case GL_DEBUG_TYPE_POP_GROUP: 4984 type_str = "POP_GROUP"; 4985 break; 4986 case GL_DEBUG_TYPE_PORTABILITY: 4987 type_str = "PORTABILITY"; 4988 break; 4989 case GL_DEBUG_TYPE_PUSH_GROUP: 4990 type_str = "PUSH_GROUP"; 4991 break; 4992 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: 4993 type_str = "UNDEFINED_BEHAVIOR"; 4994 break; 4995 default: 4996 break; 4997 } 4998 4999 switch (severity) 5000 { 5001 case GL_DEBUG_SEVERITY_HIGH: 5002 severity_str = "H"; 5003 break; 5004 case GL_DEBUG_SEVERITY_LOW: 5005 severity_str = "L"; 5006 break; 5007 case GL_DEBUG_SEVERITY_MEDIUM: 5008 severity_str = "M"; 5009 break; 5010 case GL_DEBUG_SEVERITY_NOTIFICATION: 5011 severity_str = "N"; 5012 break; 5013 default: 5014 break; 5015 } 5016 5017 ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|" 5018 << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id 5019 << ": " << message << tcu::TestLog::EndMessage; 5020 } 5021 5022 /** Constructor 5023 * 5024 * @param context Test context 5025 * @param test_name Test name 5026 * @param test_description Test description 5027 **/ 5028 TestBase::TestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description) 5029 : TestCase(context, test_name, test_description) 5030 { 5031 /* Nothing to be done here */ 5032 } 5033 5034 /** Execute test 5035 * 5036 * @return tcu::TestNode::STOP otherwise 5037 **/ 5038 tcu::TestNode::IterateResult TestBase::iterate() 5039 { 5040 bool test_result; 5041 5042 #if DEBUG_ENBALE_MESSAGE_CALLBACK 5043 const Functions& gl = m_context.getRenderContext().getFunctions(); 5044 5045 gl.debugMessageCallback(debug_proc, &m_context); 5046 GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 5047 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 5048 5049 try 5050 { 5051 /* Execute test */ 5052 test_result = test(); 5053 } 5054 catch (std::exception& exc) 5055 { 5056 TCU_FAIL(exc.what()); 5057 } 5058 5059 /* Set result */ 5060 if (true == test_result) 5061 { 5062 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 5063 } 5064 else 5065 { 5066 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 5067 } 5068 5069 /* Done */ 5070 return tcu::TestNode::STOP; 5071 } 5072 5073 /** Get last input location available for given type at specific stage 5074 * 5075 * @param stage Shader stage 5076 * @param type Input type 5077 * @param array_length Length of input array 5078 * 5079 * @return Last location index 5080 **/ 5081 GLint TestBase::getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length, bool ignore_prev_stage) 5082 { 5083 GLint divide = 4; /* 4 components per location */ 5084 GLint param = 0; 5085 GLenum pname = 0; 5086 GLint paramPrev = 0; 5087 GLenum pnamePrev = 0; 5088 5089 /* Select pnmae */ 5090 switch (stage) 5091 { 5092 case Utils::Shader::FRAGMENT: 5093 pname = GL_MAX_FRAGMENT_INPUT_COMPONENTS; 5094 pnamePrev = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS; 5095 break; 5096 case Utils::Shader::GEOMETRY: 5097 pname = GL_MAX_GEOMETRY_INPUT_COMPONENTS; 5098 pnamePrev = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS; 5099 break; 5100 case Utils::Shader::TESS_CTRL: 5101 pname = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS; 5102 pnamePrev = GL_MAX_VERTEX_OUTPUT_COMPONENTS; 5103 break; 5104 case Utils::Shader::TESS_EVAL: 5105 pname = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS; 5106 pnamePrev = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS; 5107 break; 5108 case Utils::Shader::VERTEX: 5109 pname = GL_MAX_VERTEX_ATTRIBS; 5110 divide = 1; 5111 break; 5112 default: 5113 TCU_FAIL("Invalid enum"); 5114 break; 5115 } 5116 5117 /* Zero means no array, but 1 slot is required */ 5118 if (0 == array_length) 5119 { 5120 array_length += 1; 5121 } 5122 5123 /* Get MAX */ 5124 const Functions& gl = m_context.getRenderContext().getFunctions(); 5125 5126 gl.getIntegerv(pname, ¶m); 5127 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 5128 5129 if (pnamePrev && !ignore_prev_stage) { 5130 gl.getIntegerv(pnamePrev, ¶mPrev); 5131 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 5132 5133 /* Don't read from a location that doesn't exist in the previous stage */ 5134 param = de::min(param, paramPrev); 5135 } 5136 5137 /* Calculate */ 5138 #if WRKARD_VARYINGLOCATIONSTEST 5139 5140 const GLint n_avl_locations = 16; 5141 5142 #else 5143 5144 const GLint n_avl_locations = param / divide; 5145 5146 #endif 5147 5148 const GLuint n_req_location = type.GetLocations(stage == Utils::Shader::VERTEX) * array_length; 5149 5150 return n_avl_locations - n_req_location; /* last is max - 1 */ 5151 } 5152 5153 /** Get last output location available for given type at specific stage 5154 * 5155 * @param stage Shader stage 5156 * @param type Input type 5157 * @param array_length Length of input array 5158 * 5159 * @return Last location index 5160 **/ 5161 GLint TestBase::getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length, bool ignore_next_stage) 5162 { 5163 GLint param = 0; 5164 GLenum pname = 0; 5165 GLint paramNext = 0; 5166 GLenum pnameNext = 0; 5167 5168 /* Select pname */ 5169 switch (stage) 5170 { 5171 case Utils::Shader::GEOMETRY: 5172 pname = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS; 5173 pnameNext = GL_MAX_FRAGMENT_INPUT_COMPONENTS; 5174 break; 5175 case Utils::Shader::TESS_CTRL: 5176 pname = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS; 5177 pnameNext = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS; 5178 break; 5179 case Utils::Shader::TESS_EVAL: 5180 pname = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS; 5181 pnameNext = GL_MAX_GEOMETRY_INPUT_COMPONENTS; 5182 break; 5183 case Utils::Shader::VERTEX: 5184 pname = GL_MAX_VERTEX_OUTPUT_COMPONENTS; 5185 pnameNext = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS; 5186 break; 5187 default: 5188 TCU_FAIL("Invalid enum"); 5189 break; 5190 } 5191 5192 /* Zero means no array, but 1 slot is required */ 5193 if (0 == array_length) 5194 { 5195 array_length += 1; 5196 } 5197 5198 /* Get MAX */ 5199 const Functions& gl = m_context.getRenderContext().getFunctions(); 5200 5201 gl.getIntegerv(pname, ¶m); 5202 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 5203 5204 /* Calculate */ 5205 #if WRKARD_VARYINGLOCATIONSTEST 5206 5207 const GLint n_avl_locations = 16; 5208 5209 #else 5210 5211 /* Don't write to a location that doesn't exist in the next stage */ 5212 if (!ignore_next_stage) 5213 { 5214 gl.getIntegerv(pnameNext, ¶mNext); 5215 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 5216 5217 param = de::min(param, paramNext); 5218 } 5219 5220 const GLint n_avl_locations = param / 4; /* 4 components per location */ 5221 5222 #endif 5223 5224 const GLuint n_req_location = type.GetLocations() * array_length; 5225 5226 return n_avl_locations - n_req_location; /* last is max - 1 */ 5227 } 5228 5229 /** Basic implementation 5230 * 5231 * @param ignored 5232 * 5233 * @return Empty string 5234 **/ 5235 std::string TestBase::getTestCaseName(GLuint /* test_case_index */) 5236 { 5237 std::string result; 5238 5239 return result; 5240 } 5241 5242 /** Basic implementation 5243 * 5244 * @return 1 5245 **/ 5246 GLuint TestBase::getTestCaseNumber() 5247 { 5248 return 1; 5249 } 5250 5251 /** Check if flat qualifier is required for given type, stage and storage 5252 * 5253 * @param stage Shader stage 5254 * @param type Input type 5255 * @param storage Storage of variable 5256 * 5257 * @return Last location index 5258 **/ 5259 bool TestBase::isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type& type, 5260 Utils::Variable::STORAGE storage) const 5261 { 5262 /* Float types do not need flat at all */ 5263 if (Utils::Type::Float == type.m_basic_type) 5264 { 5265 return false; 5266 } 5267 5268 /* Inputs to fragment shader */ 5269 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_INPUT == storage)) 5270 { 5271 return true; 5272 } 5273 5274 /* Outputs from geometry shader */ 5275 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_OUTPUT == storage)) 5276 { 5277 return true; 5278 } 5279 5280 return false; 5281 } 5282 5283 /** Basic implementation of testInit method 5284 * 5285 **/ 5286 void TestBase::testInit() 5287 { 5288 } 5289 5290 /** Calculate stride for interface 5291 * 5292 * @param interface Interface 5293 * 5294 * @return Calculated value 5295 **/ 5296 GLuint TestBase::calculateStride(const Utils::Interface& interface) const 5297 { 5298 const size_t n_members = interface.m_members.size(); 5299 5300 GLuint stride = 0; 5301 5302 for (size_t i = 0; i < n_members; ++i) 5303 { 5304 const Utils::Variable::Descriptor& member = interface.m_members[i]; 5305 const GLuint member_offset = member.m_offset; 5306 const GLuint member_stride = member.m_expected_stride_of_element; 5307 const GLuint member_ends_at = member_offset + member_stride; 5308 5309 stride = std::max(stride, member_ends_at); 5310 } 5311 5312 return stride; 5313 } 5314 5315 /** Generate data for interface. This routine is recursive 5316 * 5317 * @param interface Interface 5318 * @param offset Offset in out_data 5319 * @param out_data Buffer to be filled 5320 **/ 5321 void TestBase::generateData(const Utils::Interface& interface, GLuint offset, std::vector<GLubyte>& out_data) const 5322 { 5323 const size_t n_members = interface.m_members.size(); 5324 GLubyte* ptr = &out_data[offset]; 5325 5326 for (size_t i = 0; i < n_members; ++i) 5327 { 5328 const Utils::Variable::Descriptor& member = interface.m_members[i]; 5329 const GLuint member_offset = member.m_offset; 5330 const GLuint n_elements = (0 == member.m_n_array_elements) ? 1 : member.m_n_array_elements; 5331 5332 for (GLuint element = 0; element < n_elements; ++element) 5333 { 5334 const GLuint element_offset = element * member.m_expected_stride_of_element; 5335 const GLuint data_offfset = member_offset + element_offset; 5336 5337 if (Utils::Variable::BUILTIN == member.m_type) 5338 { 5339 const std::vector<GLubyte>& data = member.m_builtin.GenerateData(); 5340 5341 memcpy(ptr + data_offfset, &data[0], data.size()); 5342 } 5343 else 5344 { 5345 generateData(*member.m_interface, offset + data_offfset, out_data); 5346 } 5347 } 5348 } 5349 } 5350 5351 /** Get type at index 5352 * 5353 * @param index Index of requested type 5354 * 5355 * @return Type 5356 **/ 5357 Utils::Type TestBase::getType(GLuint index) const 5358 { 5359 Utils::Type type; 5360 5361 switch (index) 5362 { 5363 case 0: 5364 type = Utils::Type::_double; 5365 break; 5366 case 1: 5367 type = Utils::Type::dmat2; 5368 break; 5369 case 2: 5370 type = Utils::Type::dmat2x3; 5371 break; 5372 case 3: 5373 type = Utils::Type::dmat2x4; 5374 break; 5375 case 4: 5376 type = Utils::Type::dmat3; 5377 break; 5378 case 5: 5379 type = Utils::Type::dmat3x2; 5380 break; 5381 case 6: 5382 type = Utils::Type::dmat3x4; 5383 break; 5384 case 7: 5385 type = Utils::Type::dmat4; 5386 break; 5387 case 8: 5388 type = Utils::Type::dmat4x2; 5389 break; 5390 case 9: 5391 type = Utils::Type::dmat4x3; 5392 break; 5393 case 10: 5394 type = Utils::Type::dvec2; 5395 break; 5396 case 11: 5397 type = Utils::Type::dvec3; 5398 break; 5399 case 12: 5400 type = Utils::Type::dvec4; 5401 break; 5402 case 13: 5403 type = Utils::Type::_float; 5404 break; 5405 case 14: 5406 type = Utils::Type::mat2; 5407 break; 5408 case 15: 5409 type = Utils::Type::mat2x3; 5410 break; 5411 case 16: 5412 type = Utils::Type::mat2x4; 5413 break; 5414 case 17: 5415 type = Utils::Type::mat3; 5416 break; 5417 case 18: 5418 type = Utils::Type::mat3x2; 5419 break; 5420 case 19: 5421 type = Utils::Type::mat3x4; 5422 break; 5423 case 20: 5424 type = Utils::Type::mat4; 5425 break; 5426 case 21: 5427 type = Utils::Type::mat4x2; 5428 break; 5429 case 22: 5430 type = Utils::Type::mat4x3; 5431 break; 5432 case 23: 5433 type = Utils::Type::vec2; 5434 break; 5435 case 24: 5436 type = Utils::Type::vec3; 5437 break; 5438 case 25: 5439 type = Utils::Type::vec4; 5440 break; 5441 case 26: 5442 type = Utils::Type::_int; 5443 break; 5444 case 27: 5445 type = Utils::Type::ivec2; 5446 break; 5447 case 28: 5448 type = Utils::Type::ivec3; 5449 break; 5450 case 29: 5451 type = Utils::Type::ivec4; 5452 break; 5453 case 30: 5454 type = Utils::Type::uint; 5455 break; 5456 case 31: 5457 type = Utils::Type::uvec2; 5458 break; 5459 case 32: 5460 type = Utils::Type::uvec3; 5461 break; 5462 case 33: 5463 type = Utils::Type::uvec4; 5464 break; 5465 default: 5466 TCU_FAIL("invalid enum"); 5467 } 5468 5469 return type; 5470 } 5471 5472 /** Get name of type at index 5473 * 5474 * @param index Index of type 5475 * 5476 * @return Name 5477 **/ 5478 std::string TestBase::getTypeName(GLuint index) const 5479 { 5480 std::string name = getType(index).GetGLSLTypeName(); 5481 5482 return name; 5483 } 5484 5485 /** Get number of types 5486 * 5487 * @return 34 5488 **/ 5489 glw::GLuint TestBase::getTypesNumber() const 5490 { 5491 return 34; 5492 } 5493 5494 /** Execute test 5495 * 5496 * @return true if test pass, false otherwise 5497 **/ 5498 bool TestBase::test() 5499 { 5500 bool result = true; 5501 GLuint n_test_cases = 0; 5502 5503 /* Prepare test */ 5504 testInit(); 5505 5506 /* GL entry points */ 5507 const Functions& gl = m_context.getRenderContext().getFunctions(); 5508 5509 /* Tessellation patch set up */ 5510 gl.patchParameteri(GL_PATCH_VERTICES, 1); 5511 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri"); 5512 5513 /* Get number of test cases */ 5514 n_test_cases = getTestCaseNumber(); 5515 5516 #if DEBUG_REPEAT_TEST_CASE 5517 5518 while (1) 5519 { 5520 GLuint test_case = DEBUG_REPEATED_TEST_CASE; 5521 5522 #else /* DEBUG_REPEAT_TEST_CASE */ 5523 5524 for (GLuint test_case = 0; test_case < n_test_cases; ++test_case) 5525 { 5526 #endif /* DEBUG_REPEAT_TEST_CASE */ 5527 5528 bool case_result = true; 5529 5530 /* Execute case */ 5531 if (false == testCase(test_case)) 5532 { 5533 case_result = false; 5534 } 5535 5536 /* Log failure */ 5537 if (false == case_result) 5538 { 5539 const std::string& test_case_name = getTestCaseName(test_case); 5540 5541 if (false == test_case_name.empty()) 5542 { 5543 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case_name 5544 << ") failed." << tcu::TestLog::EndMessage; 5545 } 5546 else 5547 { 5548 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case 5549 << ") failed." << tcu::TestLog::EndMessage; 5550 } 5551 5552 result = false; 5553 } 5554 } 5555 5556 /* Done */ 5557 return result; 5558 } 5559 5560 /* Constants used by BufferTestBase */ 5561 const GLuint BufferTestBase::bufferDescriptor::m_non_indexed = -1; 5562 5563 /** Constructor 5564 * 5565 * @param context Test context 5566 * @param test_name Name of test 5567 * @param test_description Description of test 5568 **/ 5569 BufferTestBase::BufferTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description) 5570 : TestBase(context, test_name, test_description) 5571 { 5572 } 5573 5574 /** Execute drawArrays for single vertex 5575 * 5576 * @param ignored 5577 * 5578 * @return true 5579 **/ 5580 bool BufferTestBase::executeDrawCall(bool tesEnabled, GLuint /* test_case_index */) 5581 { 5582 const Functions& gl = m_context.getRenderContext().getFunctions(); 5583 5584 gl.disable(GL_RASTERIZER_DISCARD); 5585 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 5586 5587 gl.beginTransformFeedback(GL_POINTS); 5588 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 5589 5590 // Only TES is existed, glDrawArray can use the parameter GL_PATCHES 5591 if (tesEnabled == false) 5592 { 5593 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 5594 } 5595 else 5596 { 5597 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 5598 } 5599 5600 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 5601 5602 gl.endTransformFeedback(); 5603 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 5604 5605 return true; 5606 } 5607 5608 /** Get descriptors of buffers necessary for test 5609 * 5610 * @param ignored 5611 * @param ignored 5612 **/ 5613 void BufferTestBase::getBufferDescriptors(glw::GLuint /* test_case_index */, 5614 bufferDescriptor::Vector& /* out_descriptors */) 5615 { 5616 /* Nothhing to be done */ 5617 } 5618 5619 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings 5620 * 5621 * @param ignored 5622 * @param ignored 5623 **/ 5624 void BufferTestBase::getCapturedVaryings(glw::GLuint /* test_case_index */, 5625 Utils::Program::NameVector& /* captured_varyings */, 5626 GLint* /* xfb_components */) 5627 { 5628 /* Nothing to be done */ 5629 } 5630 5631 /** Get body of main function for given shader stage 5632 * 5633 * @param ignored 5634 * @param ignored 5635 * @param out_assignments Set to empty 5636 * @param out_calculations Set to empty 5637 **/ 5638 void BufferTestBase::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */, 5639 std::string& out_assignments, std::string& out_calculations) 5640 { 5641 out_assignments = ""; 5642 out_calculations = ""; 5643 } 5644 5645 /** Get interface of shader 5646 * 5647 * @param ignored 5648 * @param ignored 5649 * @param out_interface Set to "" 5650 **/ 5651 void BufferTestBase::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */, 5652 std::string& out_interface) 5653 { 5654 out_interface = ""; 5655 } 5656 5657 /** Get source code of shader 5658 * 5659 * @param test_case_index Index of test case 5660 * @param stage Shader stage 5661 * 5662 * @return Source 5663 **/ 5664 std::string BufferTestBase::getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage) 5665 { 5666 std::string assignments; 5667 std::string calculations; 5668 std::string interface; 5669 5670 /* */ 5671 getShaderBody(test_case_index, stage, assignments, calculations); 5672 getShaderInterface(test_case_index, stage, interface); 5673 5674 /* */ 5675 std::string source = getShaderTemplate(stage); 5676 5677 /* */ 5678 size_t position = 0; 5679 Utils::replaceToken("INTERFACE", position, interface.c_str(), source); 5680 Utils::replaceToken("CALCULATIONS", position, calculations.c_str(), source); 5681 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source); 5682 5683 /* */ 5684 return source; 5685 } 5686 5687 /** Inspects program to check if all resources are as expected 5688 * 5689 * @param ignored 5690 * @param ignored 5691 * @param ignored 5692 * 5693 * @return true 5694 **/ 5695 bool BufferTestBase::inspectProgram(GLuint /* test_case_index */, Utils::Program& /* program */, 5696 std::stringstream& /* out_stream */) 5697 { 5698 return true; 5699 } 5700 5701 /** Runs test case 5702 * 5703 * @param test_case_index Id of test case 5704 * 5705 * @return true if test case pass, false otherwise 5706 **/ 5707 bool BufferTestBase::testCase(GLuint test_case_index) 5708 { 5709 try 5710 { 5711 bufferCollection buffers; 5712 Utils::Program::NameVector captured_varyings; 5713 bufferDescriptor::Vector descriptors; 5714 Utils::Program program(m_context); 5715 Utils::VertexArray vao(m_context); 5716 5717 /* Get captured varyings */ 5718 GLint xfb_components; 5719 getCapturedVaryings(test_case_index, captured_varyings, &xfb_components); 5720 5721 /* Don't generate shaders that try to capture more XFB components than the implementation's limit */ 5722 if (captured_varyings.size() > 0) 5723 { 5724 const Functions& gl = m_context.getRenderContext().getFunctions(); 5725 5726 GLint max_xfb_components; 5727 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_components); 5728 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 5729 5730 if (xfb_components > max_xfb_components) 5731 return true; 5732 } 5733 5734 /* Get shader sources */ 5735 const std::string& fragment_shader = getShaderSource(test_case_index, Utils::Shader::FRAGMENT); 5736 const std::string& geometry_shader = getShaderSource(test_case_index, Utils::Shader::GEOMETRY); 5737 const std::string& tess_ctrl_shader = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL); 5738 const std::string& tess_eval_shader = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL); 5739 const std::string& vertex_shader = getShaderSource(test_case_index, Utils::Shader::VERTEX); 5740 5741 /* Set up program */ 5742 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader, 5743 vertex_shader, captured_varyings, true, false /* is_separable */); 5744 5745 /* Inspection */ 5746 { 5747 std::stringstream stream; 5748 if (false == inspectProgram(test_case_index, program, stream)) 5749 { 5750 m_context.getTestContext().getLog() 5751 << tcu::TestLog::Message 5752 << "Program inspection failed. Test case: " << getTestCaseName(test_case_index) 5753 << ". Reason: " << stream.str() << tcu::TestLog::EndMessage 5754 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader) 5755 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader) 5756 << tcu::TestLog::KernelSource(fragment_shader); 5757 5758 return false; 5759 } 5760 } 5761 5762 program.Use(); 5763 5764 /* Set up buffers */ 5765 getBufferDescriptors(test_case_index, descriptors); 5766 cleanBuffers(); 5767 prepareBuffers(descriptors, buffers); 5768 5769 /* Set up vao */ 5770 vao.Init(); 5771 vao.Bind(); 5772 5773 /* Draw */ 5774 bool result = executeDrawCall((program.m_tess_eval.m_id != 0), test_case_index); 5775 5776 #if USE_NSIGHT 5777 m_context.getRenderContext().postIterate(); 5778 #endif 5779 5780 if (false == result) 5781 { 5782 m_context.getTestContext().getLog() 5783 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader) 5784 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader) 5785 << tcu::TestLog::KernelSource(fragment_shader); 5786 5787 return false; 5788 } 5789 5790 /* Verify result */ 5791 if (false == verifyBuffers(buffers)) 5792 { 5793 m_context.getTestContext().getLog() 5794 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader) 5795 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader) 5796 << tcu::TestLog::KernelSource(fragment_shader); 5797 5798 return false; 5799 } 5800 } 5801 catch (Utils::Shader::InvalidSourceException& exc) 5802 { 5803 exc.log(m_context); 5804 TCU_FAIL(exc.what()); 5805 } 5806 catch (Utils::Program::BuildException& exc) 5807 { 5808 exc.log(m_context); 5809 TCU_FAIL(exc.what()); 5810 } 5811 5812 /* Done */ 5813 return true; 5814 } 5815 5816 /** Verify contents of buffers 5817 * 5818 * @param buffers Collection of buffers to be verified 5819 * 5820 * @return true if everything is as expected, false otherwise 5821 **/ 5822 bool BufferTestBase::verifyBuffers(bufferCollection& buffers) 5823 { 5824 bool result = true; 5825 5826 for (bufferCollection::Vector::iterator it = buffers.m_vector.begin(), end = buffers.m_vector.end(); end != it; 5827 ++it) 5828 { 5829 bufferCollection::pair& pair = *it; 5830 Utils::Buffer* buffer = pair.m_buffer; 5831 bufferDescriptor* descriptor = pair.m_descriptor; 5832 size_t size = descriptor->m_expected_data.size(); 5833 5834 /* Skip buffers that have no expected data */ 5835 if (0 == size) 5836 { 5837 continue; 5838 } 5839 5840 /* Get pointer to contents of buffer */ 5841 buffer->Bind(); 5842 GLvoid* buffer_data = buffer->Map(Utils::Buffer::ReadOnly); 5843 5844 /* Get pointer to expected data */ 5845 GLvoid* expected_data = &descriptor->m_expected_data[0]; 5846 5847 /* Compare */ 5848 int res = memcmp(buffer_data, expected_data, size); 5849 5850 if (0 != res) 5851 { 5852 m_context.getTestContext().getLog() 5853 << tcu::TestLog::Message 5854 << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target) 5855 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage; 5856 5857 result = false; 5858 } 5859 5860 /* Release buffer mapping */ 5861 buffer->UnMap(); 5862 } 5863 5864 return result; 5865 } 5866 5867 /** Unbinds all uniforms and xfb 5868 * 5869 **/ 5870 void BufferTestBase::cleanBuffers() 5871 { 5872 const Functions& gl = m_context.getRenderContext().getFunctions(); 5873 5874 GLint max_uni = 0; 5875 GLint max_xfb = 0; 5876 5877 gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uni); 5878 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb); 5879 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 5880 5881 for (GLint i = 0; i < max_uni; ++i) 5882 { 5883 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Uniform, i); 5884 } 5885 5886 for (GLint i = 0; i < max_xfb; ++i) 5887 { 5888 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Transform_feedback, i); 5889 } 5890 } 5891 5892 /** Get template of shader for given stage 5893 * 5894 * @param stage Stage 5895 * 5896 * @return Template of shader source 5897 **/ 5898 std::string BufferTestBase::getShaderTemplate(Utils::Shader::STAGES stage) 5899 { 5900 static const GLchar* compute_shader_template = "#version 430 core\n" 5901 "#extension GL_ARB_enhanced_layouts : require\n" 5902 "\n" 5903 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 5904 "\n" 5905 "writeonly uniform uimage2D uni_image;\n" 5906 "\n" 5907 "INTERFACE" 5908 "\n" 5909 "void main()\n" 5910 "{\n" 5911 "CALCULATIONS" 5912 "\n" 5913 "ASSIGNMENTS" 5914 "}\n" 5915 "\n"; 5916 5917 static const GLchar* fragment_shader_template = "#version 430 core\n" 5918 "#extension GL_ARB_enhanced_layouts : require\n" 5919 "\n" 5920 "INTERFACE" 5921 "\n" 5922 "void main()\n" 5923 "{\n" 5924 "CALCULATIONS" 5925 "\n" 5926 "ASSIGNMENTS" 5927 "}\n" 5928 "\n"; 5929 5930 // max_vertices is set to 3 for the test case "xfb_vertex_streams" declares 3 streams in geometry shader, 5931 // according to spec, max_vertices should be no less than 3 if there are 3 streams in GS. 5932 static const GLchar* geometry_shader_template = "#version 430 core\n" 5933 "#extension GL_ARB_enhanced_layouts : require\n" 5934 "\n" 5935 "layout(points) in;\n" 5936 "layout(points, max_vertices = 3) out;\n" 5937 "\n" 5938 "INTERFACE" 5939 "\n" 5940 "void main()\n" 5941 "{\n" 5942 "CALCULATIONS" 5943 "\n" 5944 "\n" 5945 "ASSIGNMENTS" 5946 " gl_Position = vec4(0, 0, 0, 1);\n" 5947 " EmitVertex();\n" 5948 "}\n" 5949 "\n"; 5950 5951 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n" 5952 "#extension GL_ARB_enhanced_layouts : require\n" 5953 "\n" 5954 "layout(vertices = 1) out;\n" 5955 "\n" 5956 "INTERFACE" 5957 "\n" 5958 "void main()\n" 5959 "{\n" 5960 "CALCULATIONS" 5961 "\n" 5962 "ASSIGNMENTS" 5963 "\n" 5964 " gl_TessLevelOuter[0] = 1.0;\n" 5965 " gl_TessLevelOuter[1] = 1.0;\n" 5966 " gl_TessLevelOuter[2] = 1.0;\n" 5967 " gl_TessLevelOuter[3] = 1.0;\n" 5968 " gl_TessLevelInner[0] = 1.0;\n" 5969 " gl_TessLevelInner[1] = 1.0;\n" 5970 "}\n" 5971 "\n"; 5972 5973 static const GLchar* tess_eval_shader_template = "#version 430 core\n" 5974 "#extension GL_ARB_enhanced_layouts : require\n" 5975 "\n" 5976 "layout(isolines, point_mode) in;\n" 5977 "\n" 5978 "INTERFACE" 5979 "\n" 5980 "void main()\n" 5981 "{\n" 5982 "CALCULATIONS" 5983 "\n" 5984 "ASSIGNMENTS" 5985 "}\n" 5986 "\n"; 5987 5988 static const GLchar* vertex_shader_template = "#version 430 core\n" 5989 "#extension GL_ARB_enhanced_layouts : require\n" 5990 "\n" 5991 "INTERFACE" 5992 "\n" 5993 "void main()\n" 5994 "{\n" 5995 "CALCULATIONS" 5996 "\n" 5997 "ASSIGNMENTS" 5998 "}\n" 5999 "\n"; 6000 6001 const GLchar* result = 0; 6002 6003 switch (stage) 6004 { 6005 case Utils::Shader::COMPUTE: 6006 result = compute_shader_template; 6007 break; 6008 case Utils::Shader::FRAGMENT: 6009 result = fragment_shader_template; 6010 break; 6011 case Utils::Shader::GEOMETRY: 6012 result = geometry_shader_template; 6013 break; 6014 case Utils::Shader::TESS_CTRL: 6015 result = tess_ctrl_shader_template; 6016 break; 6017 case Utils::Shader::TESS_EVAL: 6018 result = tess_eval_shader_template; 6019 break; 6020 case Utils::Shader::VERTEX: 6021 result = vertex_shader_template; 6022 break; 6023 default: 6024 TCU_FAIL("Invalid enum"); 6025 } 6026 6027 return result; 6028 } 6029 6030 /** Prepare buffer according to descriptor 6031 * 6032 * @param buffer Buffer to prepare 6033 * @param desc Descriptor 6034 **/ 6035 void BufferTestBase::prepareBuffer(Utils::Buffer& buffer, bufferDescriptor& desc) 6036 { 6037 GLsizeiptr size = 0; 6038 GLvoid* data = 0; 6039 6040 if (false == desc.m_initial_data.empty()) 6041 { 6042 size = desc.m_initial_data.size(); 6043 data = &desc.m_initial_data[0]; 6044 } 6045 else if (false == desc.m_expected_data.empty()) 6046 { 6047 size = desc.m_expected_data.size(); 6048 } 6049 6050 buffer.Init(desc.m_target, Utils::Buffer::StaticDraw, size, data); 6051 6052 if (bufferDescriptor::m_non_indexed != desc.m_index) 6053 { 6054 buffer.BindBase(desc.m_index); 6055 } 6056 else 6057 { 6058 buffer.Bind(); 6059 } 6060 } 6061 6062 /** Prepare collection of buffer 6063 * 6064 * @param descriptors Collection of descriptors 6065 * @param out_buffers Collection of buffers 6066 **/ 6067 void BufferTestBase::prepareBuffers(bufferDescriptor::Vector& descriptors, bufferCollection& out_buffers) 6068 { 6069 for (bufferDescriptor::Vector::iterator it = descriptors.begin(), end = descriptors.end(); end != it; ++it) 6070 { 6071 bufferCollection::pair pair; 6072 6073 pair.m_buffer = new Utils::Buffer(m_context); 6074 if (0 == pair.m_buffer) 6075 { 6076 TCU_FAIL("Memory allocation failed"); 6077 } 6078 6079 pair.m_descriptor = &(*it); 6080 6081 prepareBuffer(*pair.m_buffer, *pair.m_descriptor); 6082 6083 out_buffers.m_vector.push_back(pair); 6084 } 6085 } 6086 6087 /** Destructor 6088 * 6089 **/ 6090 BufferTestBase::bufferCollection::~bufferCollection() 6091 { 6092 for (Vector::iterator it = m_vector.begin(), end = m_vector.end(); end != it; ++it) 6093 { 6094 if (0 != it->m_buffer) 6095 { 6096 delete it->m_buffer; 6097 it->m_buffer = 0; 6098 } 6099 } 6100 } 6101 6102 /** Constructor 6103 * 6104 * @param context Test context 6105 * @param test_name Name of test 6106 * @param test_description Description of test 6107 **/ 6108 NegativeTestBase::NegativeTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description) 6109 : TestBase(context, test_name, test_description) 6110 { 6111 } 6112 6113 /** Selects if "compute" stage is relevant for test 6114 * 6115 * @param ignored 6116 * 6117 * @return true 6118 **/ 6119 bool NegativeTestBase::isComputeRelevant(GLuint /* test_case_index */) 6120 { 6121 return true; 6122 } 6123 6124 /** Selects if compilation failure is expected result 6125 * 6126 * @param ignored 6127 * 6128 * @return true 6129 **/ 6130 bool NegativeTestBase::isFailureExpected(GLuint /* test_case_index */) 6131 { 6132 return true; 6133 } 6134 6135 /** Runs test case 6136 * 6137 * @param test_case_index Id of test case 6138 * 6139 * @return true if test case pass, false otherwise 6140 **/ 6141 bool NegativeTestBase::testCase(GLuint test_case_index) 6142 { 6143 bool test_case_result = true; 6144 6145 /* Compute */ 6146 if (true == isComputeRelevant(test_case_index)) 6147 { 6148 const std::string& cs_source = getShaderSource(test_case_index, Utils::Shader::COMPUTE); 6149 bool is_build_error = false; 6150 const bool is_failure_expected = isFailureExpected(test_case_index); 6151 Utils::Program program(m_context); 6152 6153 try 6154 { 6155 program.Init(cs_source, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */, 6156 false /* separable */); 6157 } 6158 catch (Utils::Shader::InvalidSourceException& exc) 6159 { 6160 if (false == is_failure_expected) 6161 { 6162 m_context.getTestContext().getLog() 6163 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage; 6164 exc.log(m_context); 6165 } 6166 6167 #if DEBUG_NEG_LOG_ERROR 6168 6169 else 6170 { 6171 m_context.getTestContext().getLog() 6172 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: " 6173 << tcu::TestLog::EndMessage; 6174 exc.log(m_context); 6175 } 6176 6177 #endif /* DEBUG_NEG_LOG_ERROR */ 6178 6179 is_build_error = true; 6180 } 6181 catch (Utils::Program::BuildException& exc) 6182 { 6183 if (false == is_failure_expected) 6184 { 6185 m_context.getTestContext().getLog() 6186 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage; 6187 exc.log(m_context); 6188 } 6189 6190 #if DEBUG_NEG_LOG_ERROR 6191 6192 else 6193 { 6194 m_context.getTestContext().getLog() 6195 << tcu::TestLog::Message 6196 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage; 6197 exc.log(m_context); 6198 } 6199 6200 #endif /* DEBUG_NEG_LOG_ERROR */ 6201 6202 is_build_error = true; 6203 } 6204 6205 if (is_build_error != is_failure_expected) 6206 { 6207 if (!is_build_error) 6208 { 6209 m_context.getTestContext().getLog() 6210 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage; 6211 Utils::Shader::LogSource(m_context, cs_source, Utils::Shader::COMPUTE); 6212 } 6213 test_case_result = false; 6214 } 6215 } 6216 else /* Draw */ 6217 { 6218 const std::string& fs_source = getShaderSource(test_case_index, Utils::Shader::FRAGMENT); 6219 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY); 6220 bool is_build_error = false; 6221 const bool is_failure_expected = isFailureExpected(test_case_index); 6222 Utils::Program program(m_context); 6223 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL); 6224 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL); 6225 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX); 6226 6227 try 6228 { 6229 program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source, false /* separable */); 6230 } 6231 catch (Utils::Shader::InvalidSourceException& exc) 6232 { 6233 if (false == is_failure_expected) 6234 { 6235 m_context.getTestContext().getLog() 6236 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage; 6237 exc.log(m_context); 6238 } 6239 6240 #if DEBUG_NEG_LOG_ERROR 6241 6242 else 6243 { 6244 m_context.getTestContext().getLog() 6245 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: " 6246 << tcu::TestLog::EndMessage; 6247 exc.log(m_context); 6248 } 6249 6250 #endif /* DEBUG_NEG_LOG_ERROR */ 6251 6252 is_build_error = true; 6253 } 6254 catch (Utils::Program::BuildException& exc) 6255 { 6256 if (false == is_failure_expected) 6257 { 6258 m_context.getTestContext().getLog() 6259 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage; 6260 exc.log(m_context); 6261 } 6262 6263 #if DEBUG_NEG_LOG_ERROR 6264 6265 else 6266 { 6267 m_context.getTestContext().getLog() 6268 << tcu::TestLog::Message 6269 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage; 6270 exc.log(m_context); 6271 } 6272 6273 #endif /* DEBUG_NEG_LOG_ERROR */ 6274 6275 is_build_error = true; 6276 } 6277 6278 if (is_build_error != is_failure_expected) 6279 { 6280 if (!is_build_error) 6281 { 6282 m_context.getTestContext().getLog() 6283 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage; 6284 Utils::Shader::LogSource(m_context, vs_source, Utils::Shader::VERTEX); 6285 Utils::Shader::LogSource(m_context, tcs_source, Utils::Shader::TESS_CTRL); 6286 Utils::Shader::LogSource(m_context, tes_source, Utils::Shader::TESS_EVAL); 6287 Utils::Shader::LogSource(m_context, gs_source, Utils::Shader::GEOMETRY); 6288 Utils::Shader::LogSource(m_context, fs_source, Utils::Shader::FRAGMENT); 6289 } 6290 test_case_result = false; 6291 } 6292 } 6293 6294 return test_case_result; 6295 } 6296 6297 /* Constants used by TextureTestBase */ 6298 const glw::GLuint TextureTestBase::m_width = 16; 6299 const glw::GLuint TextureTestBase::m_height = 16; 6300 6301 /** Constructor 6302 * 6303 * @param context Test context 6304 * @param test_name Name of test 6305 * @param test_description Description of test 6306 **/ 6307 TextureTestBase::TextureTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description) 6308 : TestBase(context, test_name, test_description) 6309 { 6310 } 6311 6312 /** Get locations for all inputs with automatic_location 6313 * 6314 * @param program Program object 6315 * @param program_interface Interface of program 6316 **/ 6317 void TextureTestBase::prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface) 6318 { 6319 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 6320 6321 Utils::Variable::PtrVector& inputs = si.m_inputs; 6322 6323 for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it) 6324 { 6325 /* Test does not specify location, query value and set */ 6326 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location) 6327 { 6328 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT); 6329 GLint location = 0; 6330 6331 program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location); 6332 6333 (*it)->m_descriptor.m_expected_location = location; 6334 } 6335 } 6336 } 6337 6338 /** Verifies contents of drawn image 6339 * 6340 * @param ignored 6341 * @param color_0 Verified image 6342 * 6343 * @return true if image is filled with 1, false otherwise 6344 **/ 6345 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& color_0) 6346 { 6347 static const GLuint size = m_width * m_height; 6348 static const GLuint expected_color = 1; 6349 6350 std::vector<GLuint> data; 6351 data.resize(size); 6352 6353 color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]); 6354 6355 for (GLuint i = 0; i < size; ++i) 6356 { 6357 const GLuint color = data[i]; 6358 6359 if (expected_color != color) 6360 { 6361 m_context.getTestContext().getLog() << tcu::TestLog::Message << "R32UI[" << i << "]:" << color 6362 << tcu::TestLog::EndMessage; 6363 return false; 6364 } 6365 } 6366 6367 return true; 6368 } 6369 6370 /** Execute dispatch compute for 16x16x1 6371 * 6372 * @param ignored 6373 **/ 6374 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */) 6375 { 6376 const Functions& gl = m_context.getRenderContext().getFunctions(); 6377 6378 gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */); 6379 GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute"); 6380 } 6381 6382 /** Execute drawArrays for single vertex 6383 * 6384 * @param ignored 6385 **/ 6386 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */) 6387 { 6388 const Functions& gl = m_context.getRenderContext().getFunctions(); 6389 6390 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 6391 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 6392 } 6393 6394 /** Prepare code snippet that will pass in variables to out variables 6395 * 6396 * @param ignored 6397 * @param varying_passthrough Collection of connections between in and out variables 6398 * @param stage Shader stage 6399 * 6400 * @return Code that pass in variables to next stage 6401 **/ 6402 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */, 6403 Utils::VaryingPassthrough& varying_passthrough, Utils::Shader::STAGES stage) 6404 { 6405 static const GLchar* separator = "\n "; 6406 6407 /* Skip for compute shader */ 6408 if (Utils::Shader::COMPUTE == stage) 6409 { 6410 return ""; 6411 } 6412 6413 Utils::VaryingConnection::Vector& vector = varying_passthrough.Get(stage); 6414 6415 std::string result = Utils::g_list; 6416 size_t position = 0; 6417 6418 for (GLuint i = 0; i < vector.size(); ++i) 6419 { 6420 6421 Utils::VaryingConnection& connection = vector[i]; 6422 6423 Utils::Variable* in = connection.m_in; 6424 Utils::Variable* out = connection.m_out; 6425 6426 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT); 6427 Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT); 6428 6429 const std::string passthrough = 6430 getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour); 6431 6432 Utils::insertElementOfList(passthrough.c_str(), separator, position, result); 6433 } 6434 6435 Utils::endList("", position, result); 6436 6437 return result; 6438 } 6439 6440 /** Basic implementation of method getProgramInterface 6441 * 6442 * @param ignored 6443 * @param ignored 6444 * @param ignored 6445 **/ 6446 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */, 6447 Utils::ProgramInterface& /* program_interface */, 6448 Utils::VaryingPassthrough& /* varying_passthrough */) 6449 { 6450 } 6451 6452 /** Prepare code snippet that will verify in and uniform variables 6453 * 6454 * @param ignored 6455 * @param program_interface Interface of program 6456 * @param stage Shader stage 6457 * 6458 * @return Code that verify variables 6459 **/ 6460 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */, 6461 Utils::ProgramInterface& program_interface, 6462 Utils::Shader::STAGES stage) 6463 { 6464 static const GLchar* separator = " ||\n "; 6465 6466 std::string verification = "if (LIST)\n" 6467 " {\n" 6468 " result = 0u;\n" 6469 " }\n"; 6470 6471 /* Get flavour of in and out variables */ 6472 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT); 6473 6474 /* Get interface for shader stage */ 6475 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage); 6476 6477 /* There are no varialbes to verify */ 6478 if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size())) 6479 { 6480 return ""; 6481 } 6482 6483 /* For each in variable insert verification code */ 6484 size_t position = 0; 6485 6486 for (GLuint i = 0; i < si.m_inputs.size(); ++i) 6487 { 6488 const Utils::Variable& var = *si.m_inputs[i]; 6489 const std::string& var_verification = getVariableVerification("", var.m_data, var.m_descriptor, in_flavour); 6490 6491 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification); 6492 } 6493 6494 /* For each unifrom variable insert verification code */ 6495 for (GLuint i = 0; i < si.m_uniforms.size(); ++i) 6496 { 6497 const Utils::Variable& var = *si.m_uniforms[i]; 6498 const std::string& var_verification = 6499 getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC); 6500 6501 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification); 6502 } 6503 6504 /* For each ssb variable insert verification code */ 6505 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i) 6506 { 6507 const Utils::Variable& var = *si.m_ssb_blocks[i]; 6508 const std::string& var_verification = 6509 getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC); 6510 6511 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification); 6512 } 6513 6514 Utils::endList("", position, verification); 6515 6516 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE 6517 6518 { 6519 GLchar buffer[16]; 6520 sprintf(buffer, "%d", stage + 10); 6521 Utils::replaceToken("0u", position, buffer, verification); 6522 } 6523 6524 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE 6525 6526 if (Utils::Shader::VERTEX == stage) 6527 { 6528 Utils::replaceToken("0u", position, "in_vs_first.x", verification); 6529 } 6530 else 6531 { 6532 Utils::replaceToken("0u", position, "31u", verification); 6533 } 6534 6535 #endif 6536 6537 /* Done */ 6538 return verification; 6539 } 6540 6541 /** Selects if "compute" stage is relevant for test 6542 * 6543 * @param ignored 6544 * 6545 * @return true 6546 **/ 6547 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */) 6548 { 6549 return true; 6550 } 6551 6552 /** Selects if "draw" stages are relevant for test 6553 * 6554 * @param ignored 6555 * 6556 * @return true 6557 **/ 6558 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */) 6559 { 6560 return true; 6561 } 6562 6563 /** Prepare code that will do assignment of single in to single out 6564 * 6565 * @param in_parent_name Name of parent in variable 6566 * @param in_variable Descriptor of in variable 6567 * @param in_flavour Flavoud of in variable 6568 * @param out_parent_name Name of parent out variable 6569 * @param out_variable Descriptor of out variable 6570 * @param out_flavour Flavoud of out variable 6571 * 6572 * @return Code that does OUT = IN 6573 **/ 6574 std::string TextureTestBase::getVariablePassthrough(const std::string& in_parent_name, 6575 const Utils::Variable::Descriptor& in_variable, 6576 Utils::Variable::FLAVOUR in_flavour, 6577 const std::string& out_parent_name, 6578 const Utils::Variable::Descriptor& out_variable, 6579 Utils::Variable::FLAVOUR out_flavour) 6580 { 6581 bool done = false; 6582 GLuint index = 0; 6583 GLuint member_index = 0; 6584 size_t position = 0; 6585 std::string result = Utils::g_list; 6586 static const GLchar* separator = ";\n "; 6587 6588 /* For each member of each array element */ 6589 do 6590 { 6591 const std::string in_name = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index); 6592 const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index); 6593 std::string passthrough; 6594 6595 /* Prepare verification */ 6596 if (Utils::Variable::BUILTIN == in_variable.m_type) 6597 { 6598 size_t pass_position = 0; 6599 6600 passthrough = "OUT = IN;"; 6601 6602 Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough); 6603 Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough); 6604 6605 /* Increment index */ 6606 ++index; 6607 } 6608 else 6609 { 6610 const Utils::Interface* in_interface = in_variable.m_interface; 6611 const Utils::Interface* out_interface = out_variable.m_interface; 6612 6613 if ((0 == in_interface) || (0 == out_interface)) 6614 { 6615 TCU_FAIL("Nullptr"); 6616 } 6617 6618 const Utils::Variable::Descriptor& in_member = in_interface->m_members[member_index]; 6619 const Utils::Variable::Descriptor& out_member = out_interface->m_members[member_index]; 6620 6621 passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member, 6622 Utils::Variable::BASIC); 6623 6624 /* Increment member_index */ 6625 ++member_index; 6626 6627 /* Increment index and reset member_index if all members were processed */ 6628 if (in_interface->m_members.size() == member_index) 6629 { 6630 ++index; 6631 member_index = 0; 6632 } 6633 } 6634 6635 /* Check if loop should end */ 6636 if ((index >= in_variable.m_n_array_elements) && (0 == member_index)) 6637 { 6638 done = true; 6639 } 6640 6641 Utils::insertElementOfList(passthrough.c_str(), separator, position, result); 6642 6643 } while (true != done); 6644 6645 Utils::endList("", position, result); 6646 6647 /* Done */ 6648 return result; 6649 } 6650 6651 /** Get verification of single variable 6652 * 6653 * @param parent_name Name of parent variable 6654 * @param data Data that should be used as EXPECTED 6655 * @param variable Descriptor of variable 6656 * @param flavour Flavour of variable 6657 * 6658 * @return Code that does (EXPECTED != VALUE) || 6659 **/ 6660 std::string TextureTestBase::getVariableVerification(const std::string& parent_name, const GLvoid* data, 6661 const Utils::Variable::Descriptor& variable, 6662 Utils::Variable::FLAVOUR flavour) 6663 { 6664 static const GLchar* logic_op = " ||\n "; 6665 const GLuint n_elements = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements; 6666 size_t position = 0; 6667 std::string result = Utils::g_list; 6668 GLint stride = variable.m_expected_stride_of_element; 6669 6670 /* For each each array element */ 6671 for (GLuint element = 0; element < n_elements; ++element) 6672 { 6673 const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element); 6674 6675 /* Calculate data pointer */ 6676 GLvoid* data_ptr = (GLvoid*)((GLubyte*)data + element * stride); 6677 6678 /* Prepare verification */ 6679 if (Utils::Variable::BUILTIN == variable.m_type) 6680 { 6681 const std::string& expected = variable.m_builtin.GetGLSLConstructor(data_ptr); 6682 std::string verification; 6683 size_t verification_position = 0; 6684 6685 verification = "(EXPECTED != NAME)"; 6686 6687 Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification); 6688 Utils::replaceToken("NAME", verification_position, name.c_str(), verification); 6689 6690 Utils::insertElementOfList(verification.c_str(), logic_op, position, result); 6691 } 6692 else 6693 { 6694 const Utils::Interface* interface = variable.m_interface; 6695 6696 if (0 == interface) 6697 { 6698 TCU_FAIL("Nullptr"); 6699 } 6700 6701 const GLuint n_members = static_cast<GLuint>(interface->m_members.size()); 6702 6703 /* for each member */ 6704 for (GLuint member_index = 0; member_index < n_members; ++member_index) 6705 { 6706 const Utils::Variable::Descriptor& member = interface->m_members[member_index]; 6707 6708 /* Get verification of member */ 6709 const std::string& verification = 6710 getVariableVerification(name, (GLubyte*)data_ptr + member.m_offset, member, Utils::Variable::BASIC); 6711 6712 Utils::insertElementOfList(verification.c_str(), logic_op, position, result); 6713 } 6714 } 6715 } 6716 6717 Utils::endList("", position, result); 6718 6719 return result; 6720 } 6721 6722 /** Prepare attributes, vertex array object and array buffer 6723 * 6724 * @param test_case_index Index of test case 6725 * @param program_interface Interface of program 6726 * @param buffer Array buffer 6727 * @param vao Vertex array object 6728 **/ 6729 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface& program_interface, 6730 Utils::Buffer& buffer, Utils::VertexArray& vao) 6731 { 6732 bool use_component_qualifier = useComponentQualifier(test_case_index); 6733 6734 /* Get shader interface */ 6735 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 6736 6737 /* Bind vao and buffer */ 6738 vao.Bind(); 6739 buffer.Bind(); 6740 6741 /* Skip if there are no input variables in vertex shader */ 6742 if (0 == si.m_inputs.size()) 6743 { 6744 return; 6745 } 6746 6747 const Functions& gl = m_context.getRenderContext().getFunctions(); 6748 6749 /* Calculate vertex stride and check */ 6750 GLint max_inputs; 6751 gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_inputs); 6752 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 6753 6754 /* dvec3/4 vertex inputs use a single location but require 2x16B slots */ 6755 GLint max_slots = max_inputs * 2; 6756 6757 /* Compute used slots */ 6758 std::vector<GLint> slot_sizes; 6759 slot_sizes.resize(max_slots); 6760 std::fill(slot_sizes.begin(), slot_sizes.end(), 0); 6761 for (GLuint i = 0; i < si.m_inputs.size(); ++i) 6762 { 6763 Utils::Variable& variable = *si.m_inputs[i]; 6764 6765 GLint variable_size = static_cast<GLuint>(variable.m_data_size); 6766 6767 GLint base_slot = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16; 6768 GLint ends_at = variable.m_descriptor.m_offset % 16 + variable_size; 6769 6770 GLint array_length = std::max(1u, variable.m_descriptor.m_n_array_elements); 6771 for (GLint loc = 0; loc < array_length; loc++) { 6772 GLint slot = base_slot + loc; 6773 slot_sizes[slot] = std::max(slot_sizes[slot], ends_at); 6774 } 6775 } 6776 6777 /* Compute the offsets where we need to put vertex buffer data for each slot */ 6778 std::vector<GLint> slot_offsets; 6779 slot_offsets.resize(max_slots); 6780 std::fill(slot_offsets.begin(), slot_offsets.end(), -1); 6781 GLint buffer_size = 0; 6782 for (GLint i = 0; i < max_slots; i++) 6783 { 6784 if (slot_sizes[i] == 0) 6785 continue; 6786 slot_offsets[i] = buffer_size; 6787 buffer_size += slot_sizes[i]; 6788 } 6789 6790 /* Prepare buffer data and set up vao */ 6791 std::vector<GLubyte> buffer_data; 6792 buffer_data.resize(buffer_size); 6793 6794 GLubyte* ptr = &buffer_data[0]; 6795 6796 for (GLuint i = 0; i < si.m_inputs.size(); ++i) 6797 { 6798 Utils::Variable& variable = *si.m_inputs[i]; 6799 6800 GLint base_slot = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16; 6801 GLint variable_offset = variable.m_descriptor.m_offset % 16; 6802 GLint array_length = std::max(1u, variable.m_descriptor.m_n_array_elements); 6803 for (GLint loc = 0; loc < array_length; loc++) { 6804 GLint slot = base_slot + loc; 6805 memcpy(ptr + slot_offsets[slot] + variable_offset, variable.m_data, variable.m_data_size); 6806 } 6807 6808 if (false == use_component_qualifier) 6809 { 6810 vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin, 6811 variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized, 6812 variable.GetStride(), (GLvoid*)(intptr_t)(slot_offsets[base_slot] + variable_offset)); 6813 } 6814 else if (0 == variable.m_descriptor.m_expected_component) 6815 { 6816 /* Components can only be applied to vectors. 6817 Assumption that test use all 4 components */ 6818 const Utils::Type& type = 6819 Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type, 1 /* n_columns */, 4 /* n_rows */); 6820 6821 vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements, 6822 variable.m_descriptor.m_normalized, variable.GetStride(), 6823 (GLvoid*)(intptr_t)(slot_offsets[base_slot] + variable_offset)); 6824 } 6825 } 6826 6827 /* Update buffer */ 6828 buffer.Data(Utils::Buffer::StaticDraw, buffer_size, ptr); 6829 } 6830 6831 /** Get locations for all outputs with automatic_location 6832 * 6833 * @param program Program object 6834 * @param program_interface Interface of program 6835 **/ 6836 void TextureTestBase::prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface) 6837 { 6838 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT); 6839 Utils::Variable::PtrVector& outputs = si.m_outputs; 6840 6841 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it) 6842 { 6843 /* Test does not specify location, query value and set */ 6844 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location) 6845 { 6846 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT); 6847 GLint location = 0; 6848 6849 program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location); 6850 6851 (*it)->m_descriptor.m_expected_location = location; 6852 } 6853 } 6854 } 6855 6856 /** Prepare framebuffer with single texture as color attachment 6857 * 6858 * @param framebuffer Framebuffer 6859 * @param color_0_texture Texture that will used as color attachment 6860 **/ 6861 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture) 6862 { 6863 /* Prepare data */ 6864 std::vector<GLuint> texture_data; 6865 texture_data.resize(m_width * m_height); 6866 6867 for (GLuint i = 0; i < texture_data.size(); ++i) 6868 { 6869 texture_data[i] = 0x20406080; 6870 } 6871 6872 /* Prepare texture */ 6873 color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, 6874 &texture_data[0]); 6875 6876 /* Prepare framebuffer */ 6877 framebuffer.Init(); 6878 framebuffer.Bind(); 6879 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height); 6880 6881 framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); 6882 framebuffer.Clear(GL_COLOR_BUFFER_BIT); 6883 } 6884 6885 /** Prepare iamge unit for compute shader 6886 * 6887 * @param location Uniform location 6888 * @param image_texture Texture that will used as color attachment 6889 **/ 6890 void TextureTestBase::prepareImage(GLint location, Utils::Texture& image_texture) const 6891 { 6892 static const GLuint image_unit = 0; 6893 6894 std::vector<GLuint> texture_data; 6895 texture_data.resize(m_width * m_height); 6896 6897 for (GLuint i = 0; i < texture_data.size(); ++i) 6898 { 6899 texture_data[i] = 0x20406080; 6900 } 6901 6902 image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, 6903 &texture_data[0]); 6904 6905 const Functions& gl = m_context.getRenderContext().getFunctions(); 6906 6907 gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */, 6908 GL_WRITE_ONLY, GL_R32UI); 6909 GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture"); 6910 6911 Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit); 6912 } 6913 6914 /** Basic implementation 6915 * 6916 * @param ignored 6917 * @param si Shader interface 6918 * @param program Program 6919 * @param cs_buffer Buffer for ssb blocks 6920 **/ 6921 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program, 6922 Utils::Buffer& buffer) 6923 { 6924 /* Skip if there are no input variables in vertex shader */ 6925 if (0 == si.m_ssb_blocks.size()) 6926 { 6927 return; 6928 } 6929 6930 /* Calculate vertex stride */ 6931 GLint ssbs_stride = 0; 6932 6933 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i) 6934 { 6935 Utils::Variable& variable = *si.m_ssb_blocks[i]; 6936 6937 if (false == variable.IsBlock()) 6938 { 6939 continue; 6940 } 6941 6942 GLint variable_stride = variable.GetStride(); 6943 6944 GLint ends_at = variable_stride + variable.m_descriptor.m_offset; 6945 6946 ssbs_stride = std::max(ssbs_stride, ends_at); 6947 } 6948 6949 /* Set active program */ 6950 program.Use(); 6951 6952 /* Allocate */ 6953 buffer.Bind(); 6954 buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0); 6955 6956 /* Set up uniforms */ 6957 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i) 6958 { 6959 Utils::Variable& variable = *si.m_ssb_blocks[i]; 6960 6961 /* prepareUnifor should work fine for ssb blocks */ 6962 prepareUniform(program, variable, buffer); 6963 } 6964 } 6965 6966 /** Basic implementation 6967 * 6968 * @param test_case_index Test case index 6969 * @param program_interface Program interface 6970 * @param program Program 6971 * @param cs_buffer Buffer for compute shader stage 6972 **/ 6973 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface, 6974 Utils::Program& program, Utils::Buffer& cs_buffer) 6975 { 6976 cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0); 6977 6978 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE); 6979 6980 prepareSSBs(test_case_index, cs, program, cs_buffer); 6981 6982 cs_buffer.BindBase(Utils::Shader::COMPUTE); 6983 } 6984 6985 /** Basic implementation 6986 * 6987 * @param test_case_index Test case index 6988 * @param program_interface Program interface 6989 * @param program Program 6990 * @param fs_buffer Buffer for fragment shader stage 6991 * @param gs_buffer Buffer for geometry shader stage 6992 * @param tcs_buffer Buffer for tessellation control shader stage 6993 * @param tes_buffer Buffer for tessellation evaluation shader stage 6994 * @param vs_buffer Buffer for vertex shader stage 6995 **/ 6996 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface, 6997 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer, 6998 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer) 6999 { 7000 fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0); 7001 gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0); 7002 tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0); 7003 tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0); 7004 vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0); 7005 7006 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT); 7007 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY); 7008 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL); 7009 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL); 7010 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 7011 7012 prepareSSBs(test_case_index, fs, program, fs_buffer); 7013 prepareSSBs(test_case_index, gs, program, gs_buffer); 7014 prepareSSBs(test_case_index, tcs, program, tcs_buffer); 7015 prepareSSBs(test_case_index, tes, program, tes_buffer); 7016 prepareSSBs(test_case_index, vs, program, vs_buffer); 7017 7018 fs_buffer.BindBase(Utils::Shader::FRAGMENT); 7019 gs_buffer.BindBase(Utils::Shader::GEOMETRY); 7020 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL); 7021 tes_buffer.BindBase(Utils::Shader::TESS_EVAL); 7022 vs_buffer.BindBase(Utils::Shader::VERTEX); 7023 } 7024 7025 /** Updates buffer data with variable 7026 * 7027 * @param program Program object 7028 * @param variable Variable 7029 * @param buffer Buffer 7030 **/ 7031 void TextureTestBase::prepareUniform(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer) 7032 { 7033 const Functions& gl = m_context.getRenderContext().getFunctions(); 7034 7035 GLsizei count = variable.m_descriptor.m_n_array_elements; 7036 if (0 == count) 7037 { 7038 count = 1; 7039 } 7040 7041 if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type) 7042 { 7043 program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location, 7044 variable.m_data); 7045 } 7046 else 7047 { 7048 const bool is_block = variable.IsBlock(); 7049 7050 if (false == is_block) 7051 { 7052 TCU_FAIL("Not implemented"); 7053 } 7054 else 7055 { 7056 buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count, 7057 variable.m_data); 7058 } 7059 } 7060 } 7061 7062 /** Basic implementation 7063 * 7064 * @param ignored 7065 * @param si Shader interface 7066 * @param program Program 7067 * @param cs_buffer Buffer for uniform blocks 7068 **/ 7069 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program, 7070 Utils::Buffer& buffer) 7071 { 7072 /* Skip if there are no input variables in vertex shader */ 7073 if (0 == si.m_uniforms.size()) 7074 { 7075 return; 7076 } 7077 7078 /* Calculate vertex stride */ 7079 GLint uniforms_stride = 0; 7080 7081 for (GLuint i = 0; i < si.m_uniforms.size(); ++i) 7082 { 7083 Utils::Variable& variable = *si.m_uniforms[i]; 7084 7085 if (false == variable.IsBlock()) 7086 { 7087 continue; 7088 } 7089 7090 GLint variable_stride = variable.GetStride(); 7091 7092 GLint ends_at = variable_stride + variable.m_descriptor.m_offset; 7093 7094 uniforms_stride = std::max(uniforms_stride, ends_at); 7095 } 7096 7097 /* Set active program */ 7098 program.Use(); 7099 7100 /* Allocate */ 7101 buffer.Bind(); 7102 buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0); 7103 7104 /* Set up uniforms */ 7105 for (GLuint i = 0; i < si.m_uniforms.size(); ++i) 7106 { 7107 Utils::Variable& variable = *si.m_uniforms[i]; 7108 7109 prepareUniform(program, variable, buffer); 7110 } 7111 } 7112 7113 /** Basic implementation 7114 * 7115 * @param test_case_index Test case index 7116 * @param program_interface Program interface 7117 * @param program Program 7118 * @param cs_buffer Buffer for compute shader stage 7119 **/ 7120 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface, 7121 Utils::Program& program, Utils::Buffer& cs_buffer) 7122 { 7123 cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7124 7125 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE); 7126 7127 prepareUniforms(test_case_index, cs, program, cs_buffer); 7128 7129 cs_buffer.BindBase(Utils::Shader::COMPUTE); 7130 } 7131 7132 /** Basic implementation 7133 * 7134 * @param test_case_index Test case index 7135 * @param program_interface Program interface 7136 * @param program Program 7137 * @param fs_buffer Buffer for fragment shader stage 7138 * @param gs_buffer Buffer for geometry shader stage 7139 * @param tcs_buffer Buffer for tessellation control shader stage 7140 * @param tes_buffer Buffer for tessellation evaluation shader stage 7141 * @param vs_buffer Buffer for vertex shader stage 7142 **/ 7143 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface, 7144 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer, 7145 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer) 7146 { 7147 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7148 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7149 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7150 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7151 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7152 7153 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT); 7154 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY); 7155 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL); 7156 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL); 7157 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 7158 7159 prepareUniforms(test_case_index, fs, program, fs_buffer); 7160 prepareUniforms(test_case_index, gs, program, gs_buffer); 7161 prepareUniforms(test_case_index, tcs, program, tcs_buffer); 7162 prepareUniforms(test_case_index, tes, program, tes_buffer); 7163 prepareUniforms(test_case_index, vs, program, vs_buffer); 7164 7165 fs_buffer.BindBase(Utils::Shader::FRAGMENT); 7166 gs_buffer.BindBase(Utils::Shader::GEOMETRY); 7167 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL); 7168 tes_buffer.BindBase(Utils::Shader::TESS_EVAL); 7169 vs_buffer.BindBase(Utils::Shader::VERTEX); 7170 } 7171 7172 /** Basic implementation 7173 * 7174 * @param test_case_index Test case index 7175 * @param program_interface Program interface 7176 * @param program Program 7177 * @param fs_buffer Buffer for fragment shader stage 7178 * @param gs_buffer Buffer for geometry shader stage 7179 * @param tcs_buffer Buffer for tessellation control shader stage 7180 * @param tes_buffer Buffer for tessellation evaluation shader stage 7181 * @param vs_buffer Buffer for vertex shader stage 7182 **/ 7183 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface, 7184 Utils::Program& fs_program, Utils::Program& gs_program, 7185 Utils::Program& tcs_program, Utils::Program& tes_program, 7186 Utils::Program& vs_program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer, 7187 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer) 7188 { 7189 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7190 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7191 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7192 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7193 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7194 7195 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT); 7196 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY); 7197 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL); 7198 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL); 7199 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 7200 7201 prepareUniforms(test_case_index, fs, fs_program, fs_buffer); 7202 fs_buffer.BindBase(Utils::Shader::FRAGMENT); 7203 7204 prepareUniforms(test_case_index, gs, gs_program, gs_buffer); 7205 gs_buffer.BindBase(Utils::Shader::GEOMETRY); 7206 7207 prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer); 7208 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL); 7209 7210 prepareUniforms(test_case_index, tes, tes_program, tes_buffer); 7211 tes_buffer.BindBase(Utils::Shader::TESS_EVAL); 7212 7213 prepareUniforms(test_case_index, vs, vs_program, vs_buffer); 7214 vs_buffer.BindBase(Utils::Shader::VERTEX); 7215 } 7216 7217 /** Prepare source for shader 7218 * 7219 * @param test_case_index Index of test case 7220 * @param program_interface Interface of program 7221 * @param varying_passthrough Collection of connection between in and out variables 7222 * @param stage Shader stage 7223 * 7224 * @return Source of shader 7225 **/ 7226 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface& program_interface, 7227 Utils::VaryingPassthrough& varying_passthrough, 7228 Utils::Shader::STAGES stage) 7229 { 7230 /* Get strings */ 7231 const GLchar* shader_template = getShaderTemplate(stage); 7232 const std::string& shader_interface = program_interface.GetInterfaceForStage(stage); 7233 7234 const std::string& verification = getVerificationSnippet(test_case_index, program_interface, stage); 7235 7236 const std::string& passthrough = getPassSnippet(test_case_index, varying_passthrough, stage); 7237 7238 const GLchar* per_vertex = ""; 7239 7240 std::string source = shader_template; 7241 size_t position = 0; 7242 7243 /* Replace tokens in template */ 7244 if (Utils::Shader::GEOMETRY == stage) 7245 { 7246 if (false == useMonolithicProgram(test_case_index)) 7247 { 7248 per_vertex = "out gl_PerVertex {\n" 7249 "vec4 gl_Position;\n" 7250 "};\n" 7251 "\n"; 7252 } 7253 7254 Utils::replaceToken("PERVERTEX", position, per_vertex, source); 7255 } 7256 7257 Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source); 7258 Utils::replaceToken("VERIFICATION", position, verification.c_str(), source); 7259 7260 if (false == verification.empty()) 7261 { 7262 Utils::replaceAllTokens("ELSE", " else ", source); 7263 } 7264 else 7265 { 7266 Utils::replaceAllTokens("ELSE", "", source); 7267 } 7268 7269 Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source); 7270 7271 /* Done */ 7272 return source; 7273 } 7274 7275 /** Returns template of shader for given stage 7276 * 7277 * @param stage Shade stage 7278 * 7279 * @return Proper template 7280 **/ 7281 const GLchar* TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage) 7282 { 7283 7284 static const GLchar* compute_shader_template = 7285 "#version 430 core\n" 7286 "#extension GL_ARB_enhanced_layouts : require\n" 7287 "\n" 7288 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 7289 "\n" 7290 "writeonly uniform uimage2D uni_image;\n" 7291 "\n" 7292 "INTERFACE" 7293 "\n" 7294 "void main()\n" 7295 "{\n" 7296 " uint result = 1u;\n" 7297 "\n" 7298 " VERIFICATION" 7299 "\n" 7300 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n" 7301 "}\n" 7302 "\n"; 7303 7304 static const GLchar* fragment_shader_template = "#version 430 core\n" 7305 "#extension GL_ARB_enhanced_layouts : require\n" 7306 "\n" 7307 "flat in uint gs_fs_result;\n" 7308 " out uint fs_out_result;\n" 7309 "\n" 7310 "INTERFACE" 7311 "\n" 7312 "void main()\n" 7313 "{\n" 7314 " uint result = 1u;\n" 7315 "\n" 7316 " if (1u != gs_fs_result)\n" 7317 " {\n" 7318 " result = gs_fs_result;\n" 7319 " }\n" 7320 "ELSEVERIFICATION" 7321 "\n" 7322 " fs_out_result = result;\n" 7323 " PASSTHROUGH\n" 7324 "}\n" 7325 "\n"; 7326 7327 static const GLchar* geometry_shader_template = 7328 "#version 430 core\n" 7329 "#extension GL_ARB_enhanced_layouts : require\n" 7330 "\n" 7331 "layout(points) in;\n" 7332 "layout(triangle_strip, max_vertices = 4) out;\n" 7333 "\n" 7334 " in uint tes_gs_result[];\n" 7335 "flat out uint gs_fs_result;\n" 7336 "\n" 7337 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */ 7338 "INTERFACE" 7339 "\n" 7340 "void main()\n" 7341 "{\n" 7342 " uint result = 1u;\n" 7343 "\n" 7344 " if (1u != tes_gs_result[0])\n" 7345 " {\n" 7346 " result = tes_gs_result[0];\n" 7347 " }\n" 7348 "ELSEVERIFICATION" 7349 "\n" 7350 " gs_fs_result = result;\n" 7351 " PASSTHROUGH\n" 7352 " gl_Position = vec4(-1, -1, 0, 1);\n" 7353 " EmitVertex();\n" 7354 " gs_fs_result = result;\n" 7355 " PASSTHROUGH\n" 7356 " gl_Position = vec4(-1, 1, 0, 1);\n" 7357 " EmitVertex();\n" 7358 " gs_fs_result = result;\n" 7359 " PASSTHROUGH\n" 7360 " gl_Position = vec4(1, -1, 0, 1);\n" 7361 " EmitVertex();\n" 7362 " gs_fs_result = result;\n" 7363 " PASSTHROUGH\n" 7364 " gl_Position = vec4(1, 1, 0, 1);\n" 7365 " EmitVertex();\n" 7366 "}\n" 7367 "\n"; 7368 7369 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n" 7370 "#extension GL_ARB_enhanced_layouts : require\n" 7371 "\n" 7372 "layout(vertices = 1) out;\n" 7373 "\n" 7374 "in uint vs_tcs_result[];\n" 7375 "out uint tcs_tes_result[];\n" 7376 "\n" 7377 "INTERFACE" 7378 "\n" 7379 "void main()\n" 7380 "{\n" 7381 " uint result = 1u;\n" 7382 "\n" 7383 " if (1u != vs_tcs_result[gl_InvocationID])\n" 7384 " {\n" 7385 " result = vs_tcs_result[gl_InvocationID];\n" 7386 " }\n" 7387 "ELSEVERIFICATION" 7388 "\n" 7389 " tcs_tes_result[gl_InvocationID] = result;\n" 7390 "\n" 7391 " PASSTHROUGH\n" 7392 "\n" 7393 " gl_TessLevelOuter[0] = 1.0;\n" 7394 " gl_TessLevelOuter[1] = 1.0;\n" 7395 " gl_TessLevelOuter[2] = 1.0;\n" 7396 " gl_TessLevelOuter[3] = 1.0;\n" 7397 " gl_TessLevelInner[0] = 1.0;\n" 7398 " gl_TessLevelInner[1] = 1.0;\n" 7399 "}\n" 7400 "\n"; 7401 7402 static const GLchar* tess_eval_shader_template = "#version 430 core\n" 7403 "#extension GL_ARB_enhanced_layouts : require\n" 7404 "\n" 7405 "layout(isolines, point_mode) in;\n" 7406 "\n" 7407 "in uint tcs_tes_result[];\n" 7408 "out uint tes_gs_result;\n" 7409 "\n" 7410 "INTERFACE" 7411 "\n" 7412 "void main()\n" 7413 "{\n" 7414 " uint result = 1u;\n" 7415 "\n" 7416 " if (1 != tcs_tes_result[0])\n" 7417 " {\n" 7418 " result = tcs_tes_result[0];\n" 7419 " }\n" 7420 "ELSEVERIFICATION" 7421 "\n" 7422 " tes_gs_result = result;\n" 7423 "\n" 7424 " PASSTHROUGH\n" 7425 "}\n" 7426 "\n"; 7427 7428 static const GLchar* vertex_shader_template = "#version 430 core\n" 7429 "#extension GL_ARB_enhanced_layouts : require\n" 7430 "\n" 7431 "out uint vs_tcs_result;\n" 7432 "\n" 7433 "INTERFACE" 7434 "\n" 7435 "void main()\n" 7436 "{\n" 7437 " uint result = 1u;\n" 7438 "\n" 7439 " VERIFICATION\n" 7440 "\n" 7441 " vs_tcs_result = result;\n" 7442 "\n" 7443 " PASSTHROUGH\n" 7444 "}\n" 7445 "\n"; 7446 7447 const GLchar* result = 0; 7448 7449 switch (stage) 7450 { 7451 case Utils::Shader::COMPUTE: 7452 result = compute_shader_template; 7453 break; 7454 case Utils::Shader::FRAGMENT: 7455 result = fragment_shader_template; 7456 break; 7457 case Utils::Shader::GEOMETRY: 7458 result = geometry_shader_template; 7459 break; 7460 case Utils::Shader::TESS_CTRL: 7461 result = tess_ctrl_shader_template; 7462 break; 7463 case Utils::Shader::TESS_EVAL: 7464 result = tess_eval_shader_template; 7465 break; 7466 case Utils::Shader::VERTEX: 7467 result = vertex_shader_template; 7468 break; 7469 default: 7470 TCU_FAIL("Invalid enum"); 7471 } 7472 7473 return result; 7474 } 7475 7476 /** Runs test case 7477 * 7478 * @param test_case_index Id of test case 7479 * 7480 * @return true if test case pass, false otherwise 7481 **/ 7482 bool TextureTestBase::testCase(GLuint test_case_index) 7483 { 7484 try 7485 { 7486 if (true == useMonolithicProgram(test_case_index)) 7487 { 7488 return testMonolithic(test_case_index); 7489 } 7490 else 7491 { 7492 return testSeparable(test_case_index); 7493 } 7494 } 7495 catch (Utils::Shader::InvalidSourceException& exc) 7496 { 7497 exc.log(m_context); 7498 TCU_FAIL(exc.what()); 7499 } 7500 catch (Utils::Program::BuildException& exc) 7501 { 7502 TCU_FAIL(exc.what()); 7503 } 7504 } 7505 7506 /** Runs "draw" test with monolithic program 7507 * 7508 * @param test_case_index Id of test case 7509 **/ 7510 bool TextureTestBase::testMonolithic(GLuint test_case_index) 7511 { 7512 Utils::ProgramInterface program_interface; 7513 Utils::VaryingPassthrough varying_passthrough; 7514 7515 /* */ 7516 const std::string& test_name = getTestCaseName(test_case_index); 7517 7518 /* */ 7519 getProgramInterface(test_case_index, program_interface, varying_passthrough); 7520 7521 bool result = true; 7522 /* Draw */ 7523 if (true == isDrawRelevant(test_case_index)) 7524 { 7525 Utils::Buffer buffer_attr(m_context); 7526 Utils::Buffer buffer_ssb_fs(m_context); 7527 Utils::Buffer buffer_ssb_gs(m_context); 7528 Utils::Buffer buffer_ssb_tcs(m_context); 7529 Utils::Buffer buffer_ssb_tes(m_context); 7530 Utils::Buffer buffer_ssb_vs(m_context); 7531 Utils::Buffer buffer_u_fs(m_context); 7532 Utils::Buffer buffer_u_gs(m_context); 7533 Utils::Buffer buffer_u_tcs(m_context); 7534 Utils::Buffer buffer_u_tes(m_context); 7535 Utils::Buffer buffer_u_vs(m_context); 7536 Utils::Framebuffer framebuffer(m_context); 7537 Utils::Program program(m_context); 7538 Utils::Texture texture_fb(m_context); 7539 Utils::VertexArray vao(m_context); 7540 7541 /* */ 7542 const std::string& fragment_shader = 7543 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT); 7544 const std::string& geometry_shader = 7545 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY); 7546 const std::string& tess_ctrl_shader = 7547 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL); 7548 const std::string& tess_eval_shader = 7549 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL); 7550 const std::string& vertex_shader = 7551 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX); 7552 7553 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader, 7554 vertex_shader, false /* is_separable */); 7555 7556 /* */ 7557 prepareAttribLocation(program, program_interface); 7558 prepareFragmentDataLoc(program, program_interface); 7559 7560 /* */ 7561 std::stringstream stream; 7562 if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream)) 7563 { 7564 m_context.getTestContext().getLog() 7565 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name 7566 << ". Inspection of draw program interface failed:\n" 7567 << stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader) 7568 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader) 7569 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader); 7570 7571 return false; 7572 } 7573 7574 /* */ 7575 program.Use(); 7576 7577 /* */ 7578 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0); 7579 vao.Init(); 7580 prepareAttributes(test_case_index, program_interface, buffer_attr, vao); 7581 7582 /* */ 7583 prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs, 7584 buffer_u_tes, buffer_u_vs); 7585 7586 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs, 7587 buffer_ssb_tes, buffer_ssb_vs); 7588 7589 /* */ 7590 prepareFramebuffer(framebuffer, texture_fb); 7591 7592 /* Draw */ 7593 executeDrawCall(test_case_index); 7594 7595 #if USE_NSIGHT 7596 m_context.getRenderContext().postIterate(); 7597 #endif 7598 7599 /* Check results */ 7600 if (false == checkResults(test_case_index, texture_fb)) 7601 { 7602 m_context.getTestContext().getLog() 7603 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results." 7604 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader) 7605 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader) 7606 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader); 7607 7608 result = false; 7609 } 7610 } 7611 7612 /* Compute */ 7613 if (true == isComputeRelevant(test_case_index)) 7614 { 7615 Utils::Buffer buffer_ssb_cs(m_context); 7616 Utils::Buffer buffer_u_cs(m_context); 7617 Utils::Program program(m_context); 7618 Utils::Texture texture_im(m_context); 7619 Utils::VertexArray vao(m_context); 7620 7621 /* */ 7622 const std::string& compute_shader = 7623 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE); 7624 7625 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */, 7626 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */); 7627 7628 /* */ 7629 { 7630 std::stringstream stream; 7631 7632 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream)) 7633 { 7634 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name 7635 << ". Inspection of compute program interface failed:\n" 7636 << stream.str() << tcu::TestLog::EndMessage; 7637 7638 return false; 7639 } 7640 } 7641 7642 /* */ 7643 program.Use(); 7644 7645 /* */ 7646 vao.Init(); 7647 vao.Bind(); 7648 7649 /* */ 7650 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs); 7651 7652 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs); 7653 7654 /* */ 7655 GLint image_location = program.GetUniformLocation("uni_image"); 7656 prepareImage(image_location, texture_im); 7657 7658 /* Draw */ 7659 executeDispatchCall(test_case_index); 7660 7661 #if USE_NSIGHT 7662 m_context.getRenderContext().postIterate(); 7663 #endif 7664 7665 /* Check results */ 7666 if (false == checkResults(test_case_index, texture_im)) 7667 { 7668 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name 7669 << ". Compute - invalid results." << tcu::TestLog::EndMessage 7670 << tcu::TestLog::KernelSource(compute_shader); 7671 7672 result = false; 7673 } 7674 } 7675 7676 return result; 7677 } 7678 7679 /** Runs "draw" test with separable program 7680 * 7681 * @param test_case_index Id of test case 7682 **/ 7683 bool TextureTestBase::testSeparable(GLuint test_case_index) 7684 { 7685 Utils::ProgramInterface program_interface; 7686 Utils::VaryingPassthrough varying_passthrough; 7687 7688 /* */ 7689 const std::string& test_name = getTestCaseName(test_case_index); 7690 7691 /* */ 7692 getProgramInterface(test_case_index, program_interface, varying_passthrough); 7693 7694 bool result = true; 7695 /* Draw */ 7696 if (true == isDrawRelevant(test_case_index)) 7697 { 7698 Utils::Buffer buffer_attr(m_context); 7699 Utils::Buffer buffer_u_fs(m_context); 7700 Utils::Buffer buffer_u_gs(m_context); 7701 Utils::Buffer buffer_u_tcs(m_context); 7702 Utils::Buffer buffer_u_tes(m_context); 7703 Utils::Buffer buffer_u_vs(m_context); 7704 Utils::Framebuffer framebuffer(m_context); 7705 Utils::Pipeline pipeline(m_context); 7706 Utils::Program program_fs(m_context); 7707 Utils::Program program_gs(m_context); 7708 Utils::Program program_tcs(m_context); 7709 Utils::Program program_tes(m_context); 7710 Utils::Program program_vs(m_context); 7711 Utils::Texture texture_fb(m_context); 7712 Utils::VertexArray vao(m_context); 7713 7714 /* */ 7715 const std::string& fs = 7716 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT); 7717 const std::string& gs = 7718 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY); 7719 const std::string& tcs = 7720 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL); 7721 const std::string& tes = 7722 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL); 7723 const std::string& vs = 7724 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX); 7725 7726 program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */); 7727 program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */); 7728 program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */); 7729 program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */); 7730 program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */); 7731 7732 /* */ 7733 prepareAttribLocation(program_vs, program_interface); 7734 prepareFragmentDataLoc(program_vs, program_interface); 7735 7736 /* */ 7737 std::stringstream stream; 7738 if ((false == 7739 Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) || 7740 (false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT, 7741 stream)) || 7742 (false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY, 7743 stream)) || 7744 (false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface, 7745 Utils::Shader::TESS_CTRL, stream)) || 7746 (false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface, 7747 Utils::Shader::TESS_EVAL, stream))) 7748 { 7749 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name 7750 << ". Inspection of separable draw program interface failed:\n" 7751 << stream.str() << tcu::TestLog::EndMessage 7752 << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs) 7753 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) 7754 << tcu::TestLog::KernelSource(fs); 7755 7756 return false; 7757 } 7758 7759 /* */ 7760 pipeline.Init(); 7761 pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT); 7762 pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT); 7763 pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT); 7764 pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT); 7765 pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT); 7766 pipeline.Bind(); 7767 7768 /* */ 7769 7770 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0); 7771 vao.Init(); 7772 prepareAttributes(test_case_index, program_interface, buffer_attr, vao); 7773 7774 /* */ 7775 prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes, 7776 program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs); 7777 7778 Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id); 7779 7780 /* */ 7781 prepareFramebuffer(framebuffer, texture_fb); 7782 7783 /* Draw */ 7784 executeDrawCall(test_case_index); 7785 7786 #if USE_NSIGHT 7787 m_context.getRenderContext().postIterate(); 7788 #endif 7789 7790 /* Check results */ 7791 if (false == checkResults(test_case_index, texture_fb)) 7792 { 7793 m_context.getTestContext().getLog() 7794 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results." 7795 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs) 7796 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs); 7797 7798 result = false; 7799 } 7800 } 7801 7802 /* Compute */ 7803 if (true == isComputeRelevant(test_case_index)) 7804 { 7805 Utils::Buffer buffer_u_cs(m_context); 7806 Utils::Program program(m_context); 7807 Utils::Texture texture_im(m_context); 7808 Utils::VertexArray vao(m_context); 7809 7810 /* */ 7811 const std::string& compute_shader = 7812 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE); 7813 7814 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */, 7815 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */); 7816 7817 /* */ 7818 { 7819 std::stringstream stream; 7820 7821 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream)) 7822 { 7823 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name 7824 << ". Inspection of compute program interface failed:\n" 7825 << stream.str() << tcu::TestLog::EndMessage; 7826 7827 return false; 7828 } 7829 } 7830 7831 /* */ 7832 program.Use(); 7833 7834 /* */ 7835 vao.Init(); 7836 vao.Bind(); 7837 7838 /* */ 7839 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs); 7840 7841 /* */ 7842 GLint image_location = program.GetUniformLocation("uni_image"); 7843 prepareImage(image_location, texture_im); 7844 7845 /* Draw */ 7846 executeDispatchCall(test_case_index); 7847 7848 #if USE_NSIGHT 7849 m_context.getRenderContext().postIterate(); 7850 #endif 7851 7852 /* Check results */ 7853 if (false == checkResults(test_case_index, texture_im)) 7854 { 7855 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name 7856 << ". Compute - invalid results." << tcu::TestLog::EndMessage 7857 << tcu::TestLog::KernelSource(compute_shader); 7858 7859 result = false; 7860 } 7861 } 7862 7863 return result; 7864 } 7865 7866 /** Basic implementation 7867 * 7868 * @param ignored 7869 * 7870 * @return false 7871 **/ 7872 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */) 7873 { 7874 return false; 7875 } 7876 7877 /** Basic implementation 7878 * 7879 * @param ignored 7880 * 7881 * @return true 7882 **/ 7883 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */) 7884 { 7885 return true; 7886 } 7887 7888 /** Constructor 7889 * 7890 * @param context Test framework context 7891 **/ 7892 APIConstantValuesTest::APIConstantValuesTest(deqp::Context& context) 7893 : TestCase(context, "api_constant_values", "Test verifies values of api constants") 7894 { 7895 /* Nothing to be done here */ 7896 } 7897 7898 /** Execute test 7899 * 7900 * @return tcu::TestNode::STOP otherwise 7901 **/ 7902 tcu::TestNode::IterateResult APIConstantValuesTest::iterate() 7903 { 7904 static const GLuint expected_comp = 64; 7905 static const GLuint expected_xfb = 4; 7906 static const GLuint expected_sep = 4; 7907 GLint max_comp = 0; 7908 GLint max_xfb = 0; 7909 GLint max_sep = 0; 7910 bool test_result = true; 7911 7912 const Functions& gl = m_context.getRenderContext().getFunctions(); 7913 7914 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb); 7915 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 7916 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp); 7917 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 7918 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep); 7919 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 7920 7921 if (expected_xfb > (GLuint)max_xfb) 7922 { 7923 m_context.getTestContext().getLog() << tcu::TestLog::Message 7924 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb 7925 << " Expected at least " << expected_xfb << tcu::TestLog::EndMessage; 7926 7927 test_result = false; 7928 } 7929 7930 if (expected_comp > (GLuint)max_comp) 7931 { 7932 m_context.getTestContext().getLog() 7933 << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp 7934 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage; 7935 7936 test_result = false; 7937 } 7938 7939 if (expected_sep > (GLuint)max_sep) 7940 { 7941 m_context.getTestContext().getLog() << tcu::TestLog::Message 7942 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp 7943 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage; 7944 7945 test_result = false; 7946 } 7947 7948 /* Set result */ 7949 if (true == test_result) 7950 { 7951 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 7952 } 7953 else 7954 { 7955 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 7956 } 7957 7958 /* Done */ 7959 return tcu::TestNode::STOP; 7960 } 7961 7962 /** Constructor 7963 * 7964 * @param context Test framework context 7965 **/ 7966 APIErrorsTest::APIErrorsTest(deqp::Context& context) 7967 : TestCase(context, "api_errors", "Test verifies errors reeturned by api") 7968 { 7969 /* Nothing to be done here */ 7970 } 7971 7972 /** Execute test 7973 * 7974 * @return tcu::TestNode::STOP otherwise 7975 **/ 7976 tcu::TestNode::IterateResult APIErrorsTest::iterate() 7977 { 7978 GLint length = 0; 7979 GLchar name[64]; 7980 GLint param = 0; 7981 Utils::Program program(m_context); 7982 bool test_result = true; 7983 7984 const Functions& gl = m_context.getRenderContext().getFunctions(); 7985 7986 try 7987 { 7988 program.Init("" /* cs */, "#version 430 core\n" 7989 "#extension GL_ARB_enhanced_layouts : require\n" 7990 "\n" 7991 "in vec4 vs_fs;\n" 7992 "out vec4 fs_out;\n" 7993 "\n" 7994 "void main()\n" 7995 "{\n" 7996 " fs_out = vs_fs;\n" 7997 "}\n" 7998 "\n" /* fs */, 7999 "" /* gs */, "" /* tcs */, "" /* tes */, "#version 430 core\n" 8000 "#extension GL_ARB_enhanced_layouts : require\n" 8001 "\n" 8002 "in vec4 in_vs;\n" 8003 "layout (xfb_offset = 16) out vec4 vs_fs;\n" 8004 "\n" 8005 "void main()\n" 8006 "{\n" 8007 " vs_fs = in_vs;\n" 8008 "}\n" 8009 "\n" /* vs */, 8010 false /* separable */); 8011 } 8012 catch (Utils::Shader::InvalidSourceException& exc) 8013 { 8014 exc.log(m_context); 8015 TCU_FAIL(exc.what()); 8016 } 8017 catch (Utils::Program::BuildException& exc) 8018 { 8019 TCU_FAIL(exc.what()); 8020 } 8021 8022 /* 8023 * - GetProgramInterfaceiv should generate INVALID_OPERATION when 8024 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the 8025 * following: 8026 * * MAX_NAME_LENGTH, 8027 * * MAX_NUM_ACTIVE_VARIABLES; 8028 */ 8029 gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, ¶m); 8030 checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)", 8031 test_result); 8032 8033 /* 8034 * - GetProgramResourceIndex should generate INVALID_ENUM when 8035 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER; 8036 */ 8037 gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0"); 8038 checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result); 8039 /* 8040 * - GetProgramResourceName should generate INVALID_ENUM when 8041 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER; 8042 */ 8043 gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length, 8044 name); 8045 checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result); 8046 8047 /* Set result */ 8048 if (true == test_result) 8049 { 8050 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 8051 } 8052 else 8053 { 8054 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 8055 } 8056 8057 /* Done */ 8058 return tcu::TestNode::STOP; 8059 } 8060 8061 /** Check if error is the expected one. 8062 * 8063 * @param expected_error Expected error 8064 * @param message Message to log in case of error 8065 * @param test_result Test result, set to false in case of invalid error 8066 **/ 8067 void APIErrorsTest::checkError(GLenum expected_error, const GLchar* message, bool& test_result) 8068 { 8069 const Functions& gl = m_context.getRenderContext().getFunctions(); 8070 8071 GLenum error = gl.getError(); 8072 8073 if (error != expected_error) 8074 { 8075 m_context.getTestContext().getLog() 8076 << tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected " 8077 << glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage; 8078 8079 test_result = false; 8080 } 8081 } 8082 8083 /** Constructor 8084 * 8085 * @param context Test framework context 8086 **/ 8087 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context& context) 8088 : NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified") 8089 { 8090 /* Nothing to be done here */ 8091 } 8092 8093 /** Source for given test case and stage 8094 * 8095 * @param test_case_index Index of test case 8096 * @param stage Shader stage 8097 * 8098 * @return Shader source 8099 **/ 8100 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 8101 { 8102 static const GLchar* cs = "#version 430 core\n" 8103 "#extension GL_ARB_enhanced_layouts : require\n" 8104 "\n" 8105 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 8106 "\n" 8107 "writeonly uniform uimage2D uni_image;\n" 8108 "\n" 8109 "void main()\n" 8110 "{\n" 8111 " uint result = 1u;\n" 8112 " CONSTANT = 3;\n" 8113 "\n" 8114 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n" 8115 "}\n" 8116 "\n"; 8117 static const GLchar* fs = "#version 430 core\n" 8118 "#extension GL_ARB_enhanced_layouts : require\n" 8119 "\n" 8120 "in vec4 gs_fs;\n" 8121 "out vec4 fs_out;\n" 8122 "\n" 8123 "void main()\n" 8124 "{\n" 8125 "ASSIGNMENT" 8126 " fs_out = gs_fs;\n" 8127 "}\n" 8128 "\n"; 8129 static const GLchar* gs = "#version 430 core\n" 8130 "#extension GL_ARB_enhanced_layouts : require\n" 8131 "\n" 8132 "layout(points) in;\n" 8133 "layout(triangle_strip, max_vertices = 4) out;\n" 8134 "\n" 8135 "in vec4 tes_gs[];\n" 8136 "out vec4 gs_fs;\n" 8137 "\n" 8138 "void main()\n" 8139 "{\n" 8140 "ASSIGNMENT" 8141 " gs_fs = tes_gs[0];\n" 8142 " gl_Position = vec4(-1, -1, 0, 1);\n" 8143 " EmitVertex();\n" 8144 " gs_fs = tes_gs[0];\n" 8145 " gl_Position = vec4(-1, 1, 0, 1);\n" 8146 " EmitVertex();\n" 8147 " gs_fs = tes_gs[0];\n" 8148 " gl_Position = vec4(1, -1, 0, 1);\n" 8149 " EmitVertex();\n" 8150 " gs_fs = tes_gs[0];\n" 8151 " gl_Position = vec4(1, 1, 0, 1);\n" 8152 " EmitVertex();\n" 8153 "}\n" 8154 "\n"; 8155 static const GLchar* tcs = "#version 430 core\n" 8156 "#extension GL_ARB_enhanced_layouts : require\n" 8157 "\n" 8158 "layout(vertices = 1) out;\n" 8159 "\n" 8160 "in vec4 vs_tcs[];\n" 8161 "out vec4 tcs_tes[];\n" 8162 "\n" 8163 "void main()\n" 8164 "{\n" 8165 "\n" 8166 "ASSIGNMENT" 8167 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 8168 "\n" 8169 " gl_TessLevelOuter[0] = 1.0;\n" 8170 " gl_TessLevelOuter[1] = 1.0;\n" 8171 " gl_TessLevelOuter[2] = 1.0;\n" 8172 " gl_TessLevelOuter[3] = 1.0;\n" 8173 " gl_TessLevelInner[0] = 1.0;\n" 8174 " gl_TessLevelInner[1] = 1.0;\n" 8175 "}\n" 8176 "\n"; 8177 static const GLchar* tes = "#version 430 core\n" 8178 "#extension GL_ARB_enhanced_layouts : require\n" 8179 "\n" 8180 "layout(isolines, point_mode) in;\n" 8181 "\n" 8182 "in vec4 tcs_tes[];\n" 8183 "out vec4 tes_gs;\n" 8184 "\n" 8185 "void main()\n" 8186 "{\n" 8187 "ASSIGNMENT" 8188 " tes_gs = tcs_tes[0];\n" 8189 "}\n" 8190 "\n"; 8191 static const GLchar* vs = "#version 430 core\n" 8192 "#extension GL_ARB_enhanced_layouts : require\n" 8193 "\n" 8194 "in vec4 in_vs;\n" 8195 "out vec4 vs_tcs;\n" 8196 "\n" 8197 "void main()\n" 8198 "{\n" 8199 "ASSIGNMENT" 8200 " vs_tcs = in_vs;\n" 8201 "}\n" 8202 "\n"; 8203 8204 std::string source; 8205 testCase& test_case = m_test_cases[test_case_index]; 8206 8207 if (Utils::Shader::COMPUTE == test_case.m_stage) 8208 { 8209 size_t position = 0; 8210 8211 source = cs; 8212 8213 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source); 8214 } 8215 else 8216 { 8217 std::string assignment = " CONSTANT = 3;\n"; 8218 size_t position = 0; 8219 8220 switch (stage) 8221 { 8222 case Utils::Shader::FRAGMENT: 8223 source = fs; 8224 break; 8225 case Utils::Shader::GEOMETRY: 8226 source = gs; 8227 break; 8228 case Utils::Shader::TESS_CTRL: 8229 source = tcs; 8230 break; 8231 case Utils::Shader::TESS_EVAL: 8232 source = tes; 8233 break; 8234 case Utils::Shader::VERTEX: 8235 source = vs; 8236 break; 8237 default: 8238 TCU_FAIL("Invalid enum"); 8239 } 8240 8241 if (test_case.m_stage == stage) 8242 { 8243 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment); 8244 } 8245 else 8246 { 8247 assignment = ""; 8248 } 8249 8250 position = 0; 8251 Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source); 8252 } 8253 8254 return source; 8255 } 8256 8257 /** Get description of test case 8258 * 8259 * @param test_case_index Index of test case 8260 * 8261 * @return Constant name 8262 **/ 8263 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index) 8264 { 8265 std::string result = getConstantName(m_test_cases[test_case_index].m_constant); 8266 8267 return result; 8268 } 8269 8270 /** Get number of test cases 8271 * 8272 * @return Number of test cases 8273 **/ 8274 GLuint GLSLContantImmutablityTest::getTestCaseNumber() 8275 { 8276 return static_cast<GLuint>(m_test_cases.size()); 8277 } 8278 8279 /** Selects if "compute" stage is relevant for test 8280 * 8281 * @param test_case_index Index of test case 8282 * 8283 * @return true when tested stage is compute 8284 **/ 8285 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index) 8286 { 8287 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage); 8288 } 8289 8290 /** Prepare all test cases 8291 * 8292 **/ 8293 void GLSLContantImmutablityTest::testInit() 8294 { 8295 for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant) 8296 { 8297 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 8298 { 8299 testCase test_case = { (CONSTANTS)constant, (Utils::Shader::STAGES)stage }; 8300 8301 m_test_cases.push_back(test_case); 8302 } 8303 } 8304 } 8305 8306 /** Get name of glsl constant 8307 * 8308 * @param Constant id 8309 * 8310 * @return Name of constant used in GLSL 8311 **/ 8312 const GLchar* GLSLContantImmutablityTest::getConstantName(CONSTANTS constant) 8313 { 8314 const GLchar* name = ""; 8315 8316 switch (constant) 8317 { 8318 case GL_ARB_ENHANCED_LAYOUTS: 8319 name = "GL_ARB_enhanced_layouts"; 8320 break; 8321 case GL_MAX_XFB: 8322 name = "gl_MaxTransformFeedbackBuffers"; 8323 break; 8324 case GL_MAX_XFB_INT_COMP: 8325 name = "gl_MaxTransformFeedbackInterleavedComponents"; 8326 break; 8327 default: 8328 TCU_FAIL("Invalid enum"); 8329 } 8330 8331 return name; 8332 } 8333 8334 /** Constructor 8335 * 8336 * @param context Test framework context 8337 **/ 8338 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context& context) 8339 : TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols") 8340 { 8341 } 8342 8343 /** Selects if "compute" stage is relevant for test 8344 * 8345 * @param ignored 8346 * 8347 * @return false 8348 **/ 8349 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */) 8350 { 8351 return false; 8352 } 8353 8354 /** Prepare code snippet that will verify in and uniform variables 8355 * 8356 * @param ignored 8357 * @param ignored 8358 * @param stage Shader stage 8359 * 8360 * @return Code that verify variables 8361 **/ 8362 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */, 8363 Utils::ProgramInterface& /* program_interface */, 8364 Utils::Shader::STAGES stage) 8365 { 8366 /* Get constants */ 8367 const Functions& gl = m_context.getRenderContext().getFunctions(); 8368 8369 GLint max_transform_feedback_buffers = 0; 8370 GLint max_transform_feedback_interleaved_components = 0; 8371 8372 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers); 8373 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 8374 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components); 8375 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 8376 8377 std::string verification; 8378 8379 if (Utils::Shader::VERTEX == stage) 8380 { 8381 verification = "if (1 != GL_ARB_enhanced_layouts)\n" 8382 " {\n" 8383 " result = 0;\n" 8384 " }\n" 8385 " else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n" 8386 " != gl_MaxTransformFeedbackBuffers)\n" 8387 " {\n" 8388 " result = 0;\n" 8389 " }\n" 8390 " else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n" 8391 " != gl_MaxTransformFeedbackInterleavedComponents)\n" 8392 " {\n" 8393 " result = 0;\n" 8394 " }\n"; 8395 8396 size_t position = 0; 8397 GLchar buffer[16]; 8398 8399 sprintf(buffer, "%d", max_transform_feedback_buffers); 8400 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification); 8401 8402 sprintf(buffer, "%d", max_transform_feedback_interleaved_components); 8403 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification); 8404 } 8405 else 8406 { 8407 verification = ""; 8408 } 8409 8410 return verification; 8411 } 8412 8413 /** Constructor 8414 * 8415 * @param context Test framework context 8416 **/ 8417 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context& context) 8418 : TextureTestBase(context, "glsl_constant_integral_expression", 8419 "Test verifies that symbols can be used as constant integral expressions") 8420 { 8421 } 8422 8423 /** Get interface of program 8424 * 8425 * @param ignored 8426 * @param program_interface Interface of program 8427 * @param ignored 8428 **/ 8429 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */, 8430 Utils::ProgramInterface& program_interface, 8431 Utils::VaryingPassthrough& /* varying_passthrough */) 8432 { 8433 /* Get constants */ 8434 const Functions& gl = m_context.getRenderContext().getFunctions(); 8435 8436 GLint max_transform_feedback_buffers = 0; 8437 GLint max_transform_feedback_interleaved_components = 0; 8438 8439 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers); 8440 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 8441 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components); 8442 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 8443 8444 GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16); 8445 GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16); 8446 8447 m_gohan_length = max_transform_feedback_buffers / gohan_div; 8448 m_goten_length = max_transform_feedback_interleaved_components / goten_div; 8449 8450 /* Globals */ 8451 std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n" 8452 "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n" 8453 "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n"; 8454 8455 size_t position = 0; 8456 GLchar buffer[16]; 8457 8458 sprintf(buffer, "%d", gohan_div); 8459 Utils::replaceToken("GOHAN_DIV", position, buffer, globals); 8460 8461 sprintf(buffer, "%d", goten_div); 8462 Utils::replaceToken("GOTEN_DIV", position, buffer, globals); 8463 8464 program_interface.m_vertex.m_globals = globals; 8465 program_interface.m_tess_ctrl.m_globals = globals; 8466 program_interface.m_tess_eval.m_globals = globals; 8467 program_interface.m_geometry.m_globals = globals; 8468 program_interface.m_fragment.m_globals = globals; 8469 program_interface.m_compute.m_globals = globals; 8470 } 8471 8472 /** Prepare code snippet that will verify in and uniform variables 8473 * 8474 * @param ignored 8475 * @param ignored 8476 * @param ignored 8477 * 8478 * @return Code that verify variables 8479 **/ 8480 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(GLuint /* test_case_index */, 8481 Utils::ProgramInterface& /* program_interface */, 8482 Utils::Shader::STAGES /* stage */) 8483 { 8484 std::string verification = "{\n" 8485 " uint goku_sum = 0;\n" 8486 " uint gohan_sum = 0;\n" 8487 " uint goten_sum = 0;\n" 8488 "\n" 8489 " for (uint i = 0u; i < goku.length(); ++i)\n" 8490 " {\n" 8491 " goku_sum += goku[i];\n" 8492 " }\n" 8493 "\n" 8494 " for (uint i = 0u; i < gohan.length(); ++i)\n" 8495 " {\n" 8496 " gohan_sum += gohan[i];\n" 8497 " }\n" 8498 "\n" 8499 " for (uint i = 0u; i < goten.length(); ++i)\n" 8500 " {\n" 8501 " goten_sum += goten[i];\n" 8502 " }\n" 8503 "\n" 8504 " if ( (1u != goku_sum) &&\n" 8505 " (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n" 8506 " (EXPECTED_GOTEN_SUMu != goten_sum) )\n" 8507 " {\n" 8508 " result = 0u;\n" 8509 " }\n" 8510 " }\n"; 8511 8512 size_t position = 0; 8513 GLchar buffer[16]; 8514 8515 sprintf(buffer, "%d", m_gohan_length); 8516 Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification); 8517 8518 sprintf(buffer, "%d", m_goten_length); 8519 Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification); 8520 8521 return verification; 8522 } 8523 8524 /** Prepare unifroms 8525 * 8526 * @param ignored 8527 * @param ignored 8528 * @param program Program object 8529 * @param ignored 8530 **/ 8531 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */, 8532 Utils::ProgramInterface& /* program_interface */, 8533 Utils::Program& program, Utils::Buffer& /* cs_buffer */) 8534 { 8535 static const GLuint uniform_data[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; 8536 8537 const Functions& gl = m_context.getRenderContext().getFunctions(); 8538 8539 GLint goku_location = program.GetUniformLocation("goku"); 8540 GLint gohan_location = program.GetUniformLocation("gohan"); 8541 GLint goten_location = program.GetUniformLocation("goten"); 8542 8543 program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data); 8544 program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data); 8545 program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data); 8546 } 8547 8548 /** Prepare unifroms 8549 * 8550 * @param test_case_index Pass as param to first implemetnation 8551 * @param program_interface Pass as param to first implemetnation 8552 * @param program Pass as param to first implemetnation 8553 * @param ignored 8554 * @param ignored 8555 * @param ignored 8556 * @param ignored 8557 * @param vs_buffer Pass as param to first implemetnation 8558 **/ 8559 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint test_case_index, 8560 Utils::ProgramInterface& program_interface, 8561 Utils::Program& program, Utils::Buffer& /* fs_buffer */, 8562 Utils::Buffer& /* gs_buffer */, 8563 Utils::Buffer& /* tcs_buffer */, 8564 Utils::Buffer& /* tes_buffer */, Utils::Buffer& vs_buffer) 8565 { 8566 /* Call first implementation */ 8567 prepareUniforms(test_case_index, program_interface, program, vs_buffer); 8568 } 8569 8570 /** Constructor 8571 * 8572 * @param context Test framework context 8573 **/ 8574 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context& context) 8575 : TextureTestBase(context, "uniform_block_member_offset_and_align", 8576 "Test verifies offsets and alignment of uniform buffer members") 8577 { 8578 } 8579 8580 /** Get interface of program 8581 * 8582 * @param test_case_index Test case index 8583 * @param program_interface Interface of program 8584 * @param varying_passthrough Collection of connections between in and out variables 8585 **/ 8586 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index, 8587 Utils::ProgramInterface& program_interface, 8588 Utils::VaryingPassthrough& varying_passthrough) 8589 { 8590 std::string globals = "const int basic_size = BASIC_SIZE;\n" 8591 "const int type_align = TYPE_ALIGN;\n" 8592 "const int type_size = TYPE_SIZE;\n"; 8593 8594 Utils::Type type = getType(test_case_index); 8595 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type); 8596 const GLuint base_align = type.GetBaseAlignment(false); 8597 const GLuint array_align = type.GetBaseAlignment(true); 8598 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0); 8599 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride); 8600 8601 /* Calculate offsets */ 8602 const GLuint first_offset = 0; 8603 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2); 8604 8605 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST 8606 8607 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align); 8608 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align); 8609 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align); 8610 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align); 8611 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align); 8612 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align); 8613 8614 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */ 8615 8616 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align); 8617 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align); 8618 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align); 8619 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align); 8620 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align); 8621 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size); 8622 8623 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */ 8624 8625 /* Prepare data */ 8626 const std::vector<GLubyte>& first = type.GenerateData(); 8627 const std::vector<GLubyte>& second = type.GenerateData(); 8628 const std::vector<GLubyte>& third = type.GenerateData(); 8629 const std::vector<GLubyte>& fourth = type.GenerateData(); 8630 8631 m_data.resize(eigth_offset + base_stride); 8632 GLubyte* ptr = &m_data[0]; 8633 memcpy(ptr + first_offset, &first[0], first.size()); 8634 memcpy(ptr + second_offset, &second[0], second.size()); 8635 memcpy(ptr + third_offset, &third[0], third.size()); 8636 memcpy(ptr + fourth_offset, &fourth[0], fourth.size()); 8637 memcpy(ptr + fifth_offset, &fourth[0], fourth.size()); 8638 memcpy(ptr + sixth_offset, &third[0], third.size()); 8639 memcpy(ptr + seventh_offset, &second[0], second.size()); 8640 memcpy(ptr + eigth_offset, &first[0], first.size()); 8641 8642 /* Prepare globals */ 8643 size_t position = 0; 8644 GLchar buffer[16]; 8645 8646 sprintf(buffer, "%d", basic_size); 8647 Utils::replaceToken("BASIC_SIZE", position, buffer, globals); 8648 8649 sprintf(buffer, "%d", type_align); 8650 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals); 8651 8652 sprintf(buffer, "%d", base_stride); 8653 Utils::replaceToken("TYPE_SIZE", position, buffer, globals); 8654 8655 /* Prepare Block */ 8656 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block"); 8657 8658 vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */, 8659 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 8660 first_offset); 8661 8662 vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)", 8663 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */, 8664 0 /* n_array_elements */, base_stride, second_offset); 8665 8666 vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */, 8667 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 8668 third_offset); 8669 8670 vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */, 8671 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 8672 fourth_offset); 8673 8674 vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type, 8675 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset); 8676 8677 vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type, 8678 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset); 8679 8680 vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */, 8681 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 8682 eigth_offset); 8683 8684 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 8685 8686 /* Add globals */ 8687 vs_si.m_globals = globals; 8688 8689 /* Add uniform BLOCK */ 8690 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0, 8691 static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size()); 8692 8693 /* */ 8694 program_interface.CloneVertexInterface(varying_passthrough); 8695 } 8696 8697 /** Get type name 8698 * 8699 * @param test_case_index Index of test case 8700 * 8701 * @return Name of type test in test_case_index 8702 **/ 8703 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index) 8704 { 8705 return getTypeName(test_case_index); 8706 } 8707 8708 /** Returns number of types to test 8709 * 8710 * @return Number of types, 34 8711 **/ 8712 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber() 8713 { 8714 return getTypesNumber(); 8715 } 8716 8717 /** Prepare code snippet that will verify in and uniform variables 8718 * 8719 * @param ignored 8720 * @param ignored 8721 * @param stage Shader stage 8722 * 8723 * @return Code that verify variables 8724 **/ 8725 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet( 8726 GLuint /* test_case_index */, Utils::ProgramInterface& /* program_interface */, Utils::Shader::STAGES stage) 8727 { 8728 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n" 8729 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n" 8730 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n" 8731 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n" 8732 " {\n" 8733 " result = 0;\n" 8734 " }"; 8735 8736 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM); 8737 8738 Utils::replaceAllTokens("PREFIX", prefix, verification); 8739 8740 return verification; 8741 } 8742 8743 /** Constructor 8744 * 8745 * @param context Test framework context 8746 **/ 8747 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context& context) 8748 : NegativeTestBase( 8749 context, "uniform_block_layout_qualifier_conflict", 8750 "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block") 8751 { 8752 /* Nothing to be done here */ 8753 } 8754 8755 /** Source for given test case and stage 8756 * 8757 * @param test_case_index Index of test case 8758 * @param stage Shader stage 8759 * 8760 * @return Shader source 8761 **/ 8762 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, 8763 Utils::Shader::STAGES stage) 8764 { 8765 static const GLchar* cs = "#version 430 core\n" 8766 "#extension GL_ARB_enhanced_layouts : require\n" 8767 "\n" 8768 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 8769 "\n" 8770 "LAYOUTuniform Block {\n" 8771 " layout(offset = 16) vec4 boy;\n" 8772 " layout(align = 64) vec4 man;\n" 8773 "} uni_block;\n" 8774 "\n" 8775 "writeonly uniform image2D uni_image;\n" 8776 "\n" 8777 "void main()\n" 8778 "{\n" 8779 " vec4 result = uni_block.boy + uni_block.man;\n" 8780 "\n" 8781 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 8782 "}\n" 8783 "\n"; 8784 static const GLchar* fs = "#version 430 core\n" 8785 "#extension GL_ARB_enhanced_layouts : require\n" 8786 "\n" 8787 "LAYOUTuniform Block {\n" 8788 " layout(offset = 16) vec4 boy;\n" 8789 " layout(align = 64) vec4 man;\n" 8790 "} uni_block;\n" 8791 "\n" 8792 "in vec4 gs_fs;\n" 8793 "out vec4 fs_out;\n" 8794 "\n" 8795 "void main()\n" 8796 "{\n" 8797 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n" 8798 "}\n" 8799 "\n"; 8800 static const GLchar* gs = "#version 430 core\n" 8801 "#extension GL_ARB_enhanced_layouts : require\n" 8802 "\n" 8803 "layout(points) in;\n" 8804 "layout(triangle_strip, max_vertices = 4) out;\n" 8805 "\n" 8806 "LAYOUTuniform Block {\n" 8807 " layout(offset = 16) vec4 boy;\n" 8808 " layout(align = 64) vec4 man;\n" 8809 "} uni_block;\n" 8810 "\n" 8811 "in vec4 tes_gs[];\n" 8812 "out vec4 gs_fs;\n" 8813 "\n" 8814 "void main()\n" 8815 "{\n" 8816 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 8817 " gl_Position = vec4(-1, -1, 0, 1);\n" 8818 " EmitVertex();\n" 8819 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 8820 " gl_Position = vec4(-1, 1, 0, 1);\n" 8821 " EmitVertex();\n" 8822 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 8823 " gl_Position = vec4(1, -1, 0, 1);\n" 8824 " EmitVertex();\n" 8825 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 8826 " gl_Position = vec4(1, 1, 0, 1);\n" 8827 " EmitVertex();\n" 8828 "}\n" 8829 "\n"; 8830 static const GLchar* tcs = 8831 "#version 430 core\n" 8832 "#extension GL_ARB_enhanced_layouts : require\n" 8833 "\n" 8834 "layout(vertices = 1) out;\n" 8835 "\n" 8836 "LAYOUTuniform Block {\n" 8837 " layout(offset = 16) vec4 boy;\n" 8838 " layout(align = 64) vec4 man;\n" 8839 "} uni_block;\n" 8840 "\n" 8841 "in vec4 vs_tcs[];\n" 8842 "out vec4 tcs_tes[];\n" 8843 "\n" 8844 "void main()\n" 8845 "{\n" 8846 "\n" 8847 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n" 8848 "\n" 8849 " gl_TessLevelOuter[0] = 1.0;\n" 8850 " gl_TessLevelOuter[1] = 1.0;\n" 8851 " gl_TessLevelOuter[2] = 1.0;\n" 8852 " gl_TessLevelOuter[3] = 1.0;\n" 8853 " gl_TessLevelInner[0] = 1.0;\n" 8854 " gl_TessLevelInner[1] = 1.0;\n" 8855 "}\n" 8856 "\n"; 8857 static const GLchar* tes = "#version 430 core\n" 8858 "#extension GL_ARB_enhanced_layouts : require\n" 8859 "\n" 8860 "layout(isolines, point_mode) in;\n" 8861 "\n" 8862 "LAYOUTuniform Block {\n" 8863 " layout(offset = 16) vec4 boy;\n" 8864 " layout(align = 64) vec4 man;\n" 8865 "} uni_block;\n" 8866 "\n" 8867 "in vec4 tcs_tes[];\n" 8868 "out vec4 tes_gs;\n" 8869 "\n" 8870 "void main()\n" 8871 "{\n" 8872 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n" 8873 "}\n" 8874 "\n"; 8875 static const GLchar* vs = "#version 430 core\n" 8876 "#extension GL_ARB_enhanced_layouts : require\n" 8877 "\n" 8878 "LAYOUTuniform Block {\n" 8879 " layout(offset = 16) vec4 boy;\n" 8880 " layout(align = 64) vec4 man;\n" 8881 "} uni_block;\n" 8882 "\n" 8883 "in vec4 in_vs;\n" 8884 "out vec4 vs_tcs;\n" 8885 "\n" 8886 "void main()\n" 8887 "{\n" 8888 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n" 8889 "}\n" 8890 "\n"; 8891 8892 std::string layout = ""; 8893 size_t position = 0; 8894 testCase& test_case = m_test_cases[test_case_index]; 8895 const GLchar* qualifier = getQualifierName(test_case.m_qualifier); 8896 std::string source; 8897 8898 if (0 != qualifier[0]) 8899 { 8900 size_t layout_position = 0; 8901 8902 layout = "layout (QUALIFIER) "; 8903 8904 Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout); 8905 } 8906 8907 switch (stage) 8908 { 8909 case Utils::Shader::COMPUTE: 8910 source = cs; 8911 break; 8912 case Utils::Shader::FRAGMENT: 8913 source = fs; 8914 break; 8915 case Utils::Shader::GEOMETRY: 8916 source = gs; 8917 break; 8918 case Utils::Shader::TESS_CTRL: 8919 source = tcs; 8920 break; 8921 case Utils::Shader::TESS_EVAL: 8922 source = tes; 8923 break; 8924 case Utils::Shader::VERTEX: 8925 source = vs; 8926 break; 8927 default: 8928 TCU_FAIL("Invalid enum"); 8929 } 8930 8931 if (test_case.m_stage == stage) 8932 { 8933 Utils::replaceToken("LAYOUT", position, layout.c_str(), source); 8934 } 8935 else 8936 { 8937 Utils::replaceToken("LAYOUT", position, "layout (std140) ", source); 8938 } 8939 8940 return source; 8941 } 8942 8943 /** Get description of test case 8944 * 8945 * @param test_case_index Index of test case 8946 * 8947 * @return Qualifier name 8948 **/ 8949 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index) 8950 { 8951 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier); 8952 8953 return result; 8954 } 8955 8956 /** Get number of test cases 8957 * 8958 * @return Number of test cases 8959 **/ 8960 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber() 8961 { 8962 return static_cast<GLuint>(m_test_cases.size()); 8963 } 8964 8965 /** Selects if "compute" stage is relevant for test 8966 * 8967 * @param test_case_index Index of test case 8968 * 8969 * @return true when tested stage is compute 8970 **/ 8971 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index) 8972 { 8973 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage); 8974 } 8975 8976 /** Selects if compilation failure is expected result 8977 * 8978 * @param test_case_index Index of test case 8979 * 8980 * @return false for STD140 cases, true otherwise 8981 **/ 8982 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index) 8983 { 8984 return (STD140 != m_test_cases[test_case_index].m_qualifier); 8985 } 8986 8987 /** Prepare all test cases 8988 * 8989 **/ 8990 void UniformBlockLayoutQualifierConflictTest::testInit() 8991 { 8992 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier) 8993 { 8994 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 8995 { 8996 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage }; 8997 8998 m_test_cases.push_back(test_case); 8999 } 9000 } 9001 } 9002 9003 /** Get name of glsl constant 9004 * 9005 * @param Constant id 9006 * 9007 * @return Name of constant used in GLSL 9008 **/ 9009 const GLchar* UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier) 9010 { 9011 const GLchar* name = ""; 9012 9013 switch (qualifier) 9014 { 9015 case DEFAULT: 9016 name = ""; 9017 break; 9018 case STD140: 9019 name = "std140"; 9020 break; 9021 case SHARED: 9022 name = "shared"; 9023 break; 9024 case PACKED: 9025 name = "packed"; 9026 break; 9027 default: 9028 TCU_FAIL("Invalid enum"); 9029 } 9030 9031 return name; 9032 } 9033 9034 /** Constructor 9035 * 9036 * @param context Test framework context 9037 **/ 9038 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context) 9039 : NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment", 9040 "Test verifies that invalid alignment of offset qualifiers cause compilation failure") 9041 { 9042 /* Nothing to be done here */ 9043 } 9044 9045 /** Constructor 9046 * 9047 * @param context Test framework context 9048 * @param name Test name 9049 * @param description Test description 9050 **/ 9051 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest( 9052 deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description) 9053 : NegativeTestBase(context, name, description) 9054 { 9055 /* Nothing to be done here */ 9056 } 9057 9058 /** Source for given test case and stage 9059 * 9060 * @param test_case_index Index of test case 9061 * @param stage Shader stage 9062 * 9063 * @return Shader source 9064 **/ 9065 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, 9066 Utils::Shader::STAGES stage) 9067 { 9068 static const GLchar* cs = "#version 430 core\n" 9069 "#extension GL_ARB_enhanced_layouts : require\n" 9070 "\n" 9071 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 9072 "\n" 9073 "layout (std140) uniform Block {\n" 9074 " layout (offset = OFFSET) TYPE member;\n" 9075 "} block;\n" 9076 "\n" 9077 "writeonly uniform image2D uni_image;\n" 9078 "\n" 9079 "void main()\n" 9080 "{\n" 9081 " vec4 result = vec4(1, 0, 0.5, 1);\n" 9082 "\n" 9083 " if (TYPE(1) == block.member)\n" 9084 " {\n" 9085 " result = vec4(1, 1, 1, 1);\n" 9086 " }\n" 9087 "\n" 9088 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 9089 "}\n" 9090 "\n"; 9091 static const GLchar* fs = "#version 430 core\n" 9092 "#extension GL_ARB_enhanced_layouts : require\n" 9093 "\n" 9094 "in vec4 gs_fs;\n" 9095 "out vec4 fs_out;\n" 9096 "\n" 9097 "void main()\n" 9098 "{\n" 9099 " fs_out = gs_fs;\n" 9100 "}\n" 9101 "\n"; 9102 static const GLchar* fs_tested = "#version 430 core\n" 9103 "#extension GL_ARB_enhanced_layouts : require\n" 9104 "\n" 9105 "layout (std140) uniform Block {\n" 9106 " layout (offset = OFFSET) TYPE member;\n" 9107 "} block;\n" 9108 "\n" 9109 "in vec4 gs_fs;\n" 9110 "out vec4 fs_out;\n" 9111 "\n" 9112 "void main()\n" 9113 "{\n" 9114 " if (TYPE(1) == block.member)\n" 9115 " {\n" 9116 " fs_out = vec4(1, 1, 1, 1);\n" 9117 " }\n" 9118 "\n" 9119 " fs_out += gs_fs;\n" 9120 "}\n" 9121 "\n"; 9122 static const GLchar* gs = "#version 430 core\n" 9123 "#extension GL_ARB_enhanced_layouts : require\n" 9124 "\n" 9125 "layout(points) in;\n" 9126 "layout(triangle_strip, max_vertices = 4) out;\n" 9127 "\n" 9128 "in vec4 tes_gs[];\n" 9129 "out vec4 gs_fs;\n" 9130 "\n" 9131 "void main()\n" 9132 "{\n" 9133 " gs_fs = tes_gs[0];\n" 9134 " gl_Position = vec4(-1, -1, 0, 1);\n" 9135 " EmitVertex();\n" 9136 " gs_fs = tes_gs[0];\n" 9137 " gl_Position = vec4(-1, 1, 0, 1);\n" 9138 " EmitVertex();\n" 9139 " gs_fs = tes_gs[0];\n" 9140 " gl_Position = vec4(1, -1, 0, 1);\n" 9141 " EmitVertex();\n" 9142 " gs_fs = tes_gs[0];\n" 9143 " gl_Position = vec4(1, 1, 0, 1);\n" 9144 " EmitVertex();\n" 9145 "}\n" 9146 "\n"; 9147 static const GLchar* gs_tested = "#version 430 core\n" 9148 "#extension GL_ARB_enhanced_layouts : require\n" 9149 "\n" 9150 "layout(points) in;\n" 9151 "layout(triangle_strip, max_vertices = 4) out;\n" 9152 "\n" 9153 "layout (std140) uniform Block {\n" 9154 " layout (offset = OFFSET) TYPE member;\n" 9155 "} block;\n" 9156 "\n" 9157 "in vec4 tes_gs[];\n" 9158 "out vec4 gs_fs;\n" 9159 "\n" 9160 "void main()\n" 9161 "{\n" 9162 " if (TYPE(1) == block.member)\n" 9163 " {\n" 9164 " gs_fs = vec4(1, 1, 1, 1);\n" 9165 " }\n" 9166 "\n" 9167 " gs_fs += tes_gs[0];\n" 9168 " gl_Position = vec4(-1, -1, 0, 1);\n" 9169 " EmitVertex();\n" 9170 " gs_fs += tes_gs[0];\n" 9171 " gl_Position = vec4(-1, 1, 0, 1);\n" 9172 " EmitVertex();\n" 9173 " gs_fs += tes_gs[0];\n" 9174 " gl_Position = vec4(1, -1, 0, 1);\n" 9175 " EmitVertex();\n" 9176 " gs_fs += tes_gs[0];\n" 9177 " gl_Position = vec4(1, 1, 0, 1);\n" 9178 " EmitVertex();\n" 9179 "}\n" 9180 "\n"; 9181 static const GLchar* tcs = "#version 430 core\n" 9182 "#extension GL_ARB_enhanced_layouts : require\n" 9183 "\n" 9184 "layout(vertices = 1) out;\n" 9185 "\n" 9186 "in vec4 vs_tcs[];\n" 9187 "out vec4 tcs_tes[];\n" 9188 "\n" 9189 "void main()\n" 9190 "{\n" 9191 "\n" 9192 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 9193 "\n" 9194 " gl_TessLevelOuter[0] = 1.0;\n" 9195 " gl_TessLevelOuter[1] = 1.0;\n" 9196 " gl_TessLevelOuter[2] = 1.0;\n" 9197 " gl_TessLevelOuter[3] = 1.0;\n" 9198 " gl_TessLevelInner[0] = 1.0;\n" 9199 " gl_TessLevelInner[1] = 1.0;\n" 9200 "}\n" 9201 "\n"; 9202 static const GLchar* tcs_tested = "#version 430 core\n" 9203 "#extension GL_ARB_enhanced_layouts : require\n" 9204 "\n" 9205 "layout(vertices = 1) out;\n" 9206 "\n" 9207 "layout (std140) uniform Block {\n" 9208 " layout (offset = OFFSET) TYPE member;\n" 9209 "} block;\n" 9210 "\n" 9211 "in vec4 vs_tcs[];\n" 9212 "out vec4 tcs_tes[];\n" 9213 "\n" 9214 "void main()\n" 9215 "{\n" 9216 " if (TYPE(1) == block.member)\n" 9217 " {\n" 9218 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n" 9219 " }\n" 9220 "\n" 9221 "\n" 9222 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n" 9223 "\n" 9224 " gl_TessLevelOuter[0] = 1.0;\n" 9225 " gl_TessLevelOuter[1] = 1.0;\n" 9226 " gl_TessLevelOuter[2] = 1.0;\n" 9227 " gl_TessLevelOuter[3] = 1.0;\n" 9228 " gl_TessLevelInner[0] = 1.0;\n" 9229 " gl_TessLevelInner[1] = 1.0;\n" 9230 "}\n" 9231 "\n"; 9232 static const GLchar* tes = "#version 430 core\n" 9233 "#extension GL_ARB_enhanced_layouts : require\n" 9234 "\n" 9235 "layout(isolines, point_mode) in;\n" 9236 "\n" 9237 "in vec4 tcs_tes[];\n" 9238 "out vec4 tes_gs;\n" 9239 "\n" 9240 "void main()\n" 9241 "{\n" 9242 " tes_gs = tcs_tes[0];\n" 9243 "}\n" 9244 "\n"; 9245 static const GLchar* tes_tested = "#version 430 core\n" 9246 "#extension GL_ARB_enhanced_layouts : require\n" 9247 "\n" 9248 "layout(isolines, point_mode) in;\n" 9249 "\n" 9250 "layout (std140) uniform Block {\n" 9251 " layout (offset = OFFSET) TYPE member;\n" 9252 "} block;\n" 9253 "\n" 9254 "in vec4 tcs_tes[];\n" 9255 "out vec4 tes_gs;\n" 9256 "\n" 9257 "void main()\n" 9258 "{\n" 9259 " if (TYPE(1) == block.member)\n" 9260 " {\n" 9261 " tes_gs = vec4(1, 1, 1, 1);\n" 9262 " }\n" 9263 "\n" 9264 " tes_gs += tcs_tes[0];\n" 9265 "}\n" 9266 "\n"; 9267 static const GLchar* vs = "#version 430 core\n" 9268 "#extension GL_ARB_enhanced_layouts : require\n" 9269 "\n" 9270 "in vec4 in_vs;\n" 9271 "out vec4 vs_tcs;\n" 9272 "\n" 9273 "void main()\n" 9274 "{\n" 9275 " vs_tcs = in_vs;\n" 9276 "}\n" 9277 "\n"; 9278 static const GLchar* vs_tested = "#version 430 core\n" 9279 "#extension GL_ARB_enhanced_layouts : require\n" 9280 "\n" 9281 "layout (std140) uniform Block {\n" 9282 " layout (offset = OFFSET) TYPE member;\n" 9283 "} block;\n" 9284 "\n" 9285 "in vec4 in_vs;\n" 9286 "out vec4 vs_tcs;\n" 9287 "\n" 9288 "void main()\n" 9289 "{\n" 9290 " if (TYPE(1) == block.member)\n" 9291 " {\n" 9292 " vs_tcs = vec4(1, 1, 1, 1);\n" 9293 " }\n" 9294 "\n" 9295 " vs_tcs += in_vs;\n" 9296 "}\n" 9297 "\n"; 9298 9299 std::string source; 9300 testCase& test_case = m_test_cases[test_case_index]; 9301 9302 if (test_case.m_stage == stage) 9303 { 9304 GLchar buffer[16]; 9305 const GLuint offset = test_case.m_offset; 9306 size_t position = 0; 9307 const Utils::Type& type = test_case.m_type; 9308 const GLchar* type_name = type.GetGLSLTypeName(); 9309 9310 sprintf(buffer, "%d", offset); 9311 9312 switch (stage) 9313 { 9314 case Utils::Shader::COMPUTE: 9315 source = cs; 9316 break; 9317 case Utils::Shader::FRAGMENT: 9318 source = fs_tested; 9319 break; 9320 case Utils::Shader::GEOMETRY: 9321 source = gs_tested; 9322 break; 9323 case Utils::Shader::TESS_CTRL: 9324 source = tcs_tested; 9325 break; 9326 case Utils::Shader::TESS_EVAL: 9327 source = tes_tested; 9328 break; 9329 case Utils::Shader::VERTEX: 9330 source = vs_tested; 9331 break; 9332 default: 9333 TCU_FAIL("Invalid enum"); 9334 } 9335 9336 Utils::replaceToken("OFFSET", position, buffer, source); 9337 Utils::replaceToken("TYPE", position, type_name, source); 9338 Utils::replaceToken("TYPE", position, type_name, source); 9339 } 9340 else 9341 { 9342 switch (stage) 9343 { 9344 case Utils::Shader::FRAGMENT: 9345 source = fs; 9346 break; 9347 case Utils::Shader::GEOMETRY: 9348 source = gs; 9349 break; 9350 case Utils::Shader::TESS_CTRL: 9351 source = tcs; 9352 break; 9353 case Utils::Shader::TESS_EVAL: 9354 source = tes; 9355 break; 9356 case Utils::Shader::VERTEX: 9357 source = vs; 9358 break; 9359 default: 9360 TCU_FAIL("Invalid enum"); 9361 } 9362 } 9363 9364 return source; 9365 } 9366 9367 /** Get description of test case 9368 * 9369 * @param test_case_index Index of test case 9370 * 9371 * @return Type name and offset 9372 **/ 9373 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index) 9374 { 9375 std::stringstream stream; 9376 testCase& test_case = m_test_cases[test_case_index]; 9377 9378 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset; 9379 9380 return stream.str(); 9381 } 9382 9383 /** Get number of test cases 9384 * 9385 * @return Number of test cases 9386 **/ 9387 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber() 9388 { 9389 return static_cast<GLuint>(m_test_cases.size()); 9390 } 9391 9392 /** Get the maximum size for an uniform block 9393 * 9394 * @return The maximum size in basic machine units of a uniform block. 9395 **/ 9396 GLint UniformBlockMemberInvalidOffsetAlignmentTest::getMaxBlockSize() 9397 { 9398 const Functions& gl = m_context.getRenderContext().getFunctions(); 9399 GLint max_size = 0; 9400 9401 gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size); 9402 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 9403 9404 return max_size; 9405 } 9406 9407 /** Selects if "compute" stage is relevant for test 9408 * 9409 * @param test_case_index Index of test case 9410 * 9411 * @return true when tested stage is compute 9412 **/ 9413 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index) 9414 { 9415 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage); 9416 } 9417 9418 /** Selects if compilation failure is expected result 9419 * 9420 * @param test_case_index Index of test case 9421 * 9422 * @return should_fail field from testCase 9423 **/ 9424 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index) 9425 { 9426 return m_test_cases[test_case_index].m_should_fail; 9427 } 9428 9429 /** Checks if stage is supported 9430 * 9431 * @param stage ignored 9432 * 9433 * @return true 9434 **/ 9435 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */) 9436 { 9437 return true; 9438 } 9439 9440 /** Prepare all test cases 9441 * 9442 **/ 9443 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit() 9444 { 9445 const GLuint n_types = getTypesNumber(); 9446 bool stage_support[Utils::Shader::STAGE_MAX]; 9447 9448 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 9449 { 9450 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage); 9451 } 9452 9453 for (GLuint i = 0; i < n_types; ++i) 9454 { 9455 const Utils::Type& type = getType(i); 9456 const GLuint alignment = type.GetBaseAlignment(false); 9457 const GLuint type_size = type.GetSize(true); 9458 const GLuint sec_to_end = getMaxBlockSize() - 2 * type_size; 9459 9460 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 9461 { 9462 if (false == stage_support[stage]) 9463 { 9464 continue; 9465 } 9466 9467 for (GLuint offset = 0; offset <= type_size; ++offset) 9468 { 9469 const GLuint modulo = offset % alignment; 9470 const bool is_aligned = (0 == modulo) ? true : false; 9471 const bool should_fail = !is_aligned; 9472 9473 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type }; 9474 9475 m_test_cases.push_back(test_case); 9476 } 9477 9478 for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset) 9479 { 9480 const GLuint modulo = offset % alignment; 9481 const bool is_aligned = (0 == modulo) ? true : false; 9482 const bool should_fail = !is_aligned; 9483 9484 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type }; 9485 9486 m_test_cases.push_back(test_case); 9487 } 9488 } 9489 } 9490 } 9491 9492 /** Constructor 9493 * 9494 * @param context Test framework context 9495 **/ 9496 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context) 9497 : NegativeTestBase(context, "uniform_block_member_overlapping_offsets", 9498 "Test verifies that overlapping offsets qualifiers cause compilation failure") 9499 { 9500 /* Nothing to be done here */ 9501 } 9502 9503 /** Constructor 9504 * 9505 * @param context Test framework context 9506 * @param name Test name 9507 * @param description Test description 9508 **/ 9509 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context, 9510 const glw::GLchar* name, 9511 const glw::GLchar* description) 9512 : NegativeTestBase(context, name, description) 9513 { 9514 /* Nothing to be done here */ 9515 } 9516 9517 /** Source for given test case and stage 9518 * 9519 * @param test_case_index Index of test case 9520 * @param stage Shader stage 9521 * 9522 * @return Shader source 9523 **/ 9524 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, 9525 Utils::Shader::STAGES stage) 9526 { 9527 static const GLchar* cs = "#version 430 core\n" 9528 "#extension GL_ARB_enhanced_layouts : require\n" 9529 "\n" 9530 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 9531 "\n" 9532 "layout (std140) uniform Block {\n" 9533 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 9534 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 9535 "} block;\n" 9536 "\n" 9537 "writeonly uniform image2D uni_image;\n" 9538 "\n" 9539 "void main()\n" 9540 "{\n" 9541 " vec4 result = vec4(1, 0, 0.5, 1);\n" 9542 "\n" 9543 " if ((BOY_TYPE(1) == block.boy) ||\n" 9544 " (MAN_TYPE(0) == block.man) )\n" 9545 " {\n" 9546 " result = vec4(1, 1, 1, 1);\n" 9547 " }\n" 9548 "\n" 9549 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 9550 "}\n" 9551 "\n"; 9552 static const GLchar* fs = "#version 430 core\n" 9553 "#extension GL_ARB_enhanced_layouts : require\n" 9554 "\n" 9555 "in vec4 gs_fs;\n" 9556 "out vec4 fs_out;\n" 9557 "\n" 9558 "void main()\n" 9559 "{\n" 9560 " fs_out = gs_fs;\n" 9561 "}\n" 9562 "\n"; 9563 static const GLchar* fs_tested = "#version 430 core\n" 9564 "#extension GL_ARB_enhanced_layouts : require\n" 9565 "\n" 9566 "layout (std140) uniform Block {\n" 9567 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 9568 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 9569 "} block;\n" 9570 "\n" 9571 "in vec4 gs_fs;\n" 9572 "out vec4 fs_out;\n" 9573 "\n" 9574 "void main()\n" 9575 "{\n" 9576 " if ((BOY_TYPE(1) == block.boy) ||\n" 9577 " (MAN_TYPE(0) == block.man) )\n" 9578 " {\n" 9579 " fs_out = vec4(1, 1, 1, 1);\n" 9580 " }\n" 9581 "\n" 9582 " fs_out += gs_fs;\n" 9583 "}\n" 9584 "\n"; 9585 static const GLchar* gs = "#version 430 core\n" 9586 "#extension GL_ARB_enhanced_layouts : require\n" 9587 "\n" 9588 "layout(points) in;\n" 9589 "layout(triangle_strip, max_vertices = 4) out;\n" 9590 "\n" 9591 "in vec4 tes_gs[];\n" 9592 "out vec4 gs_fs;\n" 9593 "\n" 9594 "void main()\n" 9595 "{\n" 9596 " gs_fs = tes_gs[0];\n" 9597 " gl_Position = vec4(-1, -1, 0, 1);\n" 9598 " EmitVertex();\n" 9599 " gs_fs = tes_gs[0];\n" 9600 " gl_Position = vec4(-1, 1, 0, 1);\n" 9601 " EmitVertex();\n" 9602 " gs_fs = tes_gs[0];\n" 9603 " gl_Position = vec4(1, -1, 0, 1);\n" 9604 " EmitVertex();\n" 9605 " gs_fs = tes_gs[0];\n" 9606 " gl_Position = vec4(1, 1, 0, 1);\n" 9607 " EmitVertex();\n" 9608 "}\n" 9609 "\n"; 9610 static const GLchar* gs_tested = "#version 430 core\n" 9611 "#extension GL_ARB_enhanced_layouts : require\n" 9612 "\n" 9613 "layout(points) in;\n" 9614 "layout(triangle_strip, max_vertices = 4) out;\n" 9615 "\n" 9616 "layout (std140) uniform Block {\n" 9617 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 9618 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 9619 "} block;\n" 9620 "\n" 9621 "in vec4 tes_gs[];\n" 9622 "out vec4 gs_fs;\n" 9623 "\n" 9624 "void main()\n" 9625 "{\n" 9626 " if ((BOY_TYPE(1) == block.boy) ||\n" 9627 " (MAN_TYPE(0) == block.man) )\n" 9628 " {\n" 9629 " gs_fs = vec4(1, 1, 1, 1);\n" 9630 " }\n" 9631 "\n" 9632 " gs_fs += tes_gs[0];\n" 9633 " gl_Position = vec4(-1, -1, 0, 1);\n" 9634 " EmitVertex();\n" 9635 " gs_fs += tes_gs[0];\n" 9636 " gl_Position = vec4(-1, 1, 0, 1);\n" 9637 " EmitVertex();\n" 9638 " gs_fs += tes_gs[0];\n" 9639 " gl_Position = vec4(1, -1, 0, 1);\n" 9640 " EmitVertex();\n" 9641 " gs_fs += tes_gs[0];\n" 9642 " gl_Position = vec4(1, 1, 0, 1);\n" 9643 " EmitVertex();\n" 9644 "}\n" 9645 "\n"; 9646 static const GLchar* tcs = "#version 430 core\n" 9647 "#extension GL_ARB_enhanced_layouts : require\n" 9648 "\n" 9649 "layout(vertices = 1) out;\n" 9650 "\n" 9651 "in vec4 vs_tcs[];\n" 9652 "out vec4 tcs_tes[];\n" 9653 "\n" 9654 "void main()\n" 9655 "{\n" 9656 "\n" 9657 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 9658 "\n" 9659 " gl_TessLevelOuter[0] = 1.0;\n" 9660 " gl_TessLevelOuter[1] = 1.0;\n" 9661 " gl_TessLevelOuter[2] = 1.0;\n" 9662 " gl_TessLevelOuter[3] = 1.0;\n" 9663 " gl_TessLevelInner[0] = 1.0;\n" 9664 " gl_TessLevelInner[1] = 1.0;\n" 9665 "}\n" 9666 "\n"; 9667 static const GLchar* tcs_tested = "#version 430 core\n" 9668 "#extension GL_ARB_enhanced_layouts : require\n" 9669 "\n" 9670 "layout(vertices = 1) out;\n" 9671 "\n" 9672 "layout (std140) uniform Block {\n" 9673 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 9674 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 9675 "} block;\n" 9676 "\n" 9677 "in vec4 vs_tcs[];\n" 9678 "out vec4 tcs_tes[];\n" 9679 "\n" 9680 "void main()\n" 9681 "{\n" 9682 " if ((BOY_TYPE(1) == block.boy) ||\n" 9683 " (MAN_TYPE(0) == block.man) )\n" 9684 " {\n" 9685 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n" 9686 " }\n" 9687 "\n" 9688 "\n" 9689 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n" 9690 "\n" 9691 " gl_TessLevelOuter[0] = 1.0;\n" 9692 " gl_TessLevelOuter[1] = 1.0;\n" 9693 " gl_TessLevelOuter[2] = 1.0;\n" 9694 " gl_TessLevelOuter[3] = 1.0;\n" 9695 " gl_TessLevelInner[0] = 1.0;\n" 9696 " gl_TessLevelInner[1] = 1.0;\n" 9697 "}\n" 9698 "\n"; 9699 static const GLchar* tes = "#version 430 core\n" 9700 "#extension GL_ARB_enhanced_layouts : require\n" 9701 "\n" 9702 "layout(isolines, point_mode) in;\n" 9703 "\n" 9704 "in vec4 tcs_tes[];\n" 9705 "out vec4 tes_gs;\n" 9706 "\n" 9707 "void main()\n" 9708 "{\n" 9709 " tes_gs = tcs_tes[0];\n" 9710 "}\n" 9711 "\n"; 9712 static const GLchar* tes_tested = "#version 430 core\n" 9713 "#extension GL_ARB_enhanced_layouts : require\n" 9714 "\n" 9715 "layout(isolines, point_mode) in;\n" 9716 "\n" 9717 "layout (std140) uniform Block {\n" 9718 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 9719 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 9720 "} block;\n" 9721 "\n" 9722 "in vec4 tcs_tes[];\n" 9723 "out vec4 tes_gs;\n" 9724 "\n" 9725 "void main()\n" 9726 "{\n" 9727 " if ((BOY_TYPE(1) == block.boy) ||\n" 9728 " (MAN_TYPE(0) == block.man) )\n" 9729 " {\n" 9730 " tes_gs = vec4(1, 1, 1, 1);\n" 9731 " }\n" 9732 "\n" 9733 " tes_gs += tcs_tes[0];\n" 9734 "}\n" 9735 "\n"; 9736 static const GLchar* vs = "#version 430 core\n" 9737 "#extension GL_ARB_enhanced_layouts : require\n" 9738 "\n" 9739 "in vec4 in_vs;\n" 9740 "out vec4 vs_tcs;\n" 9741 "\n" 9742 "void main()\n" 9743 "{\n" 9744 " vs_tcs = in_vs;\n" 9745 "}\n" 9746 "\n"; 9747 static const GLchar* vs_tested = "#version 430 core\n" 9748 "#extension GL_ARB_enhanced_layouts : require\n" 9749 "\n" 9750 "layout (std140) uniform Block {\n" 9751 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 9752 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 9753 "} block;\n" 9754 "\n" 9755 "in vec4 in_vs;\n" 9756 "out vec4 vs_tcs;\n" 9757 "\n" 9758 "void main()\n" 9759 "{\n" 9760 " if ((BOY_TYPE(1) == block.boy) ||\n" 9761 " (MAN_TYPE(0) == block.man) )\n" 9762 " {\n" 9763 " vs_tcs = vec4(1, 1, 1, 1);\n" 9764 " }\n" 9765 "\n" 9766 " vs_tcs += in_vs;\n" 9767 "}\n" 9768 "\n"; 9769 9770 std::string source; 9771 testCase& test_case = m_test_cases[test_case_index]; 9772 9773 if (test_case.m_stage == stage) 9774 { 9775 GLchar buffer[16]; 9776 const GLuint boy_offset = test_case.m_boy_offset; 9777 const Utils::Type& boy_type = test_case.m_boy_type; 9778 const GLchar* boy_type_name = boy_type.GetGLSLTypeName(); 9779 const GLuint man_offset = test_case.m_man_offset; 9780 const Utils::Type& man_type = test_case.m_man_type; 9781 const GLchar* man_type_name = man_type.GetGLSLTypeName(); 9782 size_t position = 0; 9783 9784 switch (stage) 9785 { 9786 case Utils::Shader::COMPUTE: 9787 source = cs; 9788 break; 9789 case Utils::Shader::FRAGMENT: 9790 source = fs_tested; 9791 break; 9792 case Utils::Shader::GEOMETRY: 9793 source = gs_tested; 9794 break; 9795 case Utils::Shader::TESS_CTRL: 9796 source = tcs_tested; 9797 break; 9798 case Utils::Shader::TESS_EVAL: 9799 source = tes_tested; 9800 break; 9801 case Utils::Shader::VERTEX: 9802 source = vs_tested; 9803 break; 9804 default: 9805 TCU_FAIL("Invalid enum"); 9806 } 9807 9808 sprintf(buffer, "%d", boy_offset); 9809 Utils::replaceToken("BOY_OFFSET", position, buffer, source); 9810 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source); 9811 sprintf(buffer, "%d", man_offset); 9812 Utils::replaceToken("MAN_OFFSET", position, buffer, source); 9813 Utils::replaceToken("MAN_TYPE", position, man_type_name, source); 9814 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source); 9815 Utils::replaceToken("MAN_TYPE", position, man_type_name, source); 9816 } 9817 else 9818 { 9819 switch (stage) 9820 { 9821 case Utils::Shader::FRAGMENT: 9822 source = fs; 9823 break; 9824 case Utils::Shader::GEOMETRY: 9825 source = gs; 9826 break; 9827 case Utils::Shader::TESS_CTRL: 9828 source = tcs; 9829 break; 9830 case Utils::Shader::TESS_EVAL: 9831 source = tes; 9832 break; 9833 case Utils::Shader::VERTEX: 9834 source = vs; 9835 break; 9836 default: 9837 TCU_FAIL("Invalid enum"); 9838 } 9839 } 9840 9841 return source; 9842 } 9843 9844 /** Get description of test case 9845 * 9846 * @param test_case_index Index of test case 9847 * 9848 * @return Type name and offset 9849 **/ 9850 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index) 9851 { 9852 std::stringstream stream; 9853 testCase& test_case = m_test_cases[test_case_index]; 9854 9855 stream << "Type: " << test_case.m_boy_type.GetGLSLTypeName() << ", offset: " << test_case.m_boy_offset 9856 << ". Type: " << test_case.m_man_type.GetGLSLTypeName() << ", offset: " << test_case.m_man_offset; 9857 9858 return stream.str(); 9859 } 9860 9861 /** Get number of test cases 9862 * 9863 * @return Number of test cases 9864 **/ 9865 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber() 9866 { 9867 return static_cast<GLuint>(m_test_cases.size()); 9868 } 9869 9870 /** Selects if "compute" stage is relevant for test 9871 * 9872 * @param test_case_index Index of test case 9873 * 9874 * @return true when tested stage is compute 9875 **/ 9876 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index) 9877 { 9878 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage); 9879 } 9880 9881 /** Checks if stage is supported 9882 * 9883 * @param stage ignored 9884 * 9885 * @return true 9886 **/ 9887 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */) 9888 { 9889 return true; 9890 } 9891 9892 /** Prepare all test cases 9893 * 9894 **/ 9895 void UniformBlockMemberOverlappingOffsetsTest::testInit() 9896 { 9897 const GLuint n_types = getTypesNumber(); 9898 bool stage_support[Utils::Shader::STAGE_MAX]; 9899 9900 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 9901 { 9902 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage); 9903 } 9904 9905 for (GLuint i = 0; i < n_types; ++i) 9906 { 9907 const Utils::Type& boy_type = getType(i); 9908 const GLuint boy_size = boy_type.GetActualAlignment(1 /* align */, false /* is_array*/); 9909 9910 for (GLuint j = 0; j < n_types; ++j) 9911 { 9912 const Utils::Type& man_type = getType(j); 9913 const GLuint man_align = man_type.GetBaseAlignment(false); 9914 const GLuint man_size = man_type.GetActualAlignment(1 /* align */, false /* is_array*/); 9915 9916 const GLuint boy_offset = lcm(boy_size, man_size); 9917 const GLuint man_after_start = boy_offset + 1; 9918 const GLuint man_after_off = man_type.GetActualOffset(man_after_start, man_size); 9919 const GLuint man_before_start = boy_offset - man_align; 9920 const GLuint man_before_off = man_type.GetActualOffset(man_before_start, man_size); 9921 9922 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 9923 { 9924 if (false == stage_support[stage]) 9925 { 9926 continue; 9927 } 9928 9929 if ((boy_offset > man_before_off) && (boy_offset < man_before_off + man_size)) 9930 { 9931 testCase test_case = { boy_offset, boy_type, man_before_off, man_type, 9932 (Utils::Shader::STAGES)stage }; 9933 9934 m_test_cases.push_back(test_case); 9935 } 9936 9937 if ((boy_offset < man_after_off) && (boy_offset + boy_size > man_after_off)) 9938 { 9939 testCase test_case = { boy_offset, boy_type, man_after_off, man_type, 9940 (Utils::Shader::STAGES)stage }; 9941 9942 m_test_cases.push_back(test_case); 9943 } 9944 9945 /* Boy offset, should be fine for both types */ 9946 testCase test_case = { boy_offset, boy_type, boy_offset, man_type, (Utils::Shader::STAGES)stage }; 9947 9948 m_test_cases.push_back(test_case); 9949 } 9950 } 9951 } 9952 } 9953 9954 /** Find greatest common divisor for a and b 9955 * 9956 * @param a A argument 9957 * @param b B argument 9958 * 9959 * @return Found gcd value 9960 **/ 9961 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b) 9962 { 9963 if ((0 != a) && (0 == b)) 9964 { 9965 return a; 9966 } 9967 else 9968 { 9969 GLuint greater = std::max(a, b); 9970 GLuint lesser = std::min(a, b); 9971 9972 return gcd(lesser, greater % lesser); 9973 } 9974 } 9975 9976 /** Find lowest common multiple for a and b 9977 * 9978 * @param a A argument 9979 * @param b B argument 9980 * 9981 * @return Found gcd value 9982 **/ 9983 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b) 9984 { 9985 return (a * b) / gcd(a, b); 9986 } 9987 9988 /** Constructor 9989 * 9990 * @param context Test framework context 9991 **/ 9992 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context) 9993 : NegativeTestBase(context, "uniform_block_member_align_non_power_of_2", 9994 "Test verifies that align qualifier requires value that is a power of 2") 9995 { 9996 /* Nothing to be done here */ 9997 } 9998 9999 /** Constructor 10000 * 10001 * @param context Test framework context 10002 * @param name Test name 10003 * @param description Test description 10004 **/ 10005 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context, 10006 const glw::GLchar* name, 10007 const glw::GLchar* description) 10008 : NegativeTestBase(context, name, description) 10009 { 10010 /* Nothing to be done here */ 10011 } 10012 10013 /** Source for given test case and stage 10014 * 10015 * @param test_case_index Index of test case 10016 * @param stage Shader stage 10017 * 10018 * @return Shader source 10019 **/ 10020 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 10021 { 10022 static const GLchar* cs = "#version 430 core\n" 10023 "#extension GL_ARB_enhanced_layouts : require\n" 10024 "\n" 10025 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 10026 "\n" 10027 "layout (std140) uniform Block {\n" 10028 " vec4 boy;\n" 10029 " layout (align = ALIGN) TYPE man;\n" 10030 "} block;\n" 10031 "\n" 10032 "writeonly uniform image2D uni_image;\n" 10033 "\n" 10034 "void main()\n" 10035 "{\n" 10036 " vec4 result = vec4(1, 0, 0.5, 1);\n" 10037 "\n" 10038 " if (TYPE(0) == block.man)\n" 10039 " {\n" 10040 " result = vec4(1, 1, 1, 1) - block.boy;\n" 10041 " }\n" 10042 "\n" 10043 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 10044 "}\n" 10045 "\n"; 10046 static const GLchar* fs = "#version 430 core\n" 10047 "#extension GL_ARB_enhanced_layouts : require\n" 10048 "\n" 10049 "in vec4 gs_fs;\n" 10050 "out vec4 fs_out;\n" 10051 "\n" 10052 "void main()\n" 10053 "{\n" 10054 " fs_out = gs_fs;\n" 10055 "}\n" 10056 "\n"; 10057 static const GLchar* fs_tested = "#version 430 core\n" 10058 "#extension GL_ARB_enhanced_layouts : require\n" 10059 "\n" 10060 "layout (std140) uniform Block {\n" 10061 " vec4 boy;\n" 10062 " layout (align = ALIGN) TYPE man;\n" 10063 "} block;\n" 10064 "\n" 10065 "in vec4 gs_fs;\n" 10066 "out vec4 fs_out;\n" 10067 "\n" 10068 "void main()\n" 10069 "{\n" 10070 " if (TYPE(0) == block.man)\n" 10071 " {\n" 10072 " fs_out = block.boy;\n" 10073 " }\n" 10074 "\n" 10075 " fs_out += gs_fs;\n" 10076 "}\n" 10077 "\n"; 10078 static const GLchar* gs = "#version 430 core\n" 10079 "#extension GL_ARB_enhanced_layouts : require\n" 10080 "\n" 10081 "layout(points) in;\n" 10082 "layout(triangle_strip, max_vertices = 4) out;\n" 10083 "\n" 10084 "in vec4 tes_gs[];\n" 10085 "out vec4 gs_fs;\n" 10086 "\n" 10087 "void main()\n" 10088 "{\n" 10089 " gs_fs = tes_gs[0];\n" 10090 " gl_Position = vec4(-1, -1, 0, 1);\n" 10091 " EmitVertex();\n" 10092 " gs_fs = tes_gs[0];\n" 10093 " gl_Position = vec4(-1, 1, 0, 1);\n" 10094 " EmitVertex();\n" 10095 " gs_fs = tes_gs[0];\n" 10096 " gl_Position = vec4(1, -1, 0, 1);\n" 10097 " EmitVertex();\n" 10098 " gs_fs = tes_gs[0];\n" 10099 " gl_Position = vec4(1, 1, 0, 1);\n" 10100 " EmitVertex();\n" 10101 "}\n" 10102 "\n"; 10103 static const GLchar* gs_tested = "#version 430 core\n" 10104 "#extension GL_ARB_enhanced_layouts : require\n" 10105 "\n" 10106 "layout(points) in;\n" 10107 "layout(triangle_strip, max_vertices = 4) out;\n" 10108 "\n" 10109 "layout (std140) uniform Block {\n" 10110 " vec4 boy;\n" 10111 " layout (align = ALIGN) TYPE man;\n" 10112 "} block;\n" 10113 "\n" 10114 "in vec4 tes_gs[];\n" 10115 "out vec4 gs_fs;\n" 10116 "\n" 10117 "void main()\n" 10118 "{\n" 10119 " if (TYPE(0) == block.man)\n" 10120 " {\n" 10121 " gs_fs = block.boy;\n" 10122 " }\n" 10123 "\n" 10124 " gs_fs += tes_gs[0];\n" 10125 " gl_Position = vec4(-1, -1, 0, 1);\n" 10126 " EmitVertex();\n" 10127 " gs_fs += tes_gs[0];\n" 10128 " gl_Position = vec4(-1, 1, 0, 1);\n" 10129 " EmitVertex();\n" 10130 " gs_fs += tes_gs[0];\n" 10131 " gl_Position = vec4(1, -1, 0, 1);\n" 10132 " EmitVertex();\n" 10133 " gs_fs += tes_gs[0];\n" 10134 " gl_Position = vec4(1, 1, 0, 1);\n" 10135 " EmitVertex();\n" 10136 "}\n" 10137 "\n"; 10138 static const GLchar* tcs = "#version 430 core\n" 10139 "#extension GL_ARB_enhanced_layouts : require\n" 10140 "\n" 10141 "layout(vertices = 1) out;\n" 10142 "\n" 10143 "in vec4 vs_tcs[];\n" 10144 "out vec4 tcs_tes[];\n" 10145 "\n" 10146 "void main()\n" 10147 "{\n" 10148 "\n" 10149 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 10150 "\n" 10151 " gl_TessLevelOuter[0] = 1.0;\n" 10152 " gl_TessLevelOuter[1] = 1.0;\n" 10153 " gl_TessLevelOuter[2] = 1.0;\n" 10154 " gl_TessLevelOuter[3] = 1.0;\n" 10155 " gl_TessLevelInner[0] = 1.0;\n" 10156 " gl_TessLevelInner[1] = 1.0;\n" 10157 "}\n" 10158 "\n"; 10159 static const GLchar* tcs_tested = "#version 430 core\n" 10160 "#extension GL_ARB_enhanced_layouts : require\n" 10161 "\n" 10162 "layout(vertices = 1) out;\n" 10163 "\n" 10164 "layout (std140) uniform Block {\n" 10165 " vec4 boy;\n" 10166 " layout (align = ALIGN) TYPE man;\n" 10167 "} block;\n" 10168 "\n" 10169 "in vec4 vs_tcs[];\n" 10170 "out vec4 tcs_tes[];\n" 10171 "\n" 10172 "void main()\n" 10173 "{\n" 10174 " if (TYPE(0) == block.man)\n" 10175 " {\n" 10176 " tcs_tes[gl_InvocationID] = block.boy;\n" 10177 " }\n" 10178 "\n" 10179 "\n" 10180 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n" 10181 "\n" 10182 " gl_TessLevelOuter[0] = 1.0;\n" 10183 " gl_TessLevelOuter[1] = 1.0;\n" 10184 " gl_TessLevelOuter[2] = 1.0;\n" 10185 " gl_TessLevelOuter[3] = 1.0;\n" 10186 " gl_TessLevelInner[0] = 1.0;\n" 10187 " gl_TessLevelInner[1] = 1.0;\n" 10188 "}\n" 10189 "\n"; 10190 static const GLchar* tes = "#version 430 core\n" 10191 "#extension GL_ARB_enhanced_layouts : require\n" 10192 "\n" 10193 "layout(isolines, point_mode) in;\n" 10194 "\n" 10195 "in vec4 tcs_tes[];\n" 10196 "out vec4 tes_gs;\n" 10197 "\n" 10198 "void main()\n" 10199 "{\n" 10200 " tes_gs = tcs_tes[0];\n" 10201 "}\n" 10202 "\n"; 10203 static const GLchar* tes_tested = "#version 430 core\n" 10204 "#extension GL_ARB_enhanced_layouts : require\n" 10205 "\n" 10206 "layout(isolines, point_mode) in;\n" 10207 "\n" 10208 "layout (std140) uniform Block {\n" 10209 " vec4 boy;\n" 10210 " layout (align = ALIGN) TYPE man;\n" 10211 "} block;\n" 10212 "\n" 10213 "in vec4 tcs_tes[];\n" 10214 "out vec4 tes_gs;\n" 10215 "\n" 10216 "void main()\n" 10217 "{\n" 10218 " if (TYPE(0) == block.man)\n" 10219 " {\n" 10220 " tes_gs = block.boy;\n" 10221 " }\n" 10222 "\n" 10223 " tes_gs += tcs_tes[0];\n" 10224 "}\n" 10225 "\n"; 10226 static const GLchar* vs = "#version 430 core\n" 10227 "#extension GL_ARB_enhanced_layouts : require\n" 10228 "\n" 10229 "in vec4 in_vs;\n" 10230 "out vec4 vs_tcs;\n" 10231 "\n" 10232 "void main()\n" 10233 "{\n" 10234 " vs_tcs = in_vs;\n" 10235 "}\n" 10236 "\n"; 10237 static const GLchar* vs_tested = "#version 430 core\n" 10238 "#extension GL_ARB_enhanced_layouts : require\n" 10239 "\n" 10240 "layout (std140) uniform Block {\n" 10241 " vec4 boy;\n" 10242 " layout (align = ALIGN) TYPE man;\n" 10243 "} block;\n" 10244 "\n" 10245 "in vec4 in_vs;\n" 10246 "out vec4 vs_tcs;\n" 10247 "\n" 10248 "void main()\n" 10249 "{\n" 10250 " if (TYPE(0) == block.man)\n" 10251 " {\n" 10252 " vs_tcs = block.boy;\n" 10253 " }\n" 10254 "\n" 10255 " vs_tcs += in_vs;\n" 10256 "}\n" 10257 "\n"; 10258 10259 std::string source; 10260 testCase& test_case = m_test_cases[test_case_index]; 10261 10262 if (test_case.m_stage == stage) 10263 { 10264 GLchar buffer[16]; 10265 const GLuint alignment = test_case.m_alignment; 10266 const Utils::Type& type = test_case.m_type; 10267 const GLchar* type_name = type.GetGLSLTypeName(); 10268 size_t position = 0; 10269 10270 switch (stage) 10271 { 10272 case Utils::Shader::COMPUTE: 10273 source = cs; 10274 break; 10275 case Utils::Shader::FRAGMENT: 10276 source = fs_tested; 10277 break; 10278 case Utils::Shader::GEOMETRY: 10279 source = gs_tested; 10280 break; 10281 case Utils::Shader::TESS_CTRL: 10282 source = tcs_tested; 10283 break; 10284 case Utils::Shader::TESS_EVAL: 10285 source = tes_tested; 10286 break; 10287 case Utils::Shader::VERTEX: 10288 source = vs_tested; 10289 break; 10290 default: 10291 TCU_FAIL("Invalid enum"); 10292 } 10293 10294 sprintf(buffer, "%d", alignment); 10295 Utils::replaceToken("ALIGN", position, buffer, source); 10296 Utils::replaceToken("TYPE", position, type_name, source); 10297 Utils::replaceToken("TYPE", position, type_name, source); 10298 } 10299 else 10300 { 10301 switch (stage) 10302 { 10303 case Utils::Shader::FRAGMENT: 10304 source = fs; 10305 break; 10306 case Utils::Shader::GEOMETRY: 10307 source = gs; 10308 break; 10309 case Utils::Shader::TESS_CTRL: 10310 source = tcs; 10311 break; 10312 case Utils::Shader::TESS_EVAL: 10313 source = tes; 10314 break; 10315 case Utils::Shader::VERTEX: 10316 source = vs; 10317 break; 10318 default: 10319 TCU_FAIL("Invalid enum"); 10320 } 10321 } 10322 10323 return source; 10324 } 10325 10326 /** Get description of test case 10327 * 10328 * @param test_case_index Index of test case 10329 * 10330 * @return Type name and offset 10331 **/ 10332 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index) 10333 { 10334 std::stringstream stream; 10335 testCase& test_case = m_test_cases[test_case_index]; 10336 10337 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment; 10338 10339 return stream.str(); 10340 } 10341 10342 /** Get number of test cases 10343 * 10344 * @return Number of test cases 10345 **/ 10346 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber() 10347 { 10348 return static_cast<GLuint>(m_test_cases.size()); 10349 } 10350 10351 /** Selects if "compute" stage is relevant for test 10352 * 10353 * @param test_case_index Index of test case 10354 * 10355 * @return true when tested stage is compute 10356 **/ 10357 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index) 10358 { 10359 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage); 10360 } 10361 10362 /** Checks if stage is supported 10363 * 10364 * @param ignored 10365 * 10366 * @return true 10367 **/ 10368 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */) 10369 { 10370 return true; 10371 } 10372 10373 /** Selects if compilation failure is expected result 10374 * 10375 * @param test_case_index Index of test case 10376 * 10377 * @return should_fail field from testCase 10378 **/ 10379 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index) 10380 { 10381 return m_test_cases[test_case_index].m_should_fail; 10382 } 10383 10384 /** Prepare all test cases 10385 * 10386 **/ 10387 void UniformBlockMemberAlignNonPowerOf2Test::testInit() 10388 { 10389 static const GLuint dmat4_size = 128; 10390 const GLuint n_types = getTypesNumber(); 10391 bool stage_support[Utils::Shader::STAGE_MAX]; 10392 10393 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 10394 { 10395 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage); 10396 } 10397 10398 for (GLuint j = 0; j < n_types; ++j) 10399 { 10400 const Utils::Type& type = getType(j); 10401 10402 for (GLuint align = 0; align <= dmat4_size; ++align) 10403 { 10404 10405 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST 10406 10407 const bool should_fail = (0 == align) ? false : !isPowerOf2(align); 10408 10409 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */ 10410 10411 const bool should_fail = !isPowerOf2(align); 10412 10413 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */ 10414 10415 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 10416 { 10417 if (false == stage_support[stage]) 10418 { 10419 continue; 10420 } 10421 10422 testCase test_case = { align, type, should_fail, (Utils::Shader::STAGES)stage }; 10423 10424 m_test_cases.push_back(test_case); 10425 } 10426 } 10427 } 10428 } 10429 10430 /** Check if value is power of 2 10431 * 10432 * @param val Tested value 10433 * 10434 * @return true if val is power of 2, false otherwise 10435 **/ 10436 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val) 10437 { 10438 if (0 == val) 10439 { 10440 return false; 10441 } 10442 10443 return (0 == (val & (val - 1))); 10444 } 10445 10446 /** Constructor 10447 * 10448 * @param context Test framework context 10449 **/ 10450 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context& context) 10451 : TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer") 10452 { 10453 } 10454 10455 /** Get interface of program 10456 * 10457 * @param ignored 10458 * @param program_interface Interface of program 10459 * @param varying_passthrough Collection of connections between in and out variables 10460 **/ 10461 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */, 10462 Utils::ProgramInterface& program_interface, 10463 Utils::VaryingPassthrough& varying_passthrough) 10464 { 10465 static const Utils::Type vec4 = Utils::Type::vec4; 10466 10467 #if WRKARD_UNIFORMBLOCKALIGNMENT 10468 10469 static const GLuint block_align = 16; 10470 10471 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */ 10472 10473 static const GLuint block_align = 64; 10474 10475 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */ 10476 10477 static const GLuint vec4_stride = 16; 10478 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */ 10479 10480 /*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual 10481 alignment of a member will be the greater of the specified alignment and the base aligment for the member type 10482 */ 10483 const GLuint first_offset = 0; /* vec4 at 0 */ 10484 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */ 10485 const GLuint third_offset = 10486 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */ 10487 const GLuint fourth_offset = 10488 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */ 10489 const GLuint fifth_offset = 10490 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */ 10491 const GLuint sixth_offset = 10492 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */ 10493 10494 Utils::Interface* structure = program_interface.Structure("Data"); 10495 10496 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4, 10497 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */); 10498 10499 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float, 10500 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(), 10501 Utils::Type::vec4.GetSize() /* offset */); 10502 10503 /* Prepare Block */ 10504 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block"); 10505 10506 vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4, 10507 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */); 10508 10509 vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure, 10510 0 /* n_array_elements */, data_stride, second_offset); 10511 10512 vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure, 10513 2 /* n_array_elements */, data_stride, third_offset); 10514 10515 vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4, 10516 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset); 10517 10518 vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4, 10519 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset); 10520 10521 vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure, 10522 0 /* n_array_elements */, data_stride, sixth_offset); 10523 10524 const GLuint stride = calculateStride(*vs_uni_block); 10525 m_data.resize(stride); 10526 generateData(*vs_uni_block, 0, m_data); 10527 10528 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 10529 10530 /* Add uniform BLOCK */ 10531 #if WRKARD_UNIFORMBLOCKALIGNMENT 10532 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0, 10533 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size()); 10534 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */ 10535 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0, 10536 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size()); 10537 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */ 10538 10539 program_interface.CloneVertexInterface(varying_passthrough); 10540 } 10541 10542 /** Constructor 10543 * 10544 * @param context Test framework context 10545 **/ 10546 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context& context) 10547 : TextureTestBase(context, "ssb_member_offset_and_align", 10548 "Test verifies offsets and alignment of storage buffer members") 10549 { 10550 } 10551 10552 /** Get interface of program 10553 * 10554 * @param test_case_index Test case index 10555 * @param program_interface Interface of program 10556 * @param varying_passthrough Collection of connections between in and out variables 10557 **/ 10558 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index, 10559 Utils::ProgramInterface& program_interface, 10560 Utils::VaryingPassthrough& varying_passthrough) 10561 { 10562 std::string globals = "const int basic_size = BASIC_SIZE;\n" 10563 "const int type_align = TYPE_ALIGN;\n" 10564 "const int type_size = TYPE_SIZE;\n"; 10565 10566 Utils::Type type = getType(test_case_index); 10567 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type); 10568 const GLuint base_align = type.GetBaseAlignment(false); 10569 const GLuint array_align = type.GetBaseAlignment(true); 10570 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0); 10571 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride); 10572 10573 /* Calculate offsets */ 10574 const GLuint first_offset = 0; 10575 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2); 10576 10577 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST 10578 10579 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align); 10580 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align); 10581 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align); 10582 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align); 10583 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align); 10584 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align); 10585 10586 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */ 10587 10588 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align); 10589 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align); 10590 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align); 10591 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align); 10592 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align); 10593 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size); 10594 10595 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */ 10596 10597 /* Prepare data */ 10598 const std::vector<GLubyte>& first = type.GenerateData(); 10599 const std::vector<GLubyte>& second = type.GenerateData(); 10600 const std::vector<GLubyte>& third = type.GenerateData(); 10601 const std::vector<GLubyte>& fourth = type.GenerateData(); 10602 10603 m_data.resize(eigth_offset + base_stride); 10604 GLubyte* ptr = &m_data[0]; 10605 memcpy(ptr + first_offset, &first[0], first.size()); 10606 memcpy(ptr + second_offset, &second[0], second.size()); 10607 memcpy(ptr + third_offset, &third[0], third.size()); 10608 memcpy(ptr + fourth_offset, &fourth[0], fourth.size()); 10609 memcpy(ptr + fifth_offset, &fourth[0], fourth.size()); 10610 memcpy(ptr + sixth_offset, &third[0], third.size()); 10611 memcpy(ptr + seventh_offset, &second[0], second.size()); 10612 memcpy(ptr + eigth_offset, &first[0], first.size()); 10613 10614 /* Prepare globals */ 10615 size_t position = 0; 10616 GLchar buffer[16]; 10617 10618 sprintf(buffer, "%d", basic_size); 10619 Utils::replaceToken("BASIC_SIZE", position, buffer, globals); 10620 10621 sprintf(buffer, "%d", type_align); 10622 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals); 10623 10624 sprintf(buffer, "%d", base_stride); 10625 Utils::replaceToken("TYPE_SIZE", position, buffer, globals); 10626 10627 /* Prepare Block */ 10628 Utils::Interface* vs_buf_block = program_interface.Block("vs_buf_Block"); 10629 10630 vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */, 10631 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 10632 first_offset); 10633 10634 vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)", 10635 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */, 10636 0 /* n_array_elements */, base_stride, second_offset); 10637 10638 vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */, 10639 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 10640 third_offset); 10641 10642 vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */, 10643 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 10644 fourth_offset); 10645 10646 vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type, 10647 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset); 10648 10649 vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type, 10650 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset); 10651 10652 vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */, 10653 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 10654 eigth_offset); 10655 10656 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 10657 10658 /* Add globals */ 10659 vs_si.m_globals = globals; 10660 10661 /* Add uniform BLOCK */ 10662 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0, 10663 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size()); 10664 10665 /* */ 10666 program_interface.CloneVertexInterface(varying_passthrough); 10667 } 10668 10669 /** Get type name 10670 * 10671 * @param test_case_index Index of test case 10672 * 10673 * @return Name of type test in test_case_index 10674 **/ 10675 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index) 10676 { 10677 return getTypeName(test_case_index); 10678 } 10679 10680 /** Returns number of types to test 10681 * 10682 * @return Number of types, 34 10683 **/ 10684 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber() 10685 { 10686 return getTypesNumber(); 10687 } 10688 10689 /** Prepare code snippet that will verify in and uniform variables 10690 * 10691 * @param ignored 10692 * @param ignored 10693 * @param stage Shader stage 10694 * 10695 * @return Code that verify variables 10696 **/ 10697 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */, 10698 Utils::ProgramInterface& /* program_interface */, 10699 Utils::Shader::STAGES stage) 10700 { 10701 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n" 10702 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n" 10703 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n" 10704 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n" 10705 " {\n" 10706 " result = 0;\n" 10707 " }"; 10708 10709 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB); 10710 10711 Utils::replaceAllTokens("PREFIX", prefix, verification); 10712 10713 return verification; 10714 } 10715 10716 /** Selects if "draw" stages are relevant for test 10717 * 10718 * @param ignored 10719 * 10720 * @return true if all stages support shader storage buffers, false otherwise 10721 **/ 10722 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */) 10723 { 10724 const Functions& gl = m_context.getRenderContext().getFunctions(); 10725 GLint gs_supported_buffers = 0; 10726 GLint tcs_supported_buffers = 0; 10727 GLint tes_supported_buffers = 0; 10728 GLint vs_supported_buffers = 0; 10729 10730 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers); 10731 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers); 10732 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers); 10733 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers); 10734 10735 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 10736 10737 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) && 10738 (1 <= vs_supported_buffers)); 10739 } 10740 10741 /** Constructor 10742 * 10743 * @param context Test framework context 10744 **/ 10745 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context& context) 10746 : NegativeTestBase(context, "ssb_layout_qualifier_conflict", "Test verifies that std140 or std430 is required when " 10747 "offset and/or align qualifiers are used with storage " 10748 "block") 10749 { 10750 /* Nothing to be done here */ 10751 } 10752 10753 /** Source for given test case and stage 10754 * 10755 * @param test_case_index Index of test case 10756 * @param stage Shader stage 10757 * 10758 * @return Shader source 10759 **/ 10760 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 10761 { 10762 static const GLchar* cs = "#version 430 core\n" 10763 "#extension GL_ARB_enhanced_layouts : require\n" 10764 "\n" 10765 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 10766 "\n" 10767 "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n" 10768 " layout(offset = 16) vec4 boy;\n" 10769 " layout(align = 64) vec4 man;\n" 10770 "} uni_block;\n" 10771 "\n" 10772 "writeonly uniform image2D uni_image;\n" 10773 "\n" 10774 "void main()\n" 10775 "{\n" 10776 " vec4 result = uni_block.boy + uni_block.man;\n" 10777 "\n" 10778 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 10779 "}\n" 10780 "\n"; 10781 static const GLchar* fs = "#version 430 core\n" 10782 "#extension GL_ARB_enhanced_layouts : require\n" 10783 "\n" 10784 "layout (QUALIFIERbinding = BINDING) buffer Block {\n" 10785 " layout(offset = 16) vec4 boy;\n" 10786 " layout(align = 64) vec4 man;\n" 10787 "} uni_block;\n" 10788 "\n" 10789 "in vec4 gs_fs;\n" 10790 "out vec4 fs_out;\n" 10791 "\n" 10792 "void main()\n" 10793 "{\n" 10794 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n" 10795 "}\n" 10796 "\n"; 10797 static const GLchar* gs = "#version 430 core\n" 10798 "#extension GL_ARB_enhanced_layouts : require\n" 10799 "\n" 10800 "layout(points) in;\n" 10801 "layout(triangle_strip, max_vertices = 4) out;\n" 10802 "\n" 10803 "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n" 10804 " layout(offset = 16) vec4 boy;\n" 10805 " layout(align = 64) vec4 man;\n" 10806 "} uni_block;\n" 10807 "\n" 10808 "in vec4 tes_gs[];\n" 10809 "out vec4 gs_fs;\n" 10810 "\n" 10811 "void main()\n" 10812 "{\n" 10813 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 10814 " gl_Position = vec4(-1, -1, 0, 1);\n" 10815 " EmitVertex();\n" 10816 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 10817 " gl_Position = vec4(-1, 1, 0, 1);\n" 10818 " EmitVertex();\n" 10819 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 10820 " gl_Position = vec4(1, -1, 0, 1);\n" 10821 " EmitVertex();\n" 10822 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 10823 " gl_Position = vec4(1, 1, 0, 1);\n" 10824 " EmitVertex();\n" 10825 "}\n" 10826 "\n"; 10827 static const GLchar* tcs = 10828 "#version 430 core\n" 10829 "#extension GL_ARB_enhanced_layouts : require\n" 10830 "\n" 10831 "layout(vertices = 1) out;\n" 10832 "\n" 10833 "layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n" 10834 " layout(offset = 16) vec4 boy;\n" 10835 " layout(align = 64) vec4 man;\n" 10836 "} uni_block;\n" 10837 "\n" 10838 "in vec4 vs_tcs[];\n" 10839 "out vec4 tcs_tes[];\n" 10840 "\n" 10841 "void main()\n" 10842 "{\n" 10843 "\n" 10844 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n" 10845 "\n" 10846 " gl_TessLevelOuter[0] = 1.0;\n" 10847 " gl_TessLevelOuter[1] = 1.0;\n" 10848 " gl_TessLevelOuter[2] = 1.0;\n" 10849 " gl_TessLevelOuter[3] = 1.0;\n" 10850 " gl_TessLevelInner[0] = 1.0;\n" 10851 " gl_TessLevelInner[1] = 1.0;\n" 10852 "}\n" 10853 "\n"; 10854 static const GLchar* tes = "#version 430 core\n" 10855 "#extension GL_ARB_enhanced_layouts : require\n" 10856 "\n" 10857 "layout(isolines, point_mode) in;\n" 10858 "\n" 10859 "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n" 10860 " layout(offset = 16) vec4 boy;\n" 10861 " layout(align = 64) vec4 man;\n" 10862 "} uni_block;\n" 10863 "\n" 10864 "in vec4 tcs_tes[];\n" 10865 "out vec4 tes_gs;\n" 10866 "\n" 10867 "void main()\n" 10868 "{\n" 10869 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n" 10870 "}\n" 10871 "\n"; 10872 static const GLchar* vs = "#version 430 core\n" 10873 "#extension GL_ARB_enhanced_layouts : require\n" 10874 "\n" 10875 "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n" 10876 " layout(offset = 16) vec4 boy;\n" 10877 " layout(align = 64) vec4 man;\n" 10878 "} uni_block;\n" 10879 "\n" 10880 "in vec4 in_vs;\n" 10881 "out vec4 vs_tcs;\n" 10882 "\n" 10883 "void main()\n" 10884 "{\n" 10885 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n" 10886 "}\n" 10887 "\n"; 10888 10889 GLchar buffer[16]; 10890 size_t position = 0; 10891 std::string source; 10892 testCase& test_case = m_test_cases[test_case_index]; 10893 std::string qualifier = getQualifierName(test_case.m_qualifier); 10894 10895 if (false == qualifier.empty()) 10896 { 10897 qualifier.append(", "); 10898 } 10899 10900 sprintf(buffer, "%d", stage); 10901 10902 switch (stage) 10903 { 10904 case Utils::Shader::COMPUTE: 10905 source = cs; 10906 break; 10907 case Utils::Shader::FRAGMENT: 10908 source = fs; 10909 break; 10910 case Utils::Shader::GEOMETRY: 10911 source = gs; 10912 break; 10913 case Utils::Shader::TESS_CTRL: 10914 source = tcs; 10915 break; 10916 case Utils::Shader::TESS_EVAL: 10917 source = tes; 10918 break; 10919 case Utils::Shader::VERTEX: 10920 source = vs; 10921 break; 10922 default: 10923 TCU_FAIL("Invalid enum"); 10924 } 10925 10926 if (test_case.m_stage == stage) 10927 { 10928 Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source); 10929 } 10930 else 10931 { 10932 Utils::replaceToken("QUALIFIER", position, "std140, ", source); 10933 } 10934 10935 Utils::replaceToken("BINDING", position, buffer, source); 10936 10937 return source; 10938 } 10939 10940 /** Get description of test case 10941 * 10942 * @param test_case_index Index of test case 10943 * 10944 * @return Qualifier name 10945 **/ 10946 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index) 10947 { 10948 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier); 10949 10950 return result; 10951 } 10952 10953 /** Get number of test cases 10954 * 10955 * @return Number of test cases 10956 **/ 10957 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber() 10958 { 10959 return static_cast<GLuint>(m_test_cases.size()); 10960 } 10961 10962 /** Selects if "compute" stage is relevant for test 10963 * 10964 * @param test_case_index Index of test case 10965 * 10966 * @return true when tested stage is compute 10967 **/ 10968 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index) 10969 { 10970 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage); 10971 } 10972 10973 /** Selects if compilation failure is expected result 10974 * 10975 * @param test_case_index Index of test case 10976 * 10977 * @return false for STD140 and STD430 cases, true otherwise 10978 **/ 10979 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index) 10980 { 10981 const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier; 10982 10983 return !((STD140 == qualifier) || (STD430 == qualifier)); 10984 } 10985 10986 /** Checks if stage is supported 10987 * 10988 * @param stage Shader stage 10989 * 10990 * @return true if supported, false otherwise 10991 **/ 10992 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage) 10993 { 10994 const Functions& gl = m_context.getRenderContext().getFunctions(); 10995 GLint max_supported_buffers = 0; 10996 GLenum pname = 0; 10997 10998 switch (stage) 10999 { 11000 case Utils::Shader::COMPUTE: 11001 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS; 11002 break; 11003 case Utils::Shader::FRAGMENT: 11004 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS; 11005 break; 11006 case Utils::Shader::GEOMETRY: 11007 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS; 11008 break; 11009 case Utils::Shader::TESS_CTRL: 11010 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS; 11011 break; 11012 case Utils::Shader::TESS_EVAL: 11013 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS; 11014 break; 11015 case Utils::Shader::VERTEX: 11016 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS; 11017 break; 11018 default: 11019 TCU_FAIL("Invalid enum"); 11020 } 11021 11022 gl.getIntegerv(pname, &max_supported_buffers); 11023 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 11024 11025 return 1 <= max_supported_buffers; 11026 } 11027 11028 /** Prepare all test cases 11029 * 11030 **/ 11031 void SSBLayoutQualifierConflictTest::testInit() 11032 { 11033 bool stage_support[Utils::Shader::STAGE_MAX]; 11034 11035 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 11036 { 11037 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage); 11038 } 11039 11040 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier) 11041 { 11042 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 11043 { 11044 if (false == stage_support[stage]) 11045 { 11046 continue; 11047 } 11048 11049 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage }; 11050 11051 m_test_cases.push_back(test_case); 11052 } 11053 } 11054 } 11055 11056 /** Get name of glsl constant 11057 * 11058 * @param Constant id 11059 * 11060 * @return Name of constant used in GLSL 11061 **/ 11062 const GLchar* SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier) 11063 { 11064 const GLchar* name = ""; 11065 11066 switch (qualifier) 11067 { 11068 case DEFAULT: 11069 name = ""; 11070 break; 11071 case STD140: 11072 name = "std140"; 11073 break; 11074 case STD430: 11075 name = "std430"; 11076 break; 11077 case SHARED: 11078 name = "shared"; 11079 break; 11080 case PACKED: 11081 name = "packed"; 11082 break; 11083 default: 11084 TCU_FAIL("Invalid enum"); 11085 } 11086 11087 return name; 11088 } 11089 11090 /** Constructor 11091 * 11092 * @param context Test framework context 11093 **/ 11094 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context& context) 11095 : UniformBlockMemberInvalidOffsetAlignmentTest( 11096 context, "ssb_member_invalid_offset_alignment", 11097 "Test verifies that invalid alignment of offset qualifiers cause compilation failure") 11098 { 11099 /* Nothing to be done here */ 11100 } 11101 11102 /** Get the maximum size for a shader storage block 11103 * 11104 * @return The maximum size in basic machine units of a shader storage block. 11105 **/ 11106 GLint SSBMemberInvalidOffsetAlignmentTest::getMaxBlockSize() 11107 { 11108 const Functions& gl = m_context.getRenderContext().getFunctions(); 11109 GLint max_size = 0; 11110 11111 gl.getIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_size); 11112 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 11113 11114 return max_size; 11115 } 11116 11117 /** Source for given test case and stage 11118 * 11119 * @param test_case_index Index of test case 11120 * @param stage Shader stage 11121 * 11122 * @return Shader source 11123 **/ 11124 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 11125 { 11126 static const GLchar* cs = "#version 430 core\n" 11127 "#extension GL_ARB_enhanced_layouts : require\n" 11128 "\n" 11129 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 11130 "\n" 11131 "layout (std140) buffer Block {\n" 11132 " layout (offset = OFFSET) TYPE member;\n" 11133 "} block;\n" 11134 "\n" 11135 "writeonly uniform image2D uni_image;\n" 11136 "\n" 11137 "void main()\n" 11138 "{\n" 11139 " vec4 result = vec4(1, 0, 0.5, 1);\n" 11140 "\n" 11141 " if (TYPE(1) == block.member)\n" 11142 " {\n" 11143 " result = vec4(1, 1, 1, 1);\n" 11144 " }\n" 11145 "\n" 11146 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 11147 "}\n" 11148 "\n"; 11149 static const GLchar* fs = "#version 430 core\n" 11150 "#extension GL_ARB_enhanced_layouts : require\n" 11151 "\n" 11152 "in vec4 gs_fs;\n" 11153 "out vec4 fs_out;\n" 11154 "\n" 11155 "void main()\n" 11156 "{\n" 11157 " fs_out = gs_fs;\n" 11158 "}\n" 11159 "\n"; 11160 static const GLchar* fs_tested = "#version 430 core\n" 11161 "#extension GL_ARB_enhanced_layouts : require\n" 11162 "\n" 11163 "layout (std140) buffer Block {\n" 11164 " layout (offset = OFFSET) TYPE member;\n" 11165 "} block;\n" 11166 "\n" 11167 "in vec4 gs_fs;\n" 11168 "out vec4 fs_out;\n" 11169 "\n" 11170 "void main()\n" 11171 "{\n" 11172 " if (TYPE(1) == block.member)\n" 11173 " {\n" 11174 " fs_out = vec4(1, 1, 1, 1);\n" 11175 " }\n" 11176 "\n" 11177 " fs_out += gs_fs;\n" 11178 "}\n" 11179 "\n"; 11180 static const GLchar* gs = "#version 430 core\n" 11181 "#extension GL_ARB_enhanced_layouts : require\n" 11182 "\n" 11183 "layout(points) in;\n" 11184 "layout(triangle_strip, max_vertices = 4) out;\n" 11185 "\n" 11186 "in vec4 tes_gs[];\n" 11187 "out vec4 gs_fs;\n" 11188 "\n" 11189 "void main()\n" 11190 "{\n" 11191 " gs_fs = tes_gs[0];\n" 11192 " gl_Position = vec4(-1, -1, 0, 1);\n" 11193 " EmitVertex();\n" 11194 " gs_fs = tes_gs[0];\n" 11195 " gl_Position = vec4(-1, 1, 0, 1);\n" 11196 " EmitVertex();\n" 11197 " gs_fs = tes_gs[0];\n" 11198 " gl_Position = vec4(1, -1, 0, 1);\n" 11199 " EmitVertex();\n" 11200 " gs_fs = tes_gs[0];\n" 11201 " gl_Position = vec4(1, 1, 0, 1);\n" 11202 " EmitVertex();\n" 11203 "}\n" 11204 "\n"; 11205 static const GLchar* gs_tested = "#version 430 core\n" 11206 "#extension GL_ARB_enhanced_layouts : require\n" 11207 "\n" 11208 "layout(points) in;\n" 11209 "layout(triangle_strip, max_vertices = 4) out;\n" 11210 "\n" 11211 "layout (std140) buffer Block {\n" 11212 " layout (offset = OFFSET) TYPE member;\n" 11213 "} block;\n" 11214 "\n" 11215 "in vec4 tes_gs[];\n" 11216 "out vec4 gs_fs;\n" 11217 "\n" 11218 "void main()\n" 11219 "{\n" 11220 " if (TYPE(1) == block.member)\n" 11221 " {\n" 11222 " gs_fs = vec4(1, 1, 1, 1);\n" 11223 " }\n" 11224 "\n" 11225 " gs_fs += tes_gs[0];\n" 11226 " gl_Position = vec4(-1, -1, 0, 1);\n" 11227 " EmitVertex();\n" 11228 " gs_fs += tes_gs[0];\n" 11229 " gl_Position = vec4(-1, 1, 0, 1);\n" 11230 " EmitVertex();\n" 11231 " gs_fs += tes_gs[0];\n" 11232 " gl_Position = vec4(1, -1, 0, 1);\n" 11233 " EmitVertex();\n" 11234 " gs_fs += tes_gs[0];\n" 11235 " gl_Position = vec4(1, 1, 0, 1);\n" 11236 " EmitVertex();\n" 11237 "}\n" 11238 "\n"; 11239 static const GLchar* tcs = "#version 430 core\n" 11240 "#extension GL_ARB_enhanced_layouts : require\n" 11241 "\n" 11242 "layout(vertices = 1) out;\n" 11243 "\n" 11244 "in vec4 vs_tcs[];\n" 11245 "out vec4 tcs_tes[];\n" 11246 "\n" 11247 "void main()\n" 11248 "{\n" 11249 "\n" 11250 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 11251 "\n" 11252 " gl_TessLevelOuter[0] = 1.0;\n" 11253 " gl_TessLevelOuter[1] = 1.0;\n" 11254 " gl_TessLevelOuter[2] = 1.0;\n" 11255 " gl_TessLevelOuter[3] = 1.0;\n" 11256 " gl_TessLevelInner[0] = 1.0;\n" 11257 " gl_TessLevelInner[1] = 1.0;\n" 11258 "}\n" 11259 "\n"; 11260 static const GLchar* tcs_tested = "#version 430 core\n" 11261 "#extension GL_ARB_enhanced_layouts : require\n" 11262 "\n" 11263 "layout(vertices = 1) out;\n" 11264 "\n" 11265 "layout (std140) buffer Block {\n" 11266 " layout (offset = OFFSET) TYPE member;\n" 11267 "} block;\n" 11268 "\n" 11269 "in vec4 vs_tcs[];\n" 11270 "out vec4 tcs_tes[];\n" 11271 "\n" 11272 "void main()\n" 11273 "{\n" 11274 " if (TYPE(1) == block.member)\n" 11275 " {\n" 11276 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n" 11277 " }\n" 11278 "\n" 11279 "\n" 11280 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n" 11281 "\n" 11282 " gl_TessLevelOuter[0] = 1.0;\n" 11283 " gl_TessLevelOuter[1] = 1.0;\n" 11284 " gl_TessLevelOuter[2] = 1.0;\n" 11285 " gl_TessLevelOuter[3] = 1.0;\n" 11286 " gl_TessLevelInner[0] = 1.0;\n" 11287 " gl_TessLevelInner[1] = 1.0;\n" 11288 "}\n" 11289 "\n"; 11290 static const GLchar* tes = "#version 430 core\n" 11291 "#extension GL_ARB_enhanced_layouts : require\n" 11292 "\n" 11293 "layout(isolines, point_mode) in;\n" 11294 "\n" 11295 "in vec4 tcs_tes[];\n" 11296 "out vec4 tes_gs;\n" 11297 "\n" 11298 "void main()\n" 11299 "{\n" 11300 " tes_gs = tcs_tes[0];\n" 11301 "}\n" 11302 "\n"; 11303 static const GLchar* tes_tested = "#version 430 core\n" 11304 "#extension GL_ARB_enhanced_layouts : require\n" 11305 "\n" 11306 "layout(isolines, point_mode) in;\n" 11307 "\n" 11308 "layout (std140) buffer Block {\n" 11309 " layout (offset = OFFSET) TYPE member;\n" 11310 "} block;\n" 11311 "\n" 11312 "in vec4 tcs_tes[];\n" 11313 "out vec4 tes_gs;\n" 11314 "\n" 11315 "void main()\n" 11316 "{\n" 11317 " if (TYPE(1) == block.member)\n" 11318 " {\n" 11319 " tes_gs = vec4(1, 1, 1, 1);\n" 11320 " }\n" 11321 "\n" 11322 " tes_gs += tcs_tes[0];\n" 11323 "}\n" 11324 "\n"; 11325 static const GLchar* vs = "#version 430 core\n" 11326 "#extension GL_ARB_enhanced_layouts : require\n" 11327 "\n" 11328 "in vec4 in_vs;\n" 11329 "out vec4 vs_tcs;\n" 11330 "\n" 11331 "void main()\n" 11332 "{\n" 11333 " vs_tcs = in_vs;\n" 11334 "}\n" 11335 "\n"; 11336 static const GLchar* vs_tested = "#version 430 core\n" 11337 "#extension GL_ARB_enhanced_layouts : require\n" 11338 "\n" 11339 "layout (std140) buffer Block {\n" 11340 " layout (offset = OFFSET) TYPE member;\n" 11341 "} block;\n" 11342 "\n" 11343 "in vec4 in_vs;\n" 11344 "out vec4 vs_tcs;\n" 11345 "\n" 11346 "void main()\n" 11347 "{\n" 11348 " if (TYPE(1) == block.member)\n" 11349 " {\n" 11350 " vs_tcs = vec4(1, 1, 1, 1);\n" 11351 " }\n" 11352 "\n" 11353 " vs_tcs += in_vs;\n" 11354 "}\n" 11355 "\n"; 11356 11357 std::string source; 11358 testCase& test_case = m_test_cases[test_case_index]; 11359 11360 if (test_case.m_stage == stage) 11361 { 11362 GLchar buffer[16]; 11363 const GLuint offset = test_case.m_offset; 11364 size_t position = 0; 11365 const Utils::Type& type = test_case.m_type; 11366 const GLchar* type_name = type.GetGLSLTypeName(); 11367 11368 sprintf(buffer, "%d", offset); 11369 11370 switch (stage) 11371 { 11372 case Utils::Shader::COMPUTE: 11373 source = cs; 11374 break; 11375 case Utils::Shader::FRAGMENT: 11376 source = fs_tested; 11377 break; 11378 case Utils::Shader::GEOMETRY: 11379 source = gs_tested; 11380 break; 11381 case Utils::Shader::TESS_CTRL: 11382 source = tcs_tested; 11383 break; 11384 case Utils::Shader::TESS_EVAL: 11385 source = tes_tested; 11386 break; 11387 case Utils::Shader::VERTEX: 11388 source = vs_tested; 11389 break; 11390 default: 11391 TCU_FAIL("Invalid enum"); 11392 } 11393 11394 Utils::replaceToken("OFFSET", position, buffer, source); 11395 Utils::replaceToken("TYPE", position, type_name, source); 11396 Utils::replaceToken("TYPE", position, type_name, source); 11397 } 11398 else 11399 { 11400 switch (stage) 11401 { 11402 case Utils::Shader::FRAGMENT: 11403 source = fs; 11404 break; 11405 case Utils::Shader::GEOMETRY: 11406 source = gs; 11407 break; 11408 case Utils::Shader::TESS_CTRL: 11409 source = tcs; 11410 break; 11411 case Utils::Shader::TESS_EVAL: 11412 source = tes; 11413 break; 11414 case Utils::Shader::VERTEX: 11415 source = vs; 11416 break; 11417 default: 11418 TCU_FAIL("Invalid enum"); 11419 } 11420 } 11421 11422 return source; 11423 } 11424 11425 /** Checks if stage is supported 11426 * 11427 * @param stage Shader stage 11428 * 11429 * @return true if supported, false otherwise 11430 **/ 11431 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage) 11432 { 11433 const Functions& gl = m_context.getRenderContext().getFunctions(); 11434 GLint max_supported_buffers = 0; 11435 GLenum pname = 0; 11436 11437 switch (stage) 11438 { 11439 case Utils::Shader::COMPUTE: 11440 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS; 11441 break; 11442 case Utils::Shader::FRAGMENT: 11443 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS; 11444 break; 11445 case Utils::Shader::GEOMETRY: 11446 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS; 11447 break; 11448 case Utils::Shader::TESS_CTRL: 11449 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS; 11450 break; 11451 case Utils::Shader::TESS_EVAL: 11452 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS; 11453 break; 11454 case Utils::Shader::VERTEX: 11455 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS; 11456 break; 11457 default: 11458 TCU_FAIL("Invalid enum"); 11459 } 11460 11461 gl.getIntegerv(pname, &max_supported_buffers); 11462 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 11463 11464 return 1 <= max_supported_buffers; 11465 } 11466 11467 /** Constructor 11468 * 11469 * @param context Test framework context 11470 **/ 11471 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context& context) 11472 : UniformBlockMemberOverlappingOffsetsTest( 11473 context, "ssb_member_overlapping_offsets", 11474 "Test verifies that overlapping offsets qualifiers cause compilation failure") 11475 { 11476 /* Nothing to be done here */ 11477 } 11478 11479 /** Source for given test case and stage 11480 * 11481 * @param test_case_index Index of test case 11482 * @param stage Shader stage 11483 * 11484 * @return Shader source 11485 **/ 11486 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 11487 { 11488 static const GLchar* cs = "#version 430 core\n" 11489 "#extension GL_ARB_enhanced_layouts : require\n" 11490 "\n" 11491 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 11492 "\n" 11493 "layout (std140) buffer Block {\n" 11494 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 11495 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 11496 "} block;\n" 11497 "\n" 11498 "writeonly uniform image2D uni_image;\n" 11499 "\n" 11500 "void main()\n" 11501 "{\n" 11502 " vec4 result = vec4(1, 0, 0.5, 1);\n" 11503 "\n" 11504 " if ((BOY_TYPE(1) == block.boy) ||\n" 11505 " (MAN_TYPE(0) == block.man) )\n" 11506 " {\n" 11507 " result = vec4(1, 1, 1, 1);\n" 11508 " }\n" 11509 "\n" 11510 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 11511 "}\n" 11512 "\n"; 11513 static const GLchar* fs = "#version 430 core\n" 11514 "#extension GL_ARB_enhanced_layouts : require\n" 11515 "\n" 11516 "in vec4 gs_fs;\n" 11517 "out vec4 fs_out;\n" 11518 "\n" 11519 "void main()\n" 11520 "{\n" 11521 " fs_out = gs_fs;\n" 11522 "}\n" 11523 "\n"; 11524 static const GLchar* fs_tested = "#version 430 core\n" 11525 "#extension GL_ARB_enhanced_layouts : require\n" 11526 "\n" 11527 "layout (std140) buffer Block {\n" 11528 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 11529 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 11530 "} block;\n" 11531 "\n" 11532 "in vec4 gs_fs;\n" 11533 "out vec4 fs_out;\n" 11534 "\n" 11535 "void main()\n" 11536 "{\n" 11537 " if ((BOY_TYPE(1) == block.boy) ||\n" 11538 " (MAN_TYPE(0) == block.man) )\n" 11539 " {\n" 11540 " fs_out = vec4(1, 1, 1, 1);\n" 11541 " }\n" 11542 "\n" 11543 " fs_out += gs_fs;\n" 11544 "}\n" 11545 "\n"; 11546 static const GLchar* gs = "#version 430 core\n" 11547 "#extension GL_ARB_enhanced_layouts : require\n" 11548 "\n" 11549 "layout(points) in;\n" 11550 "layout(triangle_strip, max_vertices = 4) out;\n" 11551 "\n" 11552 "in vec4 tes_gs[];\n" 11553 "out vec4 gs_fs;\n" 11554 "\n" 11555 "void main()\n" 11556 "{\n" 11557 " gs_fs = tes_gs[0];\n" 11558 " gl_Position = vec4(-1, -1, 0, 1);\n" 11559 " EmitVertex();\n" 11560 " gs_fs = tes_gs[0];\n" 11561 " gl_Position = vec4(-1, 1, 0, 1);\n" 11562 " EmitVertex();\n" 11563 " gs_fs = tes_gs[0];\n" 11564 " gl_Position = vec4(1, -1, 0, 1);\n" 11565 " EmitVertex();\n" 11566 " gs_fs = tes_gs[0];\n" 11567 " gl_Position = vec4(1, 1, 0, 1);\n" 11568 " EmitVertex();\n" 11569 "}\n" 11570 "\n"; 11571 static const GLchar* gs_tested = "#version 430 core\n" 11572 "#extension GL_ARB_enhanced_layouts : require\n" 11573 "\n" 11574 "layout(points) in;\n" 11575 "layout(triangle_strip, max_vertices = 4) out;\n" 11576 "\n" 11577 "layout (std140) buffer Block {\n" 11578 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 11579 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 11580 "} block;\n" 11581 "\n" 11582 "in vec4 tes_gs[];\n" 11583 "out vec4 gs_fs;\n" 11584 "\n" 11585 "void main()\n" 11586 "{\n" 11587 " if ((BOY_TYPE(1) == block.boy) ||\n" 11588 " (MAN_TYPE(0) == block.man) )\n" 11589 " {\n" 11590 " gs_fs = vec4(1, 1, 1, 1);\n" 11591 " }\n" 11592 "\n" 11593 " gs_fs += tes_gs[0];\n" 11594 " gl_Position = vec4(-1, -1, 0, 1);\n" 11595 " EmitVertex();\n" 11596 " gs_fs += tes_gs[0];\n" 11597 " gl_Position = vec4(-1, 1, 0, 1);\n" 11598 " EmitVertex();\n" 11599 " gs_fs += tes_gs[0];\n" 11600 " gl_Position = vec4(1, -1, 0, 1);\n" 11601 " EmitVertex();\n" 11602 " gs_fs += tes_gs[0];\n" 11603 " gl_Position = vec4(1, 1, 0, 1);\n" 11604 " EmitVertex();\n" 11605 "}\n" 11606 "\n"; 11607 static const GLchar* tcs = "#version 430 core\n" 11608 "#extension GL_ARB_enhanced_layouts : require\n" 11609 "\n" 11610 "layout(vertices = 1) out;\n" 11611 "\n" 11612 "in vec4 vs_tcs[];\n" 11613 "out vec4 tcs_tes[];\n" 11614 "\n" 11615 "void main()\n" 11616 "{\n" 11617 "\n" 11618 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 11619 "\n" 11620 " gl_TessLevelOuter[0] = 1.0;\n" 11621 " gl_TessLevelOuter[1] = 1.0;\n" 11622 " gl_TessLevelOuter[2] = 1.0;\n" 11623 " gl_TessLevelOuter[3] = 1.0;\n" 11624 " gl_TessLevelInner[0] = 1.0;\n" 11625 " gl_TessLevelInner[1] = 1.0;\n" 11626 "}\n" 11627 "\n"; 11628 static const GLchar* tcs_tested = "#version 430 core\n" 11629 "#extension GL_ARB_enhanced_layouts : require\n" 11630 "\n" 11631 "layout(vertices = 1) out;\n" 11632 "\n" 11633 "layout (std140) buffer Block {\n" 11634 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 11635 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 11636 "} block;\n" 11637 "\n" 11638 "in vec4 vs_tcs[];\n" 11639 "out vec4 tcs_tes[];\n" 11640 "\n" 11641 "void main()\n" 11642 "{\n" 11643 " if ((BOY_TYPE(1) == block.boy) ||\n" 11644 " (MAN_TYPE(0) == block.man) )\n" 11645 " {\n" 11646 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n" 11647 " }\n" 11648 "\n" 11649 "\n" 11650 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n" 11651 "\n" 11652 " gl_TessLevelOuter[0] = 1.0;\n" 11653 " gl_TessLevelOuter[1] = 1.0;\n" 11654 " gl_TessLevelOuter[2] = 1.0;\n" 11655 " gl_TessLevelOuter[3] = 1.0;\n" 11656 " gl_TessLevelInner[0] = 1.0;\n" 11657 " gl_TessLevelInner[1] = 1.0;\n" 11658 "}\n" 11659 "\n"; 11660 static const GLchar* tes = "#version 430 core\n" 11661 "#extension GL_ARB_enhanced_layouts : require\n" 11662 "\n" 11663 "layout(isolines, point_mode) in;\n" 11664 "\n" 11665 "in vec4 tcs_tes[];\n" 11666 "out vec4 tes_gs;\n" 11667 "\n" 11668 "void main()\n" 11669 "{\n" 11670 " tes_gs = tcs_tes[0];\n" 11671 "}\n" 11672 "\n"; 11673 static const GLchar* tes_tested = "#version 430 core\n" 11674 "#extension GL_ARB_enhanced_layouts : require\n" 11675 "\n" 11676 "layout(isolines, point_mode) in;\n" 11677 "\n" 11678 "layout (std140) buffer Block {\n" 11679 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 11680 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 11681 "} block;\n" 11682 "\n" 11683 "in vec4 tcs_tes[];\n" 11684 "out vec4 tes_gs;\n" 11685 "\n" 11686 "void main()\n" 11687 "{\n" 11688 " if ((BOY_TYPE(1) == block.boy) ||\n" 11689 " (MAN_TYPE(0) == block.man) )\n" 11690 " {\n" 11691 " tes_gs = vec4(1, 1, 1, 1);\n" 11692 " }\n" 11693 "\n" 11694 " tes_gs += tcs_tes[0];\n" 11695 "}\n" 11696 "\n"; 11697 static const GLchar* vs = "#version 430 core\n" 11698 "#extension GL_ARB_enhanced_layouts : require\n" 11699 "\n" 11700 "in vec4 in_vs;\n" 11701 "out vec4 vs_tcs;\n" 11702 "\n" 11703 "void main()\n" 11704 "{\n" 11705 " vs_tcs = in_vs;\n" 11706 "}\n" 11707 "\n"; 11708 static const GLchar* vs_tested = "#version 430 core\n" 11709 "#extension GL_ARB_enhanced_layouts : require\n" 11710 "\n" 11711 "layout (std140) buffer Block {\n" 11712 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 11713 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 11714 "} block;\n" 11715 "\n" 11716 "in vec4 in_vs;\n" 11717 "out vec4 vs_tcs;\n" 11718 "\n" 11719 "void main()\n" 11720 "{\n" 11721 " if ((BOY_TYPE(1) == block.boy) ||\n" 11722 " (MAN_TYPE(0) == block.man) )\n" 11723 " {\n" 11724 " vs_tcs = vec4(1, 1, 1, 1);\n" 11725 " }\n" 11726 "\n" 11727 " vs_tcs += in_vs;\n" 11728 "}\n" 11729 "\n"; 11730 11731 std::string source; 11732 testCase& test_case = m_test_cases[test_case_index]; 11733 11734 if (test_case.m_stage == stage) 11735 { 11736 GLchar buffer[16]; 11737 const GLuint boy_offset = test_case.m_boy_offset; 11738 const Utils::Type& boy_type = test_case.m_boy_type; 11739 const GLchar* boy_type_name = boy_type.GetGLSLTypeName(); 11740 const GLuint man_offset = test_case.m_man_offset; 11741 const Utils::Type& man_type = test_case.m_man_type; 11742 const GLchar* man_type_name = man_type.GetGLSLTypeName(); 11743 size_t position = 0; 11744 11745 switch (stage) 11746 { 11747 case Utils::Shader::COMPUTE: 11748 source = cs; 11749 break; 11750 case Utils::Shader::FRAGMENT: 11751 source = fs_tested; 11752 break; 11753 case Utils::Shader::GEOMETRY: 11754 source = gs_tested; 11755 break; 11756 case Utils::Shader::TESS_CTRL: 11757 source = tcs_tested; 11758 break; 11759 case Utils::Shader::TESS_EVAL: 11760 source = tes_tested; 11761 break; 11762 case Utils::Shader::VERTEX: 11763 source = vs_tested; 11764 break; 11765 default: 11766 TCU_FAIL("Invalid enum"); 11767 } 11768 11769 sprintf(buffer, "%d", boy_offset); 11770 Utils::replaceToken("BOY_OFFSET", position, buffer, source); 11771 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source); 11772 sprintf(buffer, "%d", man_offset); 11773 Utils::replaceToken("MAN_OFFSET", position, buffer, source); 11774 Utils::replaceToken("MAN_TYPE", position, man_type_name, source); 11775 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source); 11776 Utils::replaceToken("MAN_TYPE", position, man_type_name, source); 11777 } 11778 else 11779 { 11780 switch (stage) 11781 { 11782 case Utils::Shader::FRAGMENT: 11783 source = fs; 11784 break; 11785 case Utils::Shader::GEOMETRY: 11786 source = gs; 11787 break; 11788 case Utils::Shader::TESS_CTRL: 11789 source = tcs; 11790 break; 11791 case Utils::Shader::TESS_EVAL: 11792 source = tes; 11793 break; 11794 case Utils::Shader::VERTEX: 11795 source = vs; 11796 break; 11797 default: 11798 TCU_FAIL("Invalid enum"); 11799 } 11800 } 11801 11802 return source; 11803 } 11804 11805 /** Checks if stage is supported 11806 * 11807 * @param stage Shader stage 11808 * 11809 * @return true if supported, false otherwise 11810 **/ 11811 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage) 11812 { 11813 const Functions& gl = m_context.getRenderContext().getFunctions(); 11814 GLint max_supported_buffers = 0; 11815 GLenum pname = 0; 11816 11817 switch (stage) 11818 { 11819 case Utils::Shader::COMPUTE: 11820 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS; 11821 break; 11822 case Utils::Shader::FRAGMENT: 11823 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS; 11824 break; 11825 case Utils::Shader::GEOMETRY: 11826 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS; 11827 break; 11828 case Utils::Shader::TESS_CTRL: 11829 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS; 11830 break; 11831 case Utils::Shader::TESS_EVAL: 11832 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS; 11833 break; 11834 case Utils::Shader::VERTEX: 11835 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS; 11836 break; 11837 default: 11838 TCU_FAIL("Invalid enum"); 11839 } 11840 11841 gl.getIntegerv(pname, &max_supported_buffers); 11842 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 11843 11844 return 1 <= max_supported_buffers; 11845 } 11846 11847 /** Constructor 11848 * 11849 * @param context Test framework context 11850 **/ 11851 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context& context) 11852 : UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2", 11853 "Test verifies that align qualifier requires value that is a power of 2") 11854 { 11855 /* Nothing to be done here */ 11856 } 11857 11858 /** Source for given test case and stage 11859 * 11860 * @param test_case_index Index of test case 11861 * @param stage Shader stage 11862 * 11863 * @return Shader source 11864 **/ 11865 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 11866 { 11867 static const GLchar* cs = "#version 430 core\n" 11868 "#extension GL_ARB_enhanced_layouts : require\n" 11869 "\n" 11870 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 11871 "\n" 11872 "layout (std140) buffer Block {\n" 11873 " vec4 boy;\n" 11874 " layout (align = ALIGN) TYPE man;\n" 11875 "} block;\n" 11876 "\n" 11877 "writeonly uniform image2D uni_image;\n" 11878 "\n" 11879 "void main()\n" 11880 "{\n" 11881 " vec4 result = vec4(1, 0, 0.5, 1);\n" 11882 "\n" 11883 " if (TYPE(0) == block.man)\n" 11884 " {\n" 11885 " result = vec4(1, 1, 1, 1) - block.boy;\n" 11886 " }\n" 11887 "\n" 11888 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 11889 "}\n" 11890 "\n"; 11891 static const GLchar* fs = "#version 430 core\n" 11892 "#extension GL_ARB_enhanced_layouts : require\n" 11893 "\n" 11894 "in vec4 gs_fs;\n" 11895 "out vec4 fs_out;\n" 11896 "\n" 11897 "void main()\n" 11898 "{\n" 11899 " fs_out = gs_fs;\n" 11900 "}\n" 11901 "\n"; 11902 static const GLchar* fs_tested = "#version 430 core\n" 11903 "#extension GL_ARB_enhanced_layouts : require\n" 11904 "\n" 11905 "layout (std140) buffer Block {\n" 11906 " vec4 boy;\n" 11907 " layout (align = ALIGN) TYPE man;\n" 11908 "} block;\n" 11909 "\n" 11910 "in vec4 gs_fs;\n" 11911 "out vec4 fs_out;\n" 11912 "\n" 11913 "void main()\n" 11914 "{\n" 11915 " if (TYPE(0) == block.man)\n" 11916 " {\n" 11917 " fs_out = block.boy;\n" 11918 " }\n" 11919 "\n" 11920 " fs_out += gs_fs;\n" 11921 "}\n" 11922 "\n"; 11923 static const GLchar* gs = "#version 430 core\n" 11924 "#extension GL_ARB_enhanced_layouts : require\n" 11925 "\n" 11926 "layout(points) in;\n" 11927 "layout(triangle_strip, max_vertices = 4) out;\n" 11928 "\n" 11929 "in vec4 tes_gs[];\n" 11930 "out vec4 gs_fs;\n" 11931 "\n" 11932 "void main()\n" 11933 "{\n" 11934 " gs_fs = tes_gs[0];\n" 11935 " gl_Position = vec4(-1, -1, 0, 1);\n" 11936 " EmitVertex();\n" 11937 " gs_fs = tes_gs[0];\n" 11938 " gl_Position = vec4(-1, 1, 0, 1);\n" 11939 " EmitVertex();\n" 11940 " gs_fs = tes_gs[0];\n" 11941 " gl_Position = vec4(1, -1, 0, 1);\n" 11942 " EmitVertex();\n" 11943 " gs_fs = tes_gs[0];\n" 11944 " gl_Position = vec4(1, 1, 0, 1);\n" 11945 " EmitVertex();\n" 11946 "}\n" 11947 "\n"; 11948 static const GLchar* gs_tested = "#version 430 core\n" 11949 "#extension GL_ARB_enhanced_layouts : require\n" 11950 "\n" 11951 "layout(points) in;\n" 11952 "layout(triangle_strip, max_vertices = 4) out;\n" 11953 "\n" 11954 "layout (std140) buffer Block {\n" 11955 " vec4 boy;\n" 11956 " layout (align = ALIGN) TYPE man;\n" 11957 "} block;\n" 11958 "\n" 11959 "in vec4 tes_gs[];\n" 11960 "out vec4 gs_fs;\n" 11961 "\n" 11962 "void main()\n" 11963 "{\n" 11964 " if (TYPE(0) == block.man)\n" 11965 " {\n" 11966 " gs_fs = block.boy;\n" 11967 " }\n" 11968 "\n" 11969 " gs_fs += tes_gs[0];\n" 11970 " gl_Position = vec4(-1, -1, 0, 1);\n" 11971 " EmitVertex();\n" 11972 " gs_fs += tes_gs[0];\n" 11973 " gl_Position = vec4(-1, 1, 0, 1);\n" 11974 " EmitVertex();\n" 11975 " gs_fs += tes_gs[0];\n" 11976 " gl_Position = vec4(1, -1, 0, 1);\n" 11977 " EmitVertex();\n" 11978 " gs_fs += tes_gs[0];\n" 11979 " gl_Position = vec4(1, 1, 0, 1);\n" 11980 " EmitVertex();\n" 11981 "}\n" 11982 "\n"; 11983 static const GLchar* tcs = "#version 430 core\n" 11984 "#extension GL_ARB_enhanced_layouts : require\n" 11985 "\n" 11986 "layout(vertices = 1) out;\n" 11987 "\n" 11988 "in vec4 vs_tcs[];\n" 11989 "out vec4 tcs_tes[];\n" 11990 "\n" 11991 "void main()\n" 11992 "{\n" 11993 "\n" 11994 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 11995 "\n" 11996 " gl_TessLevelOuter[0] = 1.0;\n" 11997 " gl_TessLevelOuter[1] = 1.0;\n" 11998 " gl_TessLevelOuter[2] = 1.0;\n" 11999 " gl_TessLevelOuter[3] = 1.0;\n" 12000 " gl_TessLevelInner[0] = 1.0;\n" 12001 " gl_TessLevelInner[1] = 1.0;\n" 12002 "}\n" 12003 "\n"; 12004 static const GLchar* tcs_tested = "#version 430 core\n" 12005 "#extension GL_ARB_enhanced_layouts : require\n" 12006 "\n" 12007 "layout(vertices = 1) out;\n" 12008 "\n" 12009 "layout (std140) buffer Block {\n" 12010 " vec4 boy;\n" 12011 " layout (align = ALIGN) TYPE man;\n" 12012 "} block;\n" 12013 "\n" 12014 "in vec4 vs_tcs[];\n" 12015 "out vec4 tcs_tes[];\n" 12016 "\n" 12017 "void main()\n" 12018 "{\n" 12019 " if (TYPE(0) == block.man)\n" 12020 " {\n" 12021 " tcs_tes[gl_InvocationID] = block.boy;\n" 12022 " }\n" 12023 "\n" 12024 "\n" 12025 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n" 12026 "\n" 12027 " gl_TessLevelOuter[0] = 1.0;\n" 12028 " gl_TessLevelOuter[1] = 1.0;\n" 12029 " gl_TessLevelOuter[2] = 1.0;\n" 12030 " gl_TessLevelOuter[3] = 1.0;\n" 12031 " gl_TessLevelInner[0] = 1.0;\n" 12032 " gl_TessLevelInner[1] = 1.0;\n" 12033 "}\n" 12034 "\n"; 12035 static const GLchar* tes = "#version 430 core\n" 12036 "#extension GL_ARB_enhanced_layouts : require\n" 12037 "\n" 12038 "layout(isolines, point_mode) in;\n" 12039 "\n" 12040 "in vec4 tcs_tes[];\n" 12041 "out vec4 tes_gs;\n" 12042 "\n" 12043 "void main()\n" 12044 "{\n" 12045 " tes_gs = tcs_tes[0];\n" 12046 "}\n" 12047 "\n"; 12048 static const GLchar* tes_tested = "#version 430 core\n" 12049 "#extension GL_ARB_enhanced_layouts : require\n" 12050 "\n" 12051 "layout(isolines, point_mode) in;\n" 12052 "\n" 12053 "layout (std140) buffer Block {\n" 12054 " vec4 boy;\n" 12055 " layout (align = ALIGN) TYPE man;\n" 12056 "} block;\n" 12057 "\n" 12058 "in vec4 tcs_tes[];\n" 12059 "out vec4 tes_gs;\n" 12060 "\n" 12061 "void main()\n" 12062 "{\n" 12063 " if (TYPE(0) == block.man)\n" 12064 " {\n" 12065 " tes_gs = block.boy;\n" 12066 " }\n" 12067 "\n" 12068 " tes_gs += tcs_tes[0];\n" 12069 "}\n" 12070 "\n"; 12071 static const GLchar* vs = "#version 430 core\n" 12072 "#extension GL_ARB_enhanced_layouts : require\n" 12073 "\n" 12074 "in vec4 in_vs;\n" 12075 "out vec4 vs_tcs;\n" 12076 "\n" 12077 "void main()\n" 12078 "{\n" 12079 " vs_tcs = in_vs;\n" 12080 "}\n" 12081 "\n"; 12082 static const GLchar* vs_tested = "#version 430 core\n" 12083 "#extension GL_ARB_enhanced_layouts : require\n" 12084 "\n" 12085 "layout (std140) buffer Block {\n" 12086 " vec4 boy;\n" 12087 " layout (align = ALIGN) TYPE man;\n" 12088 "} block;\n" 12089 "\n" 12090 "in vec4 in_vs;\n" 12091 "out vec4 vs_tcs;\n" 12092 "\n" 12093 "void main()\n" 12094 "{\n" 12095 " if (TYPE(0) == block.man)\n" 12096 " {\n" 12097 " vs_tcs = block.boy;\n" 12098 " }\n" 12099 "\n" 12100 " vs_tcs += in_vs;\n" 12101 "}\n" 12102 "\n"; 12103 12104 std::string source; 12105 testCase& test_case = m_test_cases[test_case_index]; 12106 12107 if (test_case.m_stage == stage) 12108 { 12109 GLchar buffer[16]; 12110 const GLuint alignment = test_case.m_alignment; 12111 const Utils::Type& type = test_case.m_type; 12112 const GLchar* type_name = type.GetGLSLTypeName(); 12113 size_t position = 0; 12114 12115 switch (stage) 12116 { 12117 case Utils::Shader::COMPUTE: 12118 source = cs; 12119 break; 12120 case Utils::Shader::FRAGMENT: 12121 source = fs_tested; 12122 break; 12123 case Utils::Shader::GEOMETRY: 12124 source = gs_tested; 12125 break; 12126 case Utils::Shader::TESS_CTRL: 12127 source = tcs_tested; 12128 break; 12129 case Utils::Shader::TESS_EVAL: 12130 source = tes_tested; 12131 break; 12132 case Utils::Shader::VERTEX: 12133 source = vs_tested; 12134 break; 12135 default: 12136 TCU_FAIL("Invalid enum"); 12137 } 12138 12139 sprintf(buffer, "%d", alignment); 12140 Utils::replaceToken("ALIGN", position, buffer, source); 12141 Utils::replaceToken("TYPE", position, type_name, source); 12142 Utils::replaceToken("TYPE", position, type_name, source); 12143 } 12144 else 12145 { 12146 switch (stage) 12147 { 12148 case Utils::Shader::FRAGMENT: 12149 source = fs; 12150 break; 12151 case Utils::Shader::GEOMETRY: 12152 source = gs; 12153 break; 12154 case Utils::Shader::TESS_CTRL: 12155 source = tcs; 12156 break; 12157 case Utils::Shader::TESS_EVAL: 12158 source = tes; 12159 break; 12160 case Utils::Shader::VERTEX: 12161 source = vs; 12162 break; 12163 default: 12164 TCU_FAIL("Invalid enum"); 12165 } 12166 } 12167 12168 return source; 12169 } 12170 12171 /** Checks if stage is supported 12172 * 12173 * @param stage Shader stage 12174 * 12175 * @return true if supported, false otherwise 12176 **/ 12177 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage) 12178 { 12179 const Functions& gl = m_context.getRenderContext().getFunctions(); 12180 GLint max_supported_buffers = 0; 12181 GLenum pname = 0; 12182 12183 switch (stage) 12184 { 12185 case Utils::Shader::COMPUTE: 12186 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS; 12187 break; 12188 case Utils::Shader::FRAGMENT: 12189 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS; 12190 break; 12191 case Utils::Shader::GEOMETRY: 12192 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS; 12193 break; 12194 case Utils::Shader::TESS_CTRL: 12195 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS; 12196 break; 12197 case Utils::Shader::TESS_EVAL: 12198 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS; 12199 break; 12200 case Utils::Shader::VERTEX: 12201 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS; 12202 break; 12203 default: 12204 TCU_FAIL("Invalid enum"); 12205 } 12206 12207 gl.getIntegerv(pname, &max_supported_buffers); 12208 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 12209 12210 return 1 <= max_supported_buffers; 12211 } 12212 12213 /** Constructor 12214 * 12215 * @param context Test framework context 12216 **/ 12217 SSBAlignmentTest::SSBAlignmentTest(deqp::Context& context) 12218 : TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer") 12219 { 12220 } 12221 12222 /** Get interface of program 12223 * 12224 * @param ignored 12225 * @param program_interface Interface of program 12226 * @param varying_passthrough Collection of connections between in and out variables 12227 **/ 12228 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface& program_interface, 12229 Utils::VaryingPassthrough& varying_passthrough) 12230 { 12231 static const Utils::Type vec4 = Utils::Type::vec4; 12232 12233 #if WRKARD_UNIFORMBLOCKALIGNMENT 12234 12235 static const GLuint block_align = 16; 12236 12237 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */ 12238 12239 static const GLuint block_align = 64; 12240 12241 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */ 12242 12243 static const GLuint fifth_align = 16; 12244 static const GLuint vec4_stride = 16; 12245 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */ 12246 12247 const GLuint first_offset = 0; /* vec4 at 0 */ 12248 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */ 12249 const GLuint third_offset = 12250 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */ 12251 const GLuint fourth_offset = 12252 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */ 12253 const GLuint fifth_offset = 12254 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */ 12255 const GLuint sixth_offset = 12256 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */ 12257 12258 Utils::Interface* structure = program_interface.Structure("Data"); 12259 12260 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4, 12261 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */); 12262 12263 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float, 12264 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(), 12265 Utils::Type::vec4.GetSize() /* offset */); 12266 12267 /* Prepare Block */ 12268 Utils::Interface* vs_buf_Block = program_interface.Block("vs_buf_Block"); 12269 12270 vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4, 12271 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */); 12272 12273 vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure, 12274 0 /* n_array_elements */, data_stride, second_offset); 12275 12276 vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure, 12277 2 /* n_array_elements */, data_stride, third_offset); 12278 12279 vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4, 12280 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset); 12281 12282 vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4, 12283 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset); 12284 12285 vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure, 12286 0 /* n_array_elements */, data_stride, sixth_offset); 12287 12288 const GLuint stride = calculateStride(*vs_buf_Block); 12289 m_data.resize(stride); 12290 generateData(*vs_buf_Block, 0, m_data); 12291 12292 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 12293 12294 /* Add uniform BLOCK */ 12295 #if WRKARD_UNIFORMBLOCKALIGNMENT 12296 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0, 12297 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size()); 12298 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */ 12299 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0, 12300 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size()); 12301 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */ 12302 12303 program_interface.CloneVertexInterface(varying_passthrough); 12304 } 12305 12306 /** Selects if "draw" stages are relevant for test 12307 * 12308 * @param ignored 12309 * 12310 * @return true if all stages support shader storage buffers, false otherwise 12311 **/ 12312 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */) 12313 { 12314 const Functions& gl = m_context.getRenderContext().getFunctions(); 12315 GLint gs_supported_buffers = 0; 12316 GLint tcs_supported_buffers = 0; 12317 GLint tes_supported_buffers = 0; 12318 GLint vs_supported_buffers = 0; 12319 12320 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers); 12321 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers); 12322 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers); 12323 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers); 12324 12325 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 12326 12327 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) && 12328 (1 <= vs_supported_buffers)); 12329 } 12330 12331 /** Constructor 12332 * 12333 * @param context Test framework context 12334 **/ 12335 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context) 12336 : TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected") 12337 { 12338 } 12339 12340 /** Constructor 12341 * 12342 * @param context Test context 12343 * @param test_name Name of test 12344 * @param test_description Description of test 12345 **/ 12346 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context, const glw::GLchar* test_name, 12347 const glw::GLchar* test_description) 12348 : TextureTestBase(context, test_name, test_description) 12349 { 12350 } 12351 12352 /** Get interface of program 12353 * 12354 * @param test_case_index Test case 12355 * @param program_interface Interface of program 12356 * @param varying_passthrough Collection of connections between in and out variables 12357 **/ 12358 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface, 12359 Utils::VaryingPassthrough& varying_passthrough) 12360 { 12361 const Utils::Type type = getType(test_case_index); 12362 12363 m_first_data = type.GenerateDataPacked(); 12364 m_last_data = type.GenerateDataPacked(); 12365 12366 prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough); 12367 prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough); 12368 prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough); 12369 prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough); 12370 prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough); 12371 } 12372 12373 /** Get type name 12374 * 12375 * @param test_case_index Index of test case 12376 * 12377 * @return Name of type test in test_case_index 12378 **/ 12379 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index) 12380 { 12381 return getTypeName(test_case_index); 12382 } 12383 12384 /** Returns number of types to test 12385 * 12386 * @return Number of types, 34 12387 **/ 12388 glw::GLuint VaryingLocationsTest::getTestCaseNumber() 12389 { 12390 return getTypesNumber(); 12391 } 12392 12393 /** Selects if "compute" stage is relevant for test 12394 * 12395 * @param ignored 12396 * 12397 * @return false 12398 **/ 12399 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */) 12400 { 12401 return false; 12402 } 12403 12404 /** 12405 * 12406 * 12407 **/ 12408 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc) 12409 { 12410 GLchar buffer[16]; 12411 std::string globals = "const uint first_input_location = 0u;\n" 12412 "const uint first_output_location = 0u;\n" 12413 "const uint last_input_location = LAST_INPUTu;\n" 12414 "const uint last_output_location = LAST_OUTPUTu;\n"; 12415 size_t position = 100; /* Skip first part */ 12416 12417 sprintf(buffer, "%d", last_in_loc); 12418 Utils::replaceToken("LAST_INPUT", position, buffer, globals); 12419 12420 sprintf(buffer, "%d", last_out_loc); 12421 Utils::replaceToken("LAST_OUTPUT", position, buffer, globals); 12422 12423 return globals; 12424 } 12425 12426 /** 12427 * 12428 **/ 12429 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type, 12430 Utils::ProgramInterface& program_interface, 12431 Utils::VaryingPassthrough& varying_passthrough) 12432 { 12433 const GLuint array_length = 1; 12434 const GLuint first_in_loc = 0; 12435 const GLuint first_out_loc = 0; 12436 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length, false); 12437 size_t position = 0; 12438 12439 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT); 12440 12441 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT); 12442 12443 const GLchar* qual_first_in = "layout (location = first_input_location)"; 12444 const GLchar* qual_first_out = "layout (location = first_output_location)"; 12445 const GLchar* qual_last_in = "layout (location = last_input_location)"; 12446 const GLchar* qual_last_out = "layout (location = last_output_location)"; 12447 12448 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage); 12449 const GLuint type_size = type.GetSize(); 12450 12451 std::string first_in_name = "PREFIXfirst"; 12452 std::string first_out_name = "PREFIXfirst"; 12453 std::string last_in_name = "PREFIXlast"; 12454 std::string last_out_name = "PREFIXlast"; 12455 12456 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name); 12457 position = 0; 12458 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name); 12459 position = 0; 12460 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name); 12461 position = 0; 12462 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name); 12463 12464 if (Utils::Shader::FRAGMENT == stage) 12465 { 12466 qual_first_in = "layout (location = first_input_location) flat"; 12467 qual_last_in = "layout (location = last_input_location) flat"; 12468 } 12469 if (Utils::Shader::GEOMETRY == stage) 12470 { 12471 qual_first_out = "layout (location = first_output_location) flat"; 12472 qual_last_out = "layout (location = last_output_location) flat"; 12473 } 12474 12475 Utils::Variable* first_in = si.Input( 12476 first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */, 12477 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */, 12478 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */); 12479 12480 Utils::Variable* last_in = 12481 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */, 12482 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 12483 0u /* n_array_elements */, 0u /* stride */, type_size /* offset */, 12484 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */); 12485 12486 if (Utils::Shader::FRAGMENT != stage) 12487 { 12488 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length, false); 12489 12490 Utils::Variable* first_out = 12491 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */, 12492 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 12493 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, 12494 m_first_data.size() /* data_size */); 12495 12496 Utils::Variable* last_out = si.Output( 12497 last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */, 12498 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */, 12499 0u /* stride */, 0u /* offset */, (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */); 12500 12501 si.m_globals = prepareGlobals(last_in_loc, last_out_loc); 12502 12503 varying_passthrough.Add(stage, first_in, first_out); 12504 varying_passthrough.Add(stage, last_in, last_out); 12505 } 12506 else 12507 { 12508 /* No outputs for fragment shader, so last_output_location can be 0 */ 12509 si.m_globals = prepareGlobals(last_in_loc, 0); 12510 } 12511 } 12512 12513 /** This test should be run with separable programs 12514 * 12515 * @param ignored 12516 * 12517 * @return true 12518 **/ 12519 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */) 12520 { 12521 return false; 12522 } 12523 12524 /* Constants used by VertexAttribLocationsTest */ 12525 const GLuint VertexAttribLocationsTest::m_base_vertex = 4; 12526 const GLuint VertexAttribLocationsTest::m_base_instance = 2; 12527 const GLuint VertexAttribLocationsTest::m_loc_vertex = 2; 12528 const GLuint VertexAttribLocationsTest::m_loc_instance = 5; 12529 const GLuint VertexAttribLocationsTest::m_n_instances = 4; 12530 12531 /** Constructor 12532 * 12533 * @param context Test framework context 12534 **/ 12535 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context& context) 12536 : TextureTestBase(context, "vertex_attrib_locations", 12537 "Test verifies that attribute locations are respected by drawing operations") 12538 { 12539 } 12540 12541 /** Execute proper draw command for test case 12542 * 12543 * @param test_case_index Index of test case 12544 **/ 12545 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index) 12546 { 12547 const Functions& gl = m_context.getRenderContext().getFunctions(); 12548 12549 switch (test_case_index) 12550 { 12551 case DRAWARRAYS: 12552 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 12553 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 12554 break; 12555 case DRAWARRAYSINSTANCED: 12556 gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances); 12557 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced"); 12558 break; 12559 case DRAWELEMENTS: 12560 gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL); 12561 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements"); 12562 break; 12563 case DRAWELEMENTSBASEVERTEX: 12564 gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_base_vertex); 12565 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex"); 12566 break; 12567 case DRAWELEMENTSINSTANCED: 12568 gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances); 12569 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced"); 12570 break; 12571 case DRAWELEMENTSINSTANCEDBASEINSTANCE: 12572 gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances, 12573 m_base_instance); 12574 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance"); 12575 break; 12576 case DRAWELEMENTSINSTANCEDBASEVERTEX: 12577 gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances, 12578 m_base_vertex); 12579 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex"); 12580 break; 12581 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE: 12582 gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, 12583 m_n_instances, m_base_vertex, m_base_instance); 12584 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance"); 12585 break; 12586 default: 12587 TCU_FAIL("Invalid enum"); 12588 } 12589 } 12590 12591 /** Get interface of program 12592 * 12593 * @param ignored 12594 * @param program_interface Interface of program 12595 * @param ignored 12596 **/ 12597 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */, 12598 Utils::ProgramInterface& program_interface, 12599 Utils::VaryingPassthrough& /* varying_passthrough */) 12600 { 12601 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 12602 12603 /* Globals */ 12604 si.m_globals = "const uint vertex_index_location = 2;\n" 12605 "const uint instance_index_location = 5;\n"; 12606 12607 /* Attributes */ 12608 si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */, 12609 0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */, 12610 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */, 12611 (GLvoid*)0 /* data */, 0 /* data_size */); 12612 si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */, 12613 0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */, 12614 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */, 12615 (GLvoid*)0 /* data */, 0 /* data_size */); 12616 } 12617 12618 /** Get name of test case 12619 * 12620 * @param test_case_index Index of test case 12621 * 12622 * @return Name of test case 12623 **/ 12624 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index) 12625 { 12626 std::string result; 12627 12628 switch (test_case_index) 12629 { 12630 case DRAWARRAYS: 12631 result = "DrawArrays"; 12632 break; 12633 case DRAWARRAYSINSTANCED: 12634 result = "DrawArraysInstanced"; 12635 break; 12636 case DRAWELEMENTS: 12637 result = "DrawElements"; 12638 break; 12639 case DRAWELEMENTSBASEVERTEX: 12640 result = "DrawElementsBaseVertex"; 12641 break; 12642 case DRAWELEMENTSINSTANCED: 12643 result = "DrawElementsInstanced"; 12644 break; 12645 case DRAWELEMENTSINSTANCEDBASEINSTANCE: 12646 result = "DrawElementsInstancedBaseInstance"; 12647 break; 12648 case DRAWELEMENTSINSTANCEDBASEVERTEX: 12649 result = "DrawElementsInstancedBaseVertex"; 12650 break; 12651 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE: 12652 result = "DrawElementsInstancedBaseVertexBaseInstance"; 12653 break; 12654 default: 12655 TCU_FAIL("Invalid enum"); 12656 } 12657 12658 return result; 12659 } 12660 12661 /** Get number of test cases 12662 * 12663 * @return Number of test cases 12664 **/ 12665 GLuint VertexAttribLocationsTest::getTestCaseNumber() 12666 { 12667 return TESTCASES_MAX; 12668 } 12669 12670 /** Prepare code snippet that will verify in and uniform variables 12671 * 12672 * @param ignored 12673 * @param ignored 12674 * @param stage Shader stage 12675 * 12676 * @return Code that verify variables 12677 **/ 12678 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */, 12679 Utils::ProgramInterface& /* program_interface */, 12680 Utils::Shader::STAGES stage) 12681 { 12682 std::string verification; 12683 12684 if (Utils::Shader::VERTEX == stage) 12685 { 12686 12687 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE 12688 12689 verification = "if (gl_InstanceID != instance_index)\n" 12690 " {\n" 12691 " result = 12u;\n" 12692 " }\n" 12693 " else if (gl_VertexID != vertex_index)\n" 12694 " {\n" 12695 " result = 11u;\n" 12696 " }\n"; 12697 12698 #else 12699 12700 verification = "if ((gl_VertexID != vertex_index) ||\n" 12701 " (gl_InstanceID != instance_index) )\n" 12702 " {\n" 12703 " result = 0u;\n" 12704 " }\n"; 12705 12706 #endif 12707 } 12708 else 12709 { 12710 verification = ""; 12711 } 12712 12713 return verification; 12714 } 12715 12716 /** Selects if "compute" stage is relevant for test 12717 * 12718 * @param ignored 12719 * 12720 * @return false 12721 **/ 12722 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */) 12723 { 12724 return false; 12725 } 12726 12727 /** Prepare attributes, vertex array object and array buffer 12728 * 12729 * @param ignored 12730 * @param ignored Interface of program 12731 * @param buffer Array buffer 12732 * @param vao Vertex array object 12733 **/ 12734 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */, 12735 Utils::ProgramInterface& /* program_interface */, 12736 Utils::Buffer& buffer, Utils::VertexArray& vao) 12737 { 12738 static const GLuint vertex_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; 12739 static const GLuint instance_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; 12740 12741 std::vector<GLuint> buffer_data; 12742 buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */ 12743 12744 GLubyte* ptr = (GLubyte*)&buffer_data[0]; 12745 12746 /* 12747 When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on, 12748 So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER 12749 */ 12750 if (test_case_index >= 2) 12751 { 12752 buffer.m_buffer = Utils::Buffer::Element; 12753 } 12754 vao.Bind(); 12755 buffer.Bind(); 12756 12757 vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */, 12758 0 /* stride */, 0 /* offset */); 12759 12760 vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */, 12761 false /* normalized */, 0 /* stride */, (GLvoid*)sizeof(vertex_index_data) /* offset */); 12762 // when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance 12763 // the instancecount is 4, the baseinstance is 2, the divisor should be set 2 12764 bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE || 12765 test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE); 12766 vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */, 12767 isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */); 12768 12769 memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data)); 12770 memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data)); 12771 12772 buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr); 12773 } 12774 12775 /** This test should be run with separable programs 12776 * 12777 * @param ignored 12778 * 12779 * @return true 12780 **/ 12781 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */) 12782 { 12783 return false; 12784 } 12785 12786 /** Constructor 12787 * 12788 * @param context Test framework context 12789 **/ 12790 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context& context) 12791 : VaryingLocationsTest(context, "varying_array_locations", 12792 "Test verifies that input and output locations are respected for arrays") 12793 { 12794 } 12795 12796 /** 12797 * 12798 **/ 12799 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type, 12800 Utils::ProgramInterface& program_interface, 12801 Utils::VaryingPassthrough& varying_passthrough) 12802 { 12803 const GLuint array_length = 1u; 12804 const GLuint first_in_loc = 0; 12805 const GLuint first_out_loc = 0; 12806 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length, false); 12807 size_t position = 0; 12808 12809 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT); 12810 12811 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT); 12812 12813 const GLchar* qual_first_in = "layout (location = first_input_location)"; 12814 const GLchar* qual_first_out = "layout (location = first_output_location)"; 12815 const GLchar* qual_last_in = "layout (location = last_input_location)"; 12816 const GLchar* qual_last_out = "layout (location = last_output_location)"; 12817 12818 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage); 12819 const GLuint type_size = type.GetSize(); 12820 12821 std::string first_in_name = "PREFIXfirst"; 12822 std::string first_out_name = "PREFIXfirst"; 12823 std::string last_in_name = "PREFIXlast"; 12824 std::string last_out_name = "PREFIXlast"; 12825 12826 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name); 12827 position = 0; 12828 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name); 12829 position = 0; 12830 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name); 12831 position = 0; 12832 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name); 12833 12834 if (Utils::Shader::FRAGMENT == stage) 12835 { 12836 qual_first_in = "layout (location = first_input_location) flat"; 12837 qual_last_in = "layout (location = last_input_location) flat"; 12838 } 12839 if (Utils::Shader::GEOMETRY == stage) 12840 { 12841 qual_first_out = "layout (location = first_output_location) flat"; 12842 qual_last_out = "layout (location = last_output_location) flat"; 12843 } 12844 12845 Utils::Variable* first_in = 12846 si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */, 12847 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 12848 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */, 12849 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */); 12850 12851 Utils::Variable* last_in = 12852 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */, 12853 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 12854 array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */, 12855 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */); 12856 12857 if (Utils::Shader::FRAGMENT != stage) 12858 { 12859 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length, false); 12860 12861 Utils::Variable* first_out = 12862 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */, 12863 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 12864 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */, 12865 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */); 12866 12867 Utils::Variable* last_out = 12868 si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */, 12869 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 12870 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */, 12871 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */); 12872 12873 si.m_globals = prepareGlobals(last_in_loc, last_out_loc); 12874 12875 varying_passthrough.Add(stage, first_in, first_out); 12876 varying_passthrough.Add(stage, last_in, last_out); 12877 } 12878 else 12879 { 12880 /* No outputs for fragment shader, so last_output_location can be 0 */ 12881 si.m_globals = prepareGlobals(last_in_loc, 0); 12882 } 12883 } 12884 12885 /** Constructor 12886 * 12887 * @param context Test framework context 12888 **/ 12889 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context& context) 12890 : TextureTestBase(context, "varying_structure_locations", 12891 "Test verifies that locations are respected when structures are used as in and out ") 12892 { 12893 } 12894 12895 /** Prepare code snippet that will pass in variables to out variables 12896 * 12897 * @param ignored 12898 * @param varying_passthrough Collection of connections between in and out variables 12899 * @param stage Shader stage 12900 * 12901 * @return Code that pass in variables to next stage 12902 **/ 12903 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */, 12904 Utils::VaryingPassthrough& varying_passthrough, 12905 Utils::Shader::STAGES stage) 12906 { 12907 std::string result; 12908 12909 if (Utils::Shader::VERTEX != stage) 12910 { 12911 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage); 12912 } 12913 else 12914 { 12915 result = " vs_tcs_output[0].single = vs_in_single[0];\n" 12916 " vs_tcs_output[0].array[0] = vs_in_array[0];\n"; 12917 } 12918 12919 return result; 12920 } 12921 12922 /** Get interface of program 12923 * 12924 * @param test_case_index Test case 12925 * @param program_interface Interface of program 12926 * @param varying_passthrough Collection of connections between in and out variables 12927 **/ 12928 void VaryingStructureLocationsTest::getProgramInterface(GLuint test_case_index, 12929 Utils::ProgramInterface& program_interface, 12930 Utils::VaryingPassthrough& varying_passthrough) 12931 { 12932 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 12933 const Utils::Type type = getType(test_case_index); 12934 12935 /* Prepare data */ 12936 // We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct 12937 m_single_data = type.GenerateDataPacked(); 12938 m_array_data = type.GenerateDataPacked(); 12939 12940 m_data.resize(m_single_data.size() + m_array_data.size()); 12941 GLubyte* ptr = (GLubyte*)&m_data[0]; 12942 memcpy(ptr, &m_single_data[0], m_single_data.size()); 12943 memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size()); 12944 12945 Utils::Interface* structure = program_interface.Structure("Data"); 12946 12947 structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */, 12948 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */); 12949 12950 // the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed. 12951 structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type, 12952 false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */); 12953 12954 si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */, 12955 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_single_data[0] /* data */, 12956 m_single_data.size() /* data_size */); 12957 12958 si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */, 12959 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */, 12960 (GLvoid*)&m_array_data[0] /* data */, m_array_data.size() /* data_size */); 12961 12962 si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure, 12963 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */, 12964 m_data.size() /* data_size */); 12965 12966 program_interface.CloneVertexInterface(varying_passthrough); 12967 } 12968 12969 /** Get type name 12970 * 12971 * @param test_case_index Index of test case 12972 * 12973 * @return Name of type test in test_case_index 12974 **/ 12975 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index) 12976 { 12977 return getTypeName(test_case_index); 12978 } 12979 12980 /** Returns number of types to test 12981 * 12982 * @return Number of types, 34 12983 **/ 12984 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber() 12985 { 12986 return getTypesNumber(); 12987 } 12988 12989 /** Selects if "compute" stage is relevant for test 12990 * 12991 * @param ignored 12992 * 12993 * @return false 12994 **/ 12995 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */) 12996 { 12997 return false; 12998 } 12999 13000 /** This test should be run with separable programs 13001 * 13002 * @param ignored 13003 * 13004 * @return true 13005 **/ 13006 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */) 13007 { 13008 return false; 13009 } 13010 13011 /** Constructor 13012 * 13013 * @param context Test context 13014 * @param test_name Name of test 13015 * @param test_description Description of test 13016 **/ 13017 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context& context) 13018 : NegativeTestBase(context, "varying_structure_member_location", 13019 "Test verifies that compiler does not allow location qualifier on member of strucure") 13020 { 13021 } 13022 13023 /** Source for given test case and stage 13024 * 13025 * @param test_case_index Index of test case 13026 * @param stage Shader stage 13027 * 13028 * @return Shader source 13029 **/ 13030 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 13031 { 13032 static const GLchar* struct_definition = "struct Data {\n" 13033 " vec4 gohan;\n" 13034 " layout (location = 4) vec4 goten;\n" 13035 "};\n"; 13036 static const GLchar* input_var = "in Data data;\n"; 13037 static const GLchar* output_var = "out Data data;\n"; 13038 static const GLchar* input_use = " result += data.gohan + data.goten;\n"; 13039 static const GLchar* output_use = " data.gohan = result / 2;\n" 13040 " data.goten = result / 4 - data.gohan;\n"; 13041 static const GLchar* fs = "#version 430 core\n" 13042 "#extension GL_ARB_enhanced_layouts : require\n" 13043 "\n" 13044 "in vec4 gs_fs;\n" 13045 "out vec4 fs_out;\n" 13046 "\n" 13047 "void main()\n" 13048 "{\n" 13049 " fs_out = gs_fs;\n" 13050 "}\n" 13051 "\n"; 13052 static const GLchar* fs_tested = "#version 430 core\n" 13053 "#extension GL_ARB_enhanced_layouts : require\n" 13054 "\n" 13055 "STRUCT_DEFINITION" 13056 "\n" 13057 "VARIABLE_DEFINITION" 13058 "\n" 13059 "in vec4 gs_fs;\n" 13060 "out vec4 fs_out;\n" 13061 "\n" 13062 "void main()\n" 13063 "{\n" 13064 " vec4 result = gs_fs;\n" 13065 "\n" 13066 "VARIABLE_USE" 13067 "\n" 13068 " fs_out += result;\n" 13069 "}\n" 13070 "\n"; 13071 static const GLchar* gs = "#version 430 core\n" 13072 "#extension GL_ARB_enhanced_layouts : require\n" 13073 "\n" 13074 "layout(points) in;\n" 13075 "layout(triangle_strip, max_vertices = 4) out;\n" 13076 "\n" 13077 "in vec4 tes_gs[];\n" 13078 "out vec4 gs_fs;\n" 13079 "\n" 13080 "void main()\n" 13081 "{\n" 13082 " gs_fs = tes_gs[0];\n" 13083 " gl_Position = vec4(-1, -1, 0, 1);\n" 13084 " EmitVertex();\n" 13085 " gs_fs = tes_gs[0];\n" 13086 " gl_Position = vec4(-1, 1, 0, 1);\n" 13087 " EmitVertex();\n" 13088 " gs_fs = tes_gs[0];\n" 13089 " gl_Position = vec4(1, -1, 0, 1);\n" 13090 " EmitVertex();\n" 13091 " gs_fs = tes_gs[0];\n" 13092 " gl_Position = vec4(1, 1, 0, 1);\n" 13093 " EmitVertex();\n" 13094 "}\n" 13095 "\n"; 13096 static const GLchar* gs_tested = "#version 430 core\n" 13097 "#extension GL_ARB_enhanced_layouts : require\n" 13098 "\n" 13099 "layout(points) in;\n" 13100 "layout(triangle_strip, max_vertices = 4) out;\n" 13101 "\n" 13102 "STRUCT_DEFINITION" 13103 "\n" 13104 "VARIABLE_DEFINITION" 13105 "\n" 13106 "in vec4 tes_gs[];\n" 13107 "out vec4 gs_fs;\n" 13108 "\n" 13109 "void main()\n" 13110 "{\n" 13111 " vec4 result = tes_gs[0];\n" 13112 "\n" 13113 "VARIABLE_USE" 13114 "\n" 13115 " gs_fs = result;\n" 13116 " gl_Position = vec4(-1, -1, 0, 1);\n" 13117 " EmitVertex();\n" 13118 " gs_fs = result;\n" 13119 " gl_Position = vec4(-1, 1, 0, 1);\n" 13120 " EmitVertex();\n" 13121 " gs_fs = result;\n" 13122 " gl_Position = vec4(1, -1, 0, 1);\n" 13123 " EmitVertex();\n" 13124 " gs_fs = result;\n" 13125 " gl_Position = vec4(1, 1, 0, 1);\n" 13126 " EmitVertex();\n" 13127 "}\n" 13128 "\n"; 13129 static const GLchar* tcs = "#version 430 core\n" 13130 "#extension GL_ARB_enhanced_layouts : require\n" 13131 "\n" 13132 "layout(vertices = 1) out;\n" 13133 "\n" 13134 "in vec4 vs_tcs[];\n" 13135 "out vec4 tcs_tes[];\n" 13136 "\n" 13137 "void main()\n" 13138 "{\n" 13139 "\n" 13140 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 13141 "\n" 13142 " gl_TessLevelOuter[0] = 1.0;\n" 13143 " gl_TessLevelOuter[1] = 1.0;\n" 13144 " gl_TessLevelOuter[2] = 1.0;\n" 13145 " gl_TessLevelOuter[3] = 1.0;\n" 13146 " gl_TessLevelInner[0] = 1.0;\n" 13147 " gl_TessLevelInner[1] = 1.0;\n" 13148 "}\n" 13149 "\n"; 13150 static const GLchar* tcs_tested = "#version 430 core\n" 13151 "#extension GL_ARB_enhanced_layouts : require\n" 13152 "\n" 13153 "layout(vertices = 1) out;\n" 13154 "\n" 13155 "STRUCT_DEFINITION" 13156 "\n" 13157 "VARIABLE_DEFINITION" 13158 "\n" 13159 "in vec4 vs_tcs[];\n" 13160 "out vec4 tcs_tes[];\n" 13161 "\n" 13162 "void main()\n" 13163 "{\n" 13164 " vec4 result = vs_tcs[gl_InvocationID];\n" 13165 "\n" 13166 "VARIABLE_USE" 13167 "\n" 13168 " tcs_tes[gl_InvocationID] = result;\n" 13169 "\n" 13170 " gl_TessLevelOuter[0] = 1.0;\n" 13171 " gl_TessLevelOuter[1] = 1.0;\n" 13172 " gl_TessLevelOuter[2] = 1.0;\n" 13173 " gl_TessLevelOuter[3] = 1.0;\n" 13174 " gl_TessLevelInner[0] = 1.0;\n" 13175 " gl_TessLevelInner[1] = 1.0;\n" 13176 "}\n" 13177 "\n"; 13178 static const GLchar* tes = "#version 430 core\n" 13179 "#extension GL_ARB_enhanced_layouts : require\n" 13180 "\n" 13181 "layout(isolines, point_mode) in;\n" 13182 "\n" 13183 "in vec4 tcs_tes[];\n" 13184 "out vec4 tes_gs;\n" 13185 "\n" 13186 "void main()\n" 13187 "{\n" 13188 " tes_gs = tcs_tes[0];\n" 13189 "}\n" 13190 "\n"; 13191 static const GLchar* tes_tested = "#version 430 core\n" 13192 "#extension GL_ARB_enhanced_layouts : require\n" 13193 "\n" 13194 "layout(isolines, point_mode) in;\n" 13195 "\n" 13196 "STRUCT_DEFINITION" 13197 "\n" 13198 "VARIABLE_DEFINITION" 13199 "\n" 13200 "in vec4 tcs_tes[];\n" 13201 "out vec4 tes_gs;\n" 13202 "\n" 13203 "void main()\n" 13204 "{\n" 13205 " vec4 result = tcs_tes[0];\n" 13206 "\n" 13207 "VARIABLE_USE" 13208 "\n" 13209 " tes_gs += result;\n" 13210 "}\n" 13211 "\n"; 13212 static const GLchar* vs = "#version 430 core\n" 13213 "#extension GL_ARB_enhanced_layouts : require\n" 13214 "\n" 13215 "in vec4 in_vs;\n" 13216 "out vec4 vs_tcs;\n" 13217 "\n" 13218 "void main()\n" 13219 "{\n" 13220 " vs_tcs = in_vs;\n" 13221 "}\n" 13222 "\n"; 13223 static const GLchar* vs_tested = "#version 430 core\n" 13224 "#extension GL_ARB_enhanced_layouts : require\n" 13225 "\n" 13226 "STRUCT_DEFINITION" 13227 "\n" 13228 "VARIABLE_DEFINITION" 13229 "\n" 13230 "in vec4 in_vs;\n" 13231 "out vec4 vs_tcs;\n" 13232 "\n" 13233 "void main()\n" 13234 "{\n" 13235 " vec4 result = in_vs;\n" 13236 "\n" 13237 "VARIABLE_USE" 13238 "\n" 13239 " vs_tcs += result;\n" 13240 "}\n" 13241 "\n"; 13242 13243 std::string source; 13244 testCase& test_case = m_test_cases[test_case_index]; 13245 const GLchar* var_definition = 0; 13246 const GLchar* var_use = 0; 13247 13248 if (true == test_case.m_is_input) 13249 { 13250 var_definition = input_var; 13251 var_use = input_use; 13252 } 13253 else 13254 { 13255 var_definition = output_var; 13256 var_use = output_use; 13257 } 13258 13259 if (test_case.m_stage == stage) 13260 { 13261 size_t position = 0; 13262 13263 switch (stage) 13264 { 13265 case Utils::Shader::FRAGMENT: 13266 source = fs_tested; 13267 break; 13268 case Utils::Shader::GEOMETRY: 13269 source = gs_tested; 13270 break; 13271 case Utils::Shader::TESS_CTRL: 13272 source = tcs_tested; 13273 break; 13274 case Utils::Shader::TESS_EVAL: 13275 source = tes_tested; 13276 break; 13277 case Utils::Shader::VERTEX: 13278 source = vs_tested; 13279 break; 13280 default: 13281 TCU_FAIL("Invalid enum"); 13282 } 13283 13284 Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source); 13285 Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source); 13286 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 13287 } 13288 else 13289 { 13290 switch (stage) 13291 { 13292 case Utils::Shader::FRAGMENT: 13293 source = fs; 13294 break; 13295 case Utils::Shader::GEOMETRY: 13296 source = gs; 13297 break; 13298 case Utils::Shader::TESS_CTRL: 13299 source = tcs; 13300 break; 13301 case Utils::Shader::TESS_EVAL: 13302 source = tes; 13303 break; 13304 case Utils::Shader::VERTEX: 13305 source = vs; 13306 break; 13307 default: 13308 TCU_FAIL("Invalid enum"); 13309 } 13310 } 13311 13312 return source; 13313 } 13314 13315 /** Get description of test case 13316 * 13317 * @param test_case_index Index of test case 13318 * 13319 * @return Test case description 13320 **/ 13321 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index) 13322 { 13323 std::stringstream stream; 13324 testCase& test_case = m_test_cases[test_case_index]; 13325 13326 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: "; 13327 13328 if (true == test_case.m_is_input) 13329 { 13330 stream << "input"; 13331 } 13332 else 13333 { 13334 stream << "output"; 13335 } 13336 13337 return stream.str(); 13338 } 13339 13340 /** Get number of test cases 13341 * 13342 * @return Number of test cases 13343 **/ 13344 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber() 13345 { 13346 return static_cast<GLuint>(m_test_cases.size()); 13347 } 13348 13349 /** Selects if "compute" stage is relevant for test 13350 * 13351 * @param ignored 13352 * 13353 * @return false 13354 **/ 13355 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */) 13356 { 13357 return false; 13358 } 13359 13360 /** Prepare all test cases 13361 * 13362 **/ 13363 void VaryingStructureMemberLocationTest::testInit() 13364 { 13365 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 13366 { 13367 if (Utils::Shader::COMPUTE == stage) 13368 { 13369 continue; 13370 } 13371 13372 testCase test_case_in = { true, (Utils::Shader::STAGES)stage }; 13373 testCase test_case_out = { false, (Utils::Shader::STAGES)stage }; 13374 13375 m_test_cases.push_back(test_case_in); 13376 13377 if (Utils::Shader::FRAGMENT != stage) 13378 { 13379 m_test_cases.push_back(test_case_out); 13380 } 13381 } 13382 } 13383 13384 /** Constructor 13385 * 13386 * @param context Test framework context 13387 **/ 13388 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context& context) 13389 : TextureTestBase(context, "varying_block_locations", 13390 "Test verifies that locations are respected when blocks are used as in and out ") 13391 { 13392 } 13393 13394 /** Prepare code snippet that will pass in variables to out variables 13395 * 13396 * @param ignored 13397 * @param varying_passthrough Collection of connections between in and out variables 13398 * @param stage Shader stage 13399 * 13400 * @return Code that pass in variables to next stage 13401 **/ 13402 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */, 13403 Utils::VaryingPassthrough& varying_passthrough, 13404 Utils::Shader::STAGES stage) 13405 { 13406 std::string result; 13407 13408 if (Utils::Shader::VERTEX != stage) 13409 { 13410 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage); 13411 } 13412 else 13413 { 13414 result = "vs_tcs_block.third = vs_in_third;\n" 13415 " vs_tcs_block.fourth = vs_in_fourth;\n" 13416 " vs_tcs_block.fifth = vs_in_fifth;\n"; 13417 } 13418 13419 return result; 13420 } 13421 13422 /** Get interface of program 13423 * 13424 * @param ignored 13425 * @param program_interface Interface of program 13426 * @param varying_passthrough Collection of connections between in and out variables 13427 **/ 13428 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */, 13429 Utils::ProgramInterface& program_interface, 13430 Utils::VaryingPassthrough& varying_passthrough) 13431 { 13432 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 13433 const Utils::Type vec4 = Utils::Type::vec4; 13434 13435 /* Prepare data */ 13436 m_third_data = vec4.GenerateData(); 13437 m_fourth_data = vec4.GenerateData(); 13438 m_fifth_data = vec4.GenerateData(); 13439 13440 /* Memory layout is different from location layout */ 13441 const GLuint fifth_offset = 0u; 13442 const GLuint third_offset = static_cast<GLuint>(fifth_offset + m_fifth_data.size()); 13443 const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size()); 13444 13445 m_data.resize(fourth_offset + m_fourth_data.size()); 13446 GLubyte* ptr = (GLubyte*)&m_data[0]; 13447 memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size()); 13448 memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size()); 13449 memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size()); 13450 13451 Utils::Interface* block = program_interface.Block("vs_tcs_Block"); 13452 13453 block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */, 13454 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */); 13455 13456 block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4, 13457 false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */); 13458 13459 block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */, 13460 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */); 13461 13462 si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block, 13463 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */, 13464 m_data.size() /* data_size */); 13465 13466 si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */, 13467 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */, 13468 (GLvoid*)&m_third_data[0] /* data */, m_third_data.size() /* data_size */); 13469 13470 si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */, 13471 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */, 13472 (GLvoid*)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */); 13473 13474 si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */, 13475 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */, 13476 (GLvoid*)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */); 13477 13478 program_interface.CloneVertexInterface(varying_passthrough); 13479 } 13480 13481 /** Selects if "compute" stage is relevant for test 13482 * 13483 * @param ignored 13484 * 13485 * @return false 13486 **/ 13487 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */) 13488 { 13489 return false; 13490 } 13491 13492 /** This test should be run with separable programs 13493 * 13494 * @param ignored 13495 * 13496 * @return true 13497 **/ 13498 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */) 13499 { 13500 return false; 13501 } 13502 13503 /** Constructor 13504 * 13505 * @param context Test framework context 13506 **/ 13507 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context& context) 13508 : NegativeTestBase( 13509 context, "varying_block_member_locations", 13510 "Test verifies that compilation error is reported when not all members of block are qualified with location") 13511 { 13512 } 13513 13514 /** Source for given test case and stage 13515 * 13516 * @param test_case_index Index of test case 13517 * @param stage Shader stage 13518 * 13519 * @return Shader source 13520 **/ 13521 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 13522 { 13523 static const GLchar* block_definition_all = "Goku {\n" 13524 " layout (location = 2) vec4 gohan;\n" 13525 " layout (location = 4) vec4 goten;\n" 13526 " layout (location = 6) vec4 chichi;\n" 13527 "} gokuARRAY;\n"; 13528 static const GLchar* block_definition_default = "Goku {\n" 13529 " vec4 gohan;\n" 13530 " vec4 goten;\n" 13531 " vec4 chichi;\n" 13532 "} gokuARRAY;\n"; 13533 static const GLchar* block_definition_one = "Goku {\n" 13534 " vec4 gohan;\n" 13535 " layout (location = 4) vec4 goten;\n" 13536 " vec4 chichi;\n" 13537 "} gokuARRAY;\n"; 13538 static const GLchar* input_use = " result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n"; 13539 static const GLchar* output_use = " gokuINDEX.gohan = result / 2;\n" 13540 " gokuINDEX.goten = result / 4 - gokuINDEX.gohan;\n" 13541 " gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n"; 13542 static const GLchar* fs = "#version 430 core\n" 13543 "#extension GL_ARB_enhanced_layouts : require\n" 13544 "\n" 13545 "in vec4 gs_fs;\n" 13546 "out vec4 fs_out;\n" 13547 "\n" 13548 "void main()\n" 13549 "{\n" 13550 " fs_out = gs_fs;\n" 13551 "}\n" 13552 "\n"; 13553 static const GLchar* fs_tested = "#version 430 core\n" 13554 "#extension GL_ARB_enhanced_layouts : require\n" 13555 "\n" 13556 "DIRECTION BLOCK_DEFINITION" 13557 "\n" 13558 "in vec4 gs_fs;\n" 13559 "out vec4 fs_out;\n" 13560 "\n" 13561 "void main()\n" 13562 "{\n" 13563 " vec4 result = gs_fs;\n" 13564 "\n" 13565 "VARIABLE_USE" 13566 "\n" 13567 " fs_out = result;\n" 13568 "}\n" 13569 "\n"; 13570 static const GLchar* gs = "#version 430 core\n" 13571 "#extension GL_ARB_enhanced_layouts : require\n" 13572 "\n" 13573 "layout(points) in;\n" 13574 "layout(triangle_strip, max_vertices = 4) out;\n" 13575 "\n" 13576 "in vec4 tes_gs[];\n" 13577 "out vec4 gs_fs;\n" 13578 "\n" 13579 "void main()\n" 13580 "{\n" 13581 " gs_fs = tes_gs[0];\n" 13582 " gl_Position = vec4(-1, -1, 0, 1);\n" 13583 " EmitVertex();\n" 13584 " gs_fs = tes_gs[0];\n" 13585 " gl_Position = vec4(-1, 1, 0, 1);\n" 13586 " EmitVertex();\n" 13587 " gs_fs = tes_gs[0];\n" 13588 " gl_Position = vec4(1, -1, 0, 1);\n" 13589 " EmitVertex();\n" 13590 " gs_fs = tes_gs[0];\n" 13591 " gl_Position = vec4(1, 1, 0, 1);\n" 13592 " EmitVertex();\n" 13593 "}\n" 13594 "\n"; 13595 static const GLchar* gs_tested = "#version 430 core\n" 13596 "#extension GL_ARB_enhanced_layouts : require\n" 13597 "\n" 13598 "layout(points) in;\n" 13599 "layout(triangle_strip, max_vertices = 4) out;\n" 13600 "\n" 13601 "DIRECTION BLOCK_DEFINITION" 13602 "\n" 13603 "in vec4 tes_gs[];\n" 13604 "out vec4 gs_fs;\n" 13605 "\n" 13606 "void main()\n" 13607 "{\n" 13608 " vec4 result = tes_gs[0];\n" 13609 "\n" 13610 "VARIABLE_USE" 13611 "\n" 13612 " gs_fs = result;\n" 13613 " gl_Position = vec4(-1, -1, 0, 1);\n" 13614 " EmitVertex();\n" 13615 " gs_fs = result;\n" 13616 " gl_Position = vec4(-1, 1, 0, 1);\n" 13617 " EmitVertex();\n" 13618 " gs_fs = result;\n" 13619 " gl_Position = vec4(1, -1, 0, 1);\n" 13620 " EmitVertex();\n" 13621 " gs_fs = result;\n" 13622 " gl_Position = vec4(1, 1, 0, 1);\n" 13623 " EmitVertex();\n" 13624 "}\n" 13625 "\n"; 13626 static const GLchar* tcs = "#version 430 core\n" 13627 "#extension GL_ARB_enhanced_layouts : require\n" 13628 "\n" 13629 "layout(vertices = 1) out;\n" 13630 "\n" 13631 "in vec4 vs_tcs[];\n" 13632 "out vec4 tcs_tes[];\n" 13633 "\n" 13634 "void main()\n" 13635 "{\n" 13636 "\n" 13637 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 13638 "\n" 13639 " gl_TessLevelOuter[0] = 1.0;\n" 13640 " gl_TessLevelOuter[1] = 1.0;\n" 13641 " gl_TessLevelOuter[2] = 1.0;\n" 13642 " gl_TessLevelOuter[3] = 1.0;\n" 13643 " gl_TessLevelInner[0] = 1.0;\n" 13644 " gl_TessLevelInner[1] = 1.0;\n" 13645 "}\n" 13646 "\n"; 13647 static const GLchar* tcs_tested = "#version 430 core\n" 13648 "#extension GL_ARB_enhanced_layouts : require\n" 13649 "\n" 13650 "layout(vertices = 1) out;\n" 13651 "\n" 13652 "DIRECTION BLOCK_DEFINITION" 13653 "\n" 13654 "in vec4 vs_tcs[];\n" 13655 "out vec4 tcs_tes[];\n" 13656 "\n" 13657 "void main()\n" 13658 "{\n" 13659 " vec4 result = vs_tcs[gl_InvocationID];\n" 13660 "\n" 13661 "VARIABLE_USE" 13662 "\n" 13663 " tcs_tes[gl_InvocationID] = result;\n" 13664 "\n" 13665 " gl_TessLevelOuter[0] = 1.0;\n" 13666 " gl_TessLevelOuter[1] = 1.0;\n" 13667 " gl_TessLevelOuter[2] = 1.0;\n" 13668 " gl_TessLevelOuter[3] = 1.0;\n" 13669 " gl_TessLevelInner[0] = 1.0;\n" 13670 " gl_TessLevelInner[1] = 1.0;\n" 13671 "}\n" 13672 "\n"; 13673 static const GLchar* tes = "#version 430 core\n" 13674 "#extension GL_ARB_enhanced_layouts : require\n" 13675 "\n" 13676 "layout(isolines, point_mode) in;\n" 13677 "\n" 13678 "in vec4 tcs_tes[];\n" 13679 "out vec4 tes_gs;\n" 13680 "\n" 13681 "void main()\n" 13682 "{\n" 13683 " tes_gs = tcs_tes[0];\n" 13684 "}\n" 13685 "\n"; 13686 static const GLchar* tes_tested = "#version 430 core\n" 13687 "#extension GL_ARB_enhanced_layouts : require\n" 13688 "\n" 13689 "layout(isolines, point_mode) in;\n" 13690 "\n" 13691 "DIRECTION BLOCK_DEFINITION" 13692 "\n" 13693 "in vec4 tcs_tes[];\n" 13694 "out vec4 tes_gs;\n" 13695 "\n" 13696 "void main()\n" 13697 "{\n" 13698 " vec4 result = tcs_tes[0];\n" 13699 "\n" 13700 "VARIABLE_USE" 13701 "\n" 13702 " tes_gs = result;\n" 13703 "}\n" 13704 "\n"; 13705 static const GLchar* vs = "#version 430 core\n" 13706 "#extension GL_ARB_enhanced_layouts : require\n" 13707 "\n" 13708 "in vec4 in_vs;\n" 13709 "out vec4 vs_tcs;\n" 13710 "\n" 13711 "void main()\n" 13712 "{\n" 13713 " vs_tcs = in_vs;\n" 13714 "}\n" 13715 "\n"; 13716 static const GLchar* vs_tested = "#version 430 core\n" 13717 "#extension GL_ARB_enhanced_layouts : require\n" 13718 "\n" 13719 "DIRECTION BLOCK_DEFINITION" 13720 "\n" 13721 "in vec4 in_vs;\n" 13722 "out vec4 vs_tcs;\n" 13723 "\n" 13724 "void main()\n" 13725 "{\n" 13726 " vec4 result = in_vs;\n" 13727 "\n" 13728 "VARIABLE_USE" 13729 "\n" 13730 " vs_tcs = result;\n" 13731 "}\n" 13732 "\n"; 13733 13734 static const GLchar* shaders_in[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 }, 13735 /* vs */ { 0, vs_tested, tcs, tes, gs, fs }, 13736 /* tcs */ { 0, vs_tested, tcs_tested, tes, gs, fs }, 13737 /* tes */ { 0, vs, tcs_tested, tes_tested, gs, fs }, 13738 /* gs */ { 0, vs, tcs, tes_tested, gs_tested, fs }, 13739 /* fs */ { 0, vs, tcs, tes, gs_tested, fs_tested } }; 13740 13741 static const GLchar* shaders_out[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 }, 13742 /* vs */ { 0, vs_tested, tcs_tested, tes, gs, fs }, 13743 /* tcs */ { 0, vs, tcs_tested, tes_tested, gs, fs }, 13744 /* tes */ { 0, vs, tcs, tes_tested, gs_tested, fs }, 13745 /* gs */ { 0, vs, tcs, tes, gs_tested, fs_tested }, 13746 /* fs */ { 0, 0, 0, 0, 0, 0 } }; 13747 13748 static const bool require_modifications_in[6][6] = { 13749 /* cs */ { false, false, false, false, false, false }, 13750 /* vs */ { false, true, false, false, false, false }, 13751 /* tcs */ { false, true, true, false, false, false }, 13752 /* tes */ { false, false, true, true, false, false }, 13753 /* gs */ { false, false, false, true, true, false }, 13754 /* fs */ { false, false, false, false, true, true } 13755 }; 13756 13757 static const bool require_modifications_out[6][6] = { 13758 /* cs */ { false, false, false, false, false, false }, 13759 /* vs */ { false, true, true, false, false, false }, 13760 /* tcs */ { false, false, true, true, false, false }, 13761 /* tes */ { false, false, false, true, true, false }, 13762 /* gs */ { false, false, false, false, true, true }, 13763 /* fs */ { false, false, false, false, false, false } 13764 }; 13765 13766 const GLchar* array = ""; 13767 const GLchar* direction = "out"; 13768 const GLchar* index = ""; 13769 bool require_modifications = false; 13770 std::string source; 13771 testCase& test_case = m_test_cases[test_case_index]; 13772 const GLchar* var_use = output_use; 13773 13774 if (true == test_case.m_is_input) 13775 { 13776 require_modifications = require_modifications_in[test_case.m_stage][stage]; 13777 source = shaders_in[test_case.m_stage][stage]; 13778 13779 if (test_case.m_stage == stage) 13780 { 13781 direction = "in"; 13782 var_use = input_use; 13783 } 13784 } 13785 else 13786 { 13787 require_modifications = require_modifications_out[test_case.m_stage][stage]; 13788 source = shaders_out[test_case.m_stage][stage]; 13789 13790 if (test_case.m_stage != stage) 13791 { 13792 direction = "in"; 13793 var_use = input_use; 13794 } 13795 } 13796 13797 const GLchar* definition = test_case.m_qualify_all ? block_definition_all 13798 : block_definition_default; 13799 13800 if (test_case.m_stage == stage) 13801 { 13802 if (true == test_case.m_qualify_all) 13803 { 13804 definition = block_definition_all; 13805 } 13806 else 13807 { 13808 definition = block_definition_one; 13809 } 13810 } 13811 13812 // Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation evaluation 13813 // inputs all have an additional level of arrayness relative to other shader inputs and outputs. 13814 switch (stage) 13815 { 13816 case Utils::Shader::FRAGMENT: 13817 break; 13818 case Utils::Shader::TESS_CTRL: 13819 array = "[]"; 13820 index = "[gl_InvocationID]"; 13821 break; 13822 // geometry shader's input must have one more dimension than tessellation evaluation shader's output, 13823 // the GS input block is an array, so the DS output can't be declared as an array 13824 case Utils::Shader::GEOMETRY: 13825 case Utils::Shader::TESS_EVAL: 13826 { 13827 if (std::string(direction) == std::string("in")) // match HS output and DS input 13828 { 13829 array = "[]"; 13830 index = "[0]"; 13831 } 13832 else // match DS output and GS input 13833 { 13834 array = ""; 13835 index = ""; 13836 } 13837 } 13838 break; 13839 case Utils::Shader::VERTEX: 13840 break; 13841 default: 13842 TCU_FAIL("Invalid enum"); 13843 } 13844 13845 if (true == require_modifications) 13846 { 13847 size_t position = 0; 13848 size_t temp; 13849 13850 Utils::replaceToken("DIRECTION", position, direction, source); 13851 temp = position; 13852 Utils::replaceToken("BLOCK_DEFINITION", position, definition, source); 13853 position = temp; 13854 Utils::replaceToken("ARRAY", position, array, source); 13855 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 13856 13857 Utils::replaceAllTokens("INDEX", index, source); 13858 } 13859 else 13860 { 13861 switch (stage) 13862 { 13863 case Utils::Shader::FRAGMENT: 13864 source = fs; 13865 break; 13866 case Utils::Shader::GEOMETRY: 13867 source = gs; 13868 break; 13869 case Utils::Shader::TESS_CTRL: 13870 source = tcs; 13871 break; 13872 case Utils::Shader::TESS_EVAL: 13873 source = tes; 13874 break; 13875 case Utils::Shader::VERTEX: 13876 source = vs; 13877 break; 13878 default: 13879 TCU_FAIL("Invalid enum"); 13880 } 13881 } 13882 13883 return source; 13884 } 13885 13886 /** Get description of test case 13887 * 13888 * @param test_case_index Index of test case 13889 * 13890 * @return Test case description 13891 **/ 13892 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index) 13893 { 13894 std::stringstream stream; 13895 testCase& test_case = m_test_cases[test_case_index]; 13896 13897 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: "; 13898 13899 if (true == test_case.m_is_input) 13900 { 13901 stream << "input"; 13902 } 13903 else 13904 { 13905 stream << "output"; 13906 } 13907 13908 if (true == test_case.m_qualify_all) 13909 { 13910 stream << ", all members qualified"; 13911 } 13912 else 13913 { 13914 stream << ", not all members qualified"; 13915 } 13916 13917 return stream.str(); 13918 } 13919 13920 /** Get number of test cases 13921 * 13922 * @return Number of test cases 13923 **/ 13924 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber() 13925 { 13926 return static_cast<GLuint>(m_test_cases.size()); 13927 } 13928 13929 /** Selects if "compute" stage is relevant for test 13930 * 13931 * @param ignored 13932 * 13933 * @return false 13934 **/ 13935 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */) 13936 { 13937 return false; 13938 } 13939 13940 /** Selects if compilation failure is expected result 13941 * 13942 * @param test_case_index Index of test case 13943 * 13944 * @return false when all members are qualified, true otherwise 13945 **/ 13946 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index) 13947 { 13948 return (true != m_test_cases[test_case_index].m_qualify_all); 13949 } 13950 13951 /** Prepare all test cases 13952 * 13953 **/ 13954 void VaryingBlockMemberLocationsTest::testInit() 13955 { 13956 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 13957 { 13958 if (Utils::Shader::COMPUTE == stage) 13959 { 13960 continue; 13961 } 13962 13963 testCase test_case_in_all = { true, true, (Utils::Shader::STAGES)stage }; 13964 testCase test_case_in_one = { true, false, (Utils::Shader::STAGES)stage }; 13965 testCase test_case_out_all = { false, true, (Utils::Shader::STAGES)stage }; 13966 testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage }; 13967 13968 if (Utils::Shader::VERTEX != stage) 13969 { 13970 m_test_cases.push_back(test_case_in_all); 13971 m_test_cases.push_back(test_case_in_one); 13972 } 13973 13974 if (Utils::Shader::FRAGMENT != stage) 13975 { 13976 m_test_cases.push_back(test_case_out_all); 13977 m_test_cases.push_back(test_case_out_one); 13978 } 13979 } 13980 } 13981 13982 /** Constructor 13983 * 13984 * @param context Test framework context 13985 **/ 13986 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context& context) 13987 : NegativeTestBase( 13988 context, "varying_block_automatic_member_locations", 13989 "Test verifies that compiler assigns subsequent locations to block members, even if this causes errors") 13990 { 13991 } 13992 13993 /** Source for given test case and stage 13994 * 13995 * @param test_case_index Index of test case 13996 * @param stage Shader stage 13997 * 13998 * @return Shader source 13999 **/ 14000 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint test_case_index, 14001 Utils::Shader::STAGES stage) 14002 { 14003 static const GLchar* block_definition = "layout (location = 2) DIRECTION DBZ {\n" 14004 " vec4 goku;\n" 14005 " vec4 gohan[4];\n" 14006 " vec4 goten;\n" 14007 " layout (location = 1) vec4 chichi;\n" 14008 " vec4 pan;\n" 14009 "} dbzARRAY;\n"; 14010 static const GLchar* input_use = " result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + " 14011 "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + " 14012 "dbzINDEX.pan;\n"; 14013 static const GLchar* output_use = " dbzINDEX.goku = result;\n" 14014 " dbzINDEX.gohan[0] = result / 2;\n" 14015 " dbzINDEX.gohan[1] = result / 2.25;\n" 14016 " dbzINDEX.gohan[2] = result / 2.5;\n" 14017 " dbzINDEX.gohan[3] = result / 2.75;\n" 14018 " dbzINDEX.goten = result / 4 - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - " 14019 "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n" 14020 " dbzINDEX.chichi = result / 8 - dbzINDEX.goten;\n" 14021 " dbzINDEX.pan = result / 16 - dbzINDEX.chichi;\n"; 14022 static const GLchar* fs = "#version 430 core\n" 14023 "#extension GL_ARB_enhanced_layouts : require\n" 14024 "\n" 14025 "in vec4 gs_fs;\n" 14026 "out vec4 fs_out;\n" 14027 "\n" 14028 "void main()\n" 14029 "{\n" 14030 " fs_out = gs_fs;\n" 14031 "}\n" 14032 "\n"; 14033 static const GLchar* fs_tested = "#version 430 core\n" 14034 "#extension GL_ARB_enhanced_layouts : require\n" 14035 "\n" 14036 "BLOCK_DEFINITION" 14037 "\n" 14038 "in vec4 gs_fs;\n" 14039 "out vec4 fs_out;\n" 14040 "\n" 14041 "void main()\n" 14042 "{\n" 14043 " vec4 result = gs_fs;\n" 14044 "\n" 14045 "VARIABLE_USE" 14046 "\n" 14047 " fs_out += result;\n" 14048 "}\n" 14049 "\n"; 14050 static const GLchar* gs = "#version 430 core\n" 14051 "#extension GL_ARB_enhanced_layouts : require\n" 14052 "\n" 14053 "layout(points) in;\n" 14054 "layout(triangle_strip, max_vertices = 4) out;\n" 14055 "\n" 14056 "in vec4 tes_gs[];\n" 14057 "out vec4 gs_fs;\n" 14058 "\n" 14059 "void main()\n" 14060 "{\n" 14061 " gs_fs = tes_gs[0];\n" 14062 " gl_Position = vec4(-1, -1, 0, 1);\n" 14063 " EmitVertex();\n" 14064 " gs_fs = tes_gs[0];\n" 14065 " gl_Position = vec4(-1, 1, 0, 1);\n" 14066 " EmitVertex();\n" 14067 " gs_fs = tes_gs[0];\n" 14068 " gl_Position = vec4(1, -1, 0, 1);\n" 14069 " EmitVertex();\n" 14070 " gs_fs = tes_gs[0];\n" 14071 " gl_Position = vec4(1, 1, 0, 1);\n" 14072 " EmitVertex();\n" 14073 "}\n" 14074 "\n"; 14075 static const GLchar* gs_tested = "#version 430 core\n" 14076 "#extension GL_ARB_enhanced_layouts : require\n" 14077 "\n" 14078 "layout(points) in;\n" 14079 "layout(triangle_strip, max_vertices = 4) out;\n" 14080 "\n" 14081 "BLOCK_DEFINITION" 14082 "\n" 14083 "in vec4 tes_gs[];\n" 14084 "out vec4 gs_fs;\n" 14085 "\n" 14086 "void main()\n" 14087 "{\n" 14088 " vec4 result = tes_gs[0];\n" 14089 "\n" 14090 "VARIABLE_USE" 14091 "\n" 14092 " gs_fs = result;\n" 14093 " gl_Position = vec4(-1, -1, 0, 1);\n" 14094 " EmitVertex();\n" 14095 " gs_fs = result;\n" 14096 " gl_Position = vec4(-1, 1, 0, 1);\n" 14097 " EmitVertex();\n" 14098 " gs_fs = result;\n" 14099 " gl_Position = vec4(1, -1, 0, 1);\n" 14100 " EmitVertex();\n" 14101 " gs_fs = result;\n" 14102 " gl_Position = vec4(1, 1, 0, 1);\n" 14103 " EmitVertex();\n" 14104 "}\n" 14105 "\n"; 14106 static const GLchar* tcs = "#version 430 core\n" 14107 "#extension GL_ARB_enhanced_layouts : require\n" 14108 "\n" 14109 "layout(vertices = 1) out;\n" 14110 "\n" 14111 "in vec4 vs_tcs[];\n" 14112 "out vec4 tcs_tes[];\n" 14113 "\n" 14114 "void main()\n" 14115 "{\n" 14116 "\n" 14117 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 14118 "\n" 14119 " gl_TessLevelOuter[0] = 1.0;\n" 14120 " gl_TessLevelOuter[1] = 1.0;\n" 14121 " gl_TessLevelOuter[2] = 1.0;\n" 14122 " gl_TessLevelOuter[3] = 1.0;\n" 14123 " gl_TessLevelInner[0] = 1.0;\n" 14124 " gl_TessLevelInner[1] = 1.0;\n" 14125 "}\n" 14126 "\n"; 14127 static const GLchar* tcs_tested = "#version 430 core\n" 14128 "#extension GL_ARB_enhanced_layouts : require\n" 14129 "\n" 14130 "layout(vertices = 1) out;\n" 14131 "\n" 14132 "BLOCK_DEFINITION" 14133 "\n" 14134 "in vec4 vs_tcs[];\n" 14135 "out vec4 tcs_tes[];\n" 14136 "\n" 14137 "void main()\n" 14138 "{\n" 14139 " vec4 result = vs_tcs[gl_InvocationID];\n" 14140 "\n" 14141 "VARIABLE_USE" 14142 "\n" 14143 " tcs_tes[gl_InvocationID] = result;\n" 14144 "\n" 14145 " gl_TessLevelOuter[0] = 1.0;\n" 14146 " gl_TessLevelOuter[1] = 1.0;\n" 14147 " gl_TessLevelOuter[2] = 1.0;\n" 14148 " gl_TessLevelOuter[3] = 1.0;\n" 14149 " gl_TessLevelInner[0] = 1.0;\n" 14150 " gl_TessLevelInner[1] = 1.0;\n" 14151 "}\n" 14152 "\n"; 14153 static const GLchar* tes = "#version 430 core\n" 14154 "#extension GL_ARB_enhanced_layouts : require\n" 14155 "\n" 14156 "layout(isolines, point_mode) in;\n" 14157 "\n" 14158 "in vec4 tcs_tes[];\n" 14159 "out vec4 tes_gs;\n" 14160 "\n" 14161 "void main()\n" 14162 "{\n" 14163 " tes_gs = tcs_tes[0];\n" 14164 "}\n" 14165 "\n"; 14166 static const GLchar* tes_tested = "#version 430 core\n" 14167 "#extension GL_ARB_enhanced_layouts : require\n" 14168 "\n" 14169 "layout(isolines, point_mode) in;\n" 14170 "\n" 14171 "BLOCK_DEFINITION" 14172 "\n" 14173 "in vec4 tcs_tes[];\n" 14174 "out vec4 tes_gs;\n" 14175 "\n" 14176 "void main()\n" 14177 "{\n" 14178 " vec4 result = tcs_tes[0];\n" 14179 "\n" 14180 "VARIABLE_USE" 14181 "\n" 14182 " tes_gs += result;\n" 14183 "}\n" 14184 "\n"; 14185 static const GLchar* vs = "#version 430 core\n" 14186 "#extension GL_ARB_enhanced_layouts : require\n" 14187 "\n" 14188 "in vec4 in_vs;\n" 14189 "out vec4 vs_tcs;\n" 14190 "\n" 14191 "void main()\n" 14192 "{\n" 14193 " vs_tcs = in_vs;\n" 14194 "}\n" 14195 "\n"; 14196 static const GLchar* vs_tested = "#version 430 core\n" 14197 "#extension GL_ARB_enhanced_layouts : require\n" 14198 "\n" 14199 "BLOCK_DEFINITION" 14200 "\n" 14201 "in vec4 in_vs;\n" 14202 "out vec4 vs_tcs;\n" 14203 "\n" 14204 "void main()\n" 14205 "{\n" 14206 " vec4 result = in_vs;\n" 14207 "\n" 14208 "VARIABLE_USE" 14209 "\n" 14210 " vs_tcs += result;\n" 14211 "}\n" 14212 "\n"; 14213 14214 const GLchar* array = ""; 14215 const GLchar* direction = "out"; 14216 const GLchar* index = ""; 14217 std::string source; 14218 testCase& test_case = m_test_cases[test_case_index]; 14219 const GLchar* var_use = output_use; 14220 14221 if (true == test_case.m_is_input) 14222 { 14223 direction = "in "; 14224 var_use = input_use; 14225 } 14226 14227 if (test_case.m_stage == stage) 14228 { 14229 size_t position = 0; 14230 size_t temp; 14231 14232 switch (stage) 14233 { 14234 case Utils::Shader::FRAGMENT: 14235 source = fs_tested; 14236 break; 14237 case Utils::Shader::GEOMETRY: 14238 source = gs_tested; 14239 array = "[]"; 14240 index = "[0]"; 14241 break; 14242 case Utils::Shader::TESS_CTRL: 14243 source = tcs_tested; 14244 array = "[]"; 14245 index = "[gl_InvocationID]"; 14246 break; 14247 case Utils::Shader::TESS_EVAL: 14248 source = tes_tested; 14249 array = "[]"; 14250 index = "[0]"; 14251 break; 14252 case Utils::Shader::VERTEX: 14253 source = vs_tested; 14254 break; 14255 default: 14256 TCU_FAIL("Invalid enum"); 14257 } 14258 14259 temp = position; 14260 Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source); 14261 position = temp; 14262 Utils::replaceToken("DIRECTION", position, direction, source); 14263 Utils::replaceToken("ARRAY", position, array, source); 14264 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 14265 14266 Utils::replaceAllTokens("INDEX", index, source); 14267 } 14268 else 14269 { 14270 switch (stage) 14271 { 14272 case Utils::Shader::FRAGMENT: 14273 source = fs; 14274 break; 14275 case Utils::Shader::GEOMETRY: 14276 source = gs; 14277 break; 14278 case Utils::Shader::TESS_CTRL: 14279 source = tcs; 14280 break; 14281 case Utils::Shader::TESS_EVAL: 14282 source = tes; 14283 break; 14284 case Utils::Shader::VERTEX: 14285 source = vs; 14286 break; 14287 default: 14288 TCU_FAIL("Invalid enum"); 14289 } 14290 } 14291 14292 return source; 14293 } 14294 14295 /** Get description of test case 14296 * 14297 * @param test_case_index Index of test case 14298 * 14299 * @return Test case description 14300 **/ 14301 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index) 14302 { 14303 std::stringstream stream; 14304 testCase& test_case = m_test_cases[test_case_index]; 14305 14306 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: "; 14307 14308 if (true == test_case.m_is_input) 14309 { 14310 stream << "input"; 14311 } 14312 else 14313 { 14314 stream << "output"; 14315 } 14316 14317 return stream.str(); 14318 } 14319 14320 /** Get number of test cases 14321 * 14322 * @return Number of test cases 14323 **/ 14324 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber() 14325 { 14326 return static_cast<GLuint>(m_test_cases.size()); 14327 } 14328 14329 /** Selects if "compute" stage is relevant for test 14330 * 14331 * @param ignored 14332 * 14333 * @return false 14334 **/ 14335 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */) 14336 { 14337 return false; 14338 } 14339 14340 /** Prepare all test cases 14341 * 14342 **/ 14343 void VaryingBlockAutomaticMemberLocationsTest::testInit() 14344 { 14345 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 14346 { 14347 if (Utils::Shader::COMPUTE == stage) 14348 { 14349 continue; 14350 } 14351 14352 testCase test_case_in = { true, (Utils::Shader::STAGES)stage }; 14353 testCase test_case_out = { false, (Utils::Shader::STAGES)stage }; 14354 14355 if (Utils::Shader::VERTEX != stage) 14356 { 14357 m_test_cases.push_back(test_case_in); 14358 } 14359 14360 if (Utils::Shader::FRAGMENT != stage) 14361 { 14362 m_test_cases.push_back(test_case_out); 14363 } 14364 } 14365 } 14366 14367 /** Constructor 14368 * 14369 * @param context Test framework context 14370 **/ 14371 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context& context) 14372 : NegativeTestBase(context, "varying_location_limit", 14373 "Test verifies that compiler reports error when location qualifier exceed limits") 14374 { 14375 } 14376 14377 /** Source for given test case and stage 14378 * 14379 * @param test_case_index Index of test case 14380 * @param stage Shader stage 14381 * 14382 * @return Shader source 14383 **/ 14384 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 14385 { 14386 static const GLchar* var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n"; 14387 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n" 14388 " {\n" 14389 " result += vec4(1, 0.5, 0.25, 0.125);\n" 14390 " }\n"; 14391 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n" 14392 " if (vec4(0) == result)\n" 14393 " {\n" 14394 " gokuINDEX = TYPE(1);\n" 14395 " }\n"; 14396 static const GLchar* fs = "#version 430 core\n" 14397 "#extension GL_ARB_enhanced_layouts : require\n" 14398 "\n" 14399 "in vec4 gs_fs;\n" 14400 "out vec4 fs_out;\n" 14401 "\n" 14402 "void main()\n" 14403 "{\n" 14404 " fs_out = gs_fs;\n" 14405 "}\n" 14406 "\n"; 14407 static const GLchar* fs_tested = "#version 430 core\n" 14408 "#extension GL_ARB_enhanced_layouts : require\n" 14409 "\n" 14410 "VAR_DEFINITION" 14411 "\n" 14412 "in vec4 gs_fs;\n" 14413 "out vec4 fs_out;\n" 14414 "\n" 14415 "void main()\n" 14416 "{\n" 14417 " vec4 result = gs_fs;\n" 14418 "\n" 14419 "VARIABLE_USE" 14420 "\n" 14421 " fs_out += result;\n" 14422 "}\n" 14423 "\n"; 14424 static const GLchar* gs = "#version 430 core\n" 14425 "#extension GL_ARB_enhanced_layouts : require\n" 14426 "\n" 14427 "layout(points) in;\n" 14428 "layout(triangle_strip, max_vertices = 4) out;\n" 14429 "\n" 14430 "in vec4 tes_gs[];\n" 14431 "out vec4 gs_fs;\n" 14432 "\n" 14433 "void main()\n" 14434 "{\n" 14435 " gs_fs = tes_gs[0];\n" 14436 " gl_Position = vec4(-1, -1, 0, 1);\n" 14437 " EmitVertex();\n" 14438 " gs_fs = tes_gs[0];\n" 14439 " gl_Position = vec4(-1, 1, 0, 1);\n" 14440 " EmitVertex();\n" 14441 " gs_fs = tes_gs[0];\n" 14442 " gl_Position = vec4(1, -1, 0, 1);\n" 14443 " EmitVertex();\n" 14444 " gs_fs = tes_gs[0];\n" 14445 " gl_Position = vec4(1, 1, 0, 1);\n" 14446 " EmitVertex();\n" 14447 "}\n" 14448 "\n"; 14449 static const GLchar* gs_tested = "#version 430 core\n" 14450 "#extension GL_ARB_enhanced_layouts : require\n" 14451 "\n" 14452 "layout(points) in;\n" 14453 "layout(triangle_strip, max_vertices = 4) out;\n" 14454 "\n" 14455 "VAR_DEFINITION" 14456 "\n" 14457 "in vec4 tes_gs[];\n" 14458 "out vec4 gs_fs;\n" 14459 "\n" 14460 "void main()\n" 14461 "{\n" 14462 " vec4 result = tes_gs[0];\n" 14463 "\n" 14464 "VARIABLE_USE" 14465 "\n" 14466 " gs_fs = result;\n" 14467 " gl_Position = vec4(-1, -1, 0, 1);\n" 14468 " EmitVertex();\n" 14469 " gs_fs = result;\n" 14470 " gl_Position = vec4(-1, 1, 0, 1);\n" 14471 " EmitVertex();\n" 14472 " gs_fs = result;\n" 14473 " gl_Position = vec4(1, -1, 0, 1);\n" 14474 " EmitVertex();\n" 14475 " gs_fs = result;\n" 14476 " gl_Position = vec4(1, 1, 0, 1);\n" 14477 " EmitVertex();\n" 14478 "}\n" 14479 "\n"; 14480 static const GLchar* tcs = "#version 430 core\n" 14481 "#extension GL_ARB_enhanced_layouts : require\n" 14482 "\n" 14483 "layout(vertices = 1) out;\n" 14484 "\n" 14485 "in vec4 vs_tcs[];\n" 14486 "out vec4 tcs_tes[];\n" 14487 "\n" 14488 "void main()\n" 14489 "{\n" 14490 "\n" 14491 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 14492 "\n" 14493 " gl_TessLevelOuter[0] = 1.0;\n" 14494 " gl_TessLevelOuter[1] = 1.0;\n" 14495 " gl_TessLevelOuter[2] = 1.0;\n" 14496 " gl_TessLevelOuter[3] = 1.0;\n" 14497 " gl_TessLevelInner[0] = 1.0;\n" 14498 " gl_TessLevelInner[1] = 1.0;\n" 14499 "}\n" 14500 "\n"; 14501 static const GLchar* tcs_tested = "#version 430 core\n" 14502 "#extension GL_ARB_enhanced_layouts : require\n" 14503 "\n" 14504 "layout(vertices = 1) out;\n" 14505 "\n" 14506 "VAR_DEFINITION" 14507 "\n" 14508 "in vec4 vs_tcs[];\n" 14509 "out vec4 tcs_tes[];\n" 14510 "\n" 14511 "void main()\n" 14512 "{\n" 14513 " vec4 result = vs_tcs[gl_InvocationID];\n" 14514 "\n" 14515 "VARIABLE_USE" 14516 "\n" 14517 " tcs_tes[gl_InvocationID] = result;\n" 14518 "\n" 14519 " gl_TessLevelOuter[0] = 1.0;\n" 14520 " gl_TessLevelOuter[1] = 1.0;\n" 14521 " gl_TessLevelOuter[2] = 1.0;\n" 14522 " gl_TessLevelOuter[3] = 1.0;\n" 14523 " gl_TessLevelInner[0] = 1.0;\n" 14524 " gl_TessLevelInner[1] = 1.0;\n" 14525 "}\n" 14526 "\n"; 14527 static const GLchar* tes = "#version 430 core\n" 14528 "#extension GL_ARB_enhanced_layouts : require\n" 14529 "\n" 14530 "layout(isolines, point_mode) in;\n" 14531 "\n" 14532 "in vec4 tcs_tes[];\n" 14533 "out vec4 tes_gs;\n" 14534 "\n" 14535 "void main()\n" 14536 "{\n" 14537 " tes_gs = tcs_tes[0];\n" 14538 "}\n" 14539 "\n"; 14540 static const GLchar* tes_tested = "#version 430 core\n" 14541 "#extension GL_ARB_enhanced_layouts : require\n" 14542 "\n" 14543 "layout(isolines, point_mode) in;\n" 14544 "\n" 14545 "VAR_DEFINITION" 14546 "\n" 14547 "in vec4 tcs_tes[];\n" 14548 "out vec4 tes_gs;\n" 14549 "\n" 14550 "void main()\n" 14551 "{\n" 14552 " vec4 result = tcs_tes[0];\n" 14553 "\n" 14554 "VARIABLE_USE" 14555 "\n" 14556 " tes_gs += result;\n" 14557 "}\n" 14558 "\n"; 14559 static const GLchar* vs = "#version 430 core\n" 14560 "#extension GL_ARB_enhanced_layouts : require\n" 14561 "\n" 14562 "in vec4 in_vs;\n" 14563 "out vec4 vs_tcs;\n" 14564 "\n" 14565 "void main()\n" 14566 "{\n" 14567 " vs_tcs = in_vs;\n" 14568 "}\n" 14569 "\n"; 14570 static const GLchar* vs_tested = "#version 430 core\n" 14571 "#extension GL_ARB_enhanced_layouts : require\n" 14572 "\n" 14573 "VAR_DEFINITION" 14574 "\n" 14575 "in vec4 in_vs;\n" 14576 "out vec4 vs_tcs;\n" 14577 "\n" 14578 "void main()\n" 14579 "{\n" 14580 " vec4 result = in_vs;\n" 14581 "\n" 14582 "VARIABLE_USE" 14583 "\n" 14584 " vs_tcs += result;\n" 14585 "}\n" 14586 "\n"; 14587 14588 std::string source; 14589 testCase& test_case = m_test_cases[test_case_index]; 14590 14591 if (test_case.m_stage == stage) 14592 { 14593 const GLchar* array = ""; 14594 GLchar buffer[16]; 14595 const GLchar* direction = "in "; 14596 const GLchar* flat = ""; 14597 const GLchar* index = ""; 14598 GLuint last = getLastInputLocation(stage, test_case.m_type, 0, true); 14599 size_t position = 0; 14600 size_t temp; 14601 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 14602 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT; 14603 const GLchar* var_use = input_use; 14604 14605 if (false == test_case.m_is_input) 14606 { 14607 direction = "out"; 14608 last = getLastOutputLocation(stage, test_case.m_type, 0, true); 14609 storage = Utils::Variable::VARYING_OUTPUT; 14610 var_use = output_use; 14611 } 14612 14613 if (true == isFlatRequired(stage, test_case.m_type, storage)) 14614 { 14615 flat = "flat"; 14616 } 14617 14618 sprintf(buffer, "%d", last); 14619 14620 switch (stage) 14621 { 14622 case Utils::Shader::FRAGMENT: 14623 source = fs_tested; 14624 break; 14625 case Utils::Shader::GEOMETRY: 14626 source = gs_tested; 14627 array = "[]"; 14628 index = "[0]"; 14629 break; 14630 case Utils::Shader::TESS_CTRL: 14631 source = tcs_tested; 14632 array = "[]"; 14633 index = "[gl_InvocationID]"; 14634 break; 14635 case Utils::Shader::TESS_EVAL: 14636 source = tes_tested; 14637 array = "[]"; 14638 index = "[0]"; 14639 break; 14640 case Utils::Shader::VERTEX: 14641 source = vs_tested; 14642 break; 14643 default: 14644 TCU_FAIL("Invalid enum"); 14645 } 14646 14647 temp = position; 14648 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 14649 position = temp; 14650 Utils::replaceToken("LAST", position, buffer, source); 14651 Utils::replaceToken("FLAT", position, flat, source); 14652 Utils::replaceToken("DIRECTION", position, direction, source); 14653 Utils::replaceToken("ARRAY", position, array, source); 14654 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 14655 14656 Utils::replaceAllTokens("TYPE", type_name, source); 14657 Utils::replaceAllTokens("INDEX", index, source); 14658 } 14659 else 14660 { 14661 switch (stage) 14662 { 14663 case Utils::Shader::FRAGMENT: 14664 source = fs; 14665 break; 14666 case Utils::Shader::GEOMETRY: 14667 source = gs; 14668 break; 14669 case Utils::Shader::TESS_CTRL: 14670 source = tcs; 14671 break; 14672 case Utils::Shader::TESS_EVAL: 14673 source = tes; 14674 break; 14675 case Utils::Shader::VERTEX: 14676 source = vs; 14677 break; 14678 default: 14679 TCU_FAIL("Invalid enum"); 14680 } 14681 } 14682 14683 return source; 14684 } 14685 14686 /** Get description of test case 14687 * 14688 * @param test_case_index Index of test case 14689 * 14690 * @return Test case description 14691 **/ 14692 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index) 14693 { 14694 std::stringstream stream; 14695 testCase& test_case = m_test_cases[test_case_index]; 14696 14697 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 14698 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: "; 14699 14700 if (true == test_case.m_is_input) 14701 { 14702 stream << "input"; 14703 } 14704 else 14705 { 14706 stream << "output"; 14707 } 14708 14709 return stream.str(); 14710 } 14711 14712 /** Get number of test cases 14713 * 14714 * @return Number of test cases 14715 **/ 14716 GLuint VaryingLocationLimitTest::getTestCaseNumber() 14717 { 14718 return static_cast<GLuint>(m_test_cases.size()); 14719 } 14720 14721 /** Selects if "compute" stage is relevant for test 14722 * 14723 * @param ignored 14724 * 14725 * @return false 14726 **/ 14727 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */) 14728 { 14729 return false; 14730 } 14731 14732 /** Prepare all test cases 14733 * 14734 **/ 14735 void VaryingLocationLimitTest::testInit() 14736 { 14737 const GLuint n_types = getTypesNumber(); 14738 14739 for (GLuint i = 0; i < n_types; ++i) 14740 { 14741 const Utils::Type& type = getType(i); 14742 14743 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 14744 { 14745 if (Utils::Shader::COMPUTE == stage) 14746 { 14747 continue; 14748 } 14749 14750 testCase test_case_in = { true, type, (Utils::Shader::STAGES)stage }; 14751 testCase test_case_out = { false, type, (Utils::Shader::STAGES)stage }; 14752 14753 m_test_cases.push_back(test_case_in); 14754 14755 if (Utils::Shader::FRAGMENT != stage) 14756 { 14757 m_test_cases.push_back(test_case_out); 14758 } 14759 } 14760 } 14761 } 14762 14763 /** Constructor 14764 * 14765 * @param context Test framework context 14766 **/ 14767 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context) 14768 : VaryingLocationsTest(context, "varying_components", 14769 "Test verifies that input and output components are respected") 14770 { 14771 } 14772 14773 /** Constructor 14774 * 14775 * @param context Test framework context 14776 * @param test_name Name of test 14777 * @param test_description Description of test 14778 **/ 14779 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context, const glw::GLchar* test_name, 14780 const glw::GLchar* test_description) 14781 : VaryingLocationsTest(context, test_name, test_description) 14782 { 14783 } 14784 14785 /** Get interface of program 14786 * 14787 * @param test_case_index Test case 14788 * @param program_interface Interface of program 14789 * @param varying_passthrough Collection of connections between in and out variables 14790 **/ 14791 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface, 14792 Utils::VaryingPassthrough& varying_passthrough) 14793 { 14794 GLuint array_length = getArrayLength(); 14795 const testCase& test_case = m_test_cases[test_case_index]; 14796 const Utils::Type vector_type = Utils::Type::GetType(test_case.m_type, 1, 4); 14797 Utils::ShaderInterface si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 14798 14799 /* Zero means no array, however we still need at least 1 slot of data */ 14800 if (0 == array_length) 14801 { 14802 array_length += 1; 14803 } 14804 14805 /* Generate data */ 14806 const std::vector<GLubyte>& data = vector_type.GenerateDataPacked(); 14807 const size_t data_size = data.size(); 14808 14809 /* Prepare data for variables */ 14810 m_data.resize(array_length * data_size); 14811 14812 GLubyte* dst = &m_data[0]; 14813 const GLubyte* src = &data[0]; 14814 14815 for (GLuint i = 0; i < array_length; ++i) 14816 { 14817 memcpy(dst + data_size * i, src, data_size); 14818 } 14819 14820 /* Prepare interface for each stage */ 14821 prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough); 14822 prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough); 14823 prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough); 14824 prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough); 14825 prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough); 14826 } 14827 14828 /** Get type name 14829 * 14830 * @param test_case_index Index of test case 14831 * 14832 * @return Name of type test in test_case_index 14833 **/ 14834 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index) 14835 { 14836 std::string name; 14837 14838 const testCase& test_case = m_test_cases[test_case_index]; 14839 14840 name = "Type: "; 14841 14842 switch (test_case.m_type) 14843 { 14844 case Utils::Type::Double: 14845 name.append(Utils::Type::_double.GetGLSLTypeName()); 14846 break; 14847 case Utils::Type::Float: 14848 name.append(Utils::Type::_float.GetGLSLTypeName()); 14849 break; 14850 case Utils::Type::Int: 14851 name.append(Utils::Type::_int.GetGLSLTypeName()); 14852 break; 14853 case Utils::Type::Uint: 14854 name.append(Utils::Type::uint.GetGLSLTypeName()); 14855 break; 14856 } 14857 14858 name.append(", layout: "); 14859 14860 switch (test_case.m_layout) 14861 { 14862 case GVEC4: 14863 name.append("GVEC4"); 14864 break; 14865 case SCALAR_GVEC3: 14866 name.append("SCALAR_GVEC3"); 14867 break; 14868 case GVEC3_SCALAR: 14869 name.append("GVEC3_SCALAR"); 14870 break; 14871 case GVEC2_GVEC2: 14872 name.append("GVEC2_GVEC2"); 14873 break; 14874 case GVEC2_SCALAR_SCALAR: 14875 name.append("GVEC2_SCALAR_SCALAR"); 14876 break; 14877 case SCALAR_GVEC2_SCALAR: 14878 name.append("SCALAR_GVEC2_SCALAR"); 14879 break; 14880 case SCALAR_SCALAR_GVEC2: 14881 name.append("SCALAR_SCALAR_GVEC2"); 14882 break; 14883 case SCALAR_SCALAR_SCALAR_SCALAR: 14884 name.append("SCALAR_SCALAR_SCALAR_SCALAR"); 14885 break; 14886 } 14887 14888 return name; 14889 } 14890 14891 /** Returns number of types to test 14892 * 14893 * @return Number of types, 34 14894 **/ 14895 glw::GLuint VaryingComponentsTest::getTestCaseNumber() 14896 { 14897 return static_cast<GLuint>(m_test_cases.size()); 14898 } 14899 14900 /* Prepare test cases */ 14901 void VaryingComponentsTest::testInit() 14902 { 14903 // FIXME: add tests for doubles, which have specific rules 14904 14905 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float)); 14906 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float)); 14907 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float)); 14908 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float)); 14909 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float)); 14910 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float)); 14911 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float)); 14912 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float)); 14913 14914 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int)); 14915 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int)); 14916 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int)); 14917 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int)); 14918 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int)); 14919 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int)); 14920 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int)); 14921 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int)); 14922 14923 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint)); 14924 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint)); 14925 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint)); 14926 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint)); 14927 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint)); 14928 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint)); 14929 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint)); 14930 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint)); 14931 } 14932 14933 /** Inform that test use components 14934 * 14935 * @param ignored 14936 * 14937 * @return true 14938 **/ 14939 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */) 14940 { 14941 return true; 14942 } 14943 14944 /** Get length of arrays that should be used during test 14945 * 14946 * @return 0u - no array at all 14947 **/ 14948 GLuint VaryingComponentsTest::getArrayLength() 14949 { 14950 return 0; 14951 } 14952 14953 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location) 14954 { 14955 std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location); 14956 14957 globals.append("const uint comp_x = 0u;\n" 14958 "const uint comp_y = 1u;\n" 14959 "const uint comp_z = 2u;\n" 14960 "const uint comp_w = 3u;\n"); 14961 14962 return globals; 14963 } 14964 14965 /** 14966 * 14967 **/ 14968 std::string VaryingComponentsTest::prepareName(const glw::GLchar* name, glw::GLint location, glw::GLint component, 14969 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage) 14970 { 14971 GLchar buffer[16]; 14972 std::string result = "PREFIXNAME_lLOCATION_cCOMPONENT"; 14973 size_t position = 0; 14974 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, storage); 14975 14976 Utils::replaceToken("PREFIX", position, prefix, result); 14977 Utils::replaceToken("NAME", position, name, result); 14978 14979 sprintf(buffer, "%d", location); 14980 Utils::replaceToken("LOCATION", position, buffer, result); 14981 14982 sprintf(buffer, "%d", component); 14983 Utils::replaceToken("COMPONENT", position, buffer, result); 14984 14985 return result; 14986 } 14987 14988 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar* location, const glw::GLchar* component, 14989 const glw::GLchar* interpolation) 14990 { 14991 size_t position = 0; 14992 std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION"; 14993 14994 Utils::replaceToken("LOCATION", position, location, qualifiers); 14995 Utils::replaceToken("COMPONENT", position, component, qualifiers); 14996 Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers); 14997 14998 return qualifiers; 14999 } 15000 15001 /** 15002 * 15003 **/ 15004 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& vector_type, 15005 Utils::ProgramInterface& program_interface, const testCase& test_case, 15006 Utils::VaryingPassthrough& varying_passthrough) 15007 { 15008 const GLuint array_length = getArrayLength(); 15009 const Utils::Type& basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */); 15010 descriptor desc_in[8]; 15011 descriptor desc_out[8]; 15012 const GLuint first_in_loc = 0; 15013 const GLuint first_out_loc = 0; 15014 const GLchar* interpolation = ""; 15015 const GLuint last_in_loc = getLastInputLocation(stage, vector_type, array_length, false); 15016 GLuint last_out_loc = 0; 15017 GLuint n_desc = 0; 15018 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage); 15019 15020 /* Select interpolation */ 15021 if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage)) 15022 { 15023 interpolation = " flat"; 15024 } 15025 15026 if (Utils::Shader::FRAGMENT != stage) 15027 { 15028 last_out_loc = getLastOutputLocation(stage, vector_type, array_length, false); 15029 } 15030 15031 switch (test_case.m_layout) 15032 { 15033 case GVEC4: 15034 n_desc = 2; 15035 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4"); 15036 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4"); 15037 15038 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4"); 15039 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4"); 15040 break; 15041 case SCALAR_GVEC3: 15042 n_desc = 4; 15043 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar"); 15044 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar"); 15045 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3"); 15046 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3"); 15047 15048 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar"); 15049 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar"); 15050 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3"); 15051 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3"); 15052 break; 15053 case GVEC3_SCALAR: 15054 n_desc = 4; 15055 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3"); 15056 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3"); 15057 desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar"); 15058 desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar"); 15059 15060 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3"); 15061 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3"); 15062 desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar"); 15063 desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar"); 15064 break; 15065 case GVEC2_GVEC2: 15066 n_desc = 4; 15067 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2"); 15068 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2"); 15069 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2"); 15070 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2"); 15071 15072 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2"); 15073 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2"); 15074 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2"); 15075 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2"); 15076 break; 15077 case GVEC2_SCALAR_SCALAR: 15078 n_desc = 6; 15079 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2"); 15080 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2"); 15081 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar"); 15082 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar"); 15083 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar"); 15084 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar"); 15085 15086 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2"); 15087 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2"); 15088 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar"); 15089 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar"); 15090 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar"); 15091 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar"); 15092 break; 15093 case SCALAR_GVEC2_SCALAR: 15094 n_desc = 6; 15095 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar"); 15096 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar"); 15097 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2"); 15098 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2"); 15099 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar"); 15100 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar"); 15101 15102 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar"); 15103 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar"); 15104 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2"); 15105 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2"); 15106 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar"); 15107 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar"); 15108 break; 15109 case SCALAR_SCALAR_GVEC2: 15110 n_desc = 6; 15111 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar"); 15112 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar"); 15113 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar"); 15114 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar"); 15115 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2"); 15116 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2"); 15117 15118 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar"); 15119 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar"); 15120 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar"); 15121 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar"); 15122 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2"); 15123 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2"); 15124 break; 15125 case SCALAR_SCALAR_SCALAR_SCALAR: 15126 n_desc = 8; 15127 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar"); 15128 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar"); 15129 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar"); 15130 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar"); 15131 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar"); 15132 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar"); 15133 desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar"); 15134 desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar"); 15135 15136 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar"); 15137 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar"); 15138 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar"); 15139 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar"); 15140 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar"); 15141 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar"); 15142 desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar"); 15143 desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar"); 15144 break; 15145 } 15146 15147 for (GLuint i = 0; i < n_desc; ++i) 15148 { 15149 const descriptor& in_desc = desc_in[i]; 15150 15151 Utils::Variable* in = 15152 prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT); 15153 15154 if (Utils::Shader::FRAGMENT != stage) 15155 { 15156 const descriptor& out_desc = desc_out[i]; 15157 15158 Utils::Variable* out = 15159 prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT); 15160 15161 varying_passthrough.Add(stage, in, out); 15162 } 15163 } 15164 15165 si.m_globals = prepareGlobals(last_in_loc, last_out_loc); 15166 } 15167 15168 /** 15169 * 15170 **/ 15171 Utils::Variable* VaryingComponentsTest::prepareVarying(const Utils::Type& basic_type, const descriptor& desc, 15172 const GLchar* interpolation, Utils::ShaderInterface& si, 15173 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage) 15174 { 15175 const GLuint array_length = getArrayLength(); 15176 const GLuint component_size = basic_type.GetSize(); 15177 const std::string& name = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage); 15178 const GLuint offset = desc.m_component * component_size; 15179 const std::string& qual = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation); 15180 const GLuint size = desc.m_n_rows * component_size; 15181 const Utils::Type& type = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows); 15182 Utils::Variable* var = 0; 15183 15184 if (Utils::Variable::VARYING_INPUT == storage) 15185 { 15186 var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */, 15187 desc.m_location /* expected_location */, type, /* built_in_type */ 15188 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */, 15189 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */); 15190 } 15191 else 15192 { 15193 var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */, 15194 desc.m_location /* expected_location */, type, /* built_in_type */ 15195 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */, 15196 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */); 15197 } 15198 15199 return var; 15200 } 15201 15202 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar* component_str, 15203 glw::GLint location, const glw::GLchar* location_str, glw::GLuint n_rows, 15204 const glw::GLchar* name) 15205 { 15206 m_component = component; 15207 m_component_str = component_str; 15208 m_location = location; 15209 m_location_str = location_str; 15210 m_n_rows = n_rows; 15211 m_name = name; 15212 } 15213 15214 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type) 15215 : m_layout(layout), m_type(type) 15216 { 15217 } 15218 15219 /** Constructor 15220 * 15221 * @param context Test framework context 15222 **/ 15223 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context& context) 15224 : VaryingComponentsTest(context, "varying_array_components", 15225 "Test verifies that input and output components are respected for arrays") 15226 { 15227 } 15228 15229 /** Get length of arrays that should be used during test 15230 * 15231 * @return 4u 15232 **/ 15233 GLuint VaryingArrayComponentsTest::getArrayLength() 15234 { 15235 return 4u; 15236 } 15237 15238 /** Constructor 15239 * 15240 * @param context Test framework context 15241 **/ 15242 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context& context) 15243 : NegativeTestBase(context, "varying_exceeding_components", 15244 "Test verifies that compiler reports error when component qualifier exceed limits") 15245 { 15246 } 15247 15248 /** Source for given test case and stage 15249 * 15250 * @param test_case_index Index of test case 15251 * @param stage Shader stage 15252 * 15253 * @return Shader source 15254 **/ 15255 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 15256 { 15257 static const GLchar* var_definition_arr = 15258 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n"; 15259 static const GLchar* var_definition_one = 15260 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n"; 15261 static const GLchar* input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n" 15262 " {\n" 15263 " result += vec4(1, 0.5, 0.25, 0.125);\n" 15264 " }\n"; 15265 static const GLchar* input_use_one = " if (TYPE(0) == gokuINDEX)\n" 15266 " {\n" 15267 " result += vec4(1, 0.5, 0.25, 0.125);\n" 15268 " }\n"; 15269 static const GLchar* output_use_arr = " gokuINDEX[0] = TYPE(0);\n" 15270 " if (vec4(0) == result)\n" 15271 " {\n" 15272 " gokuINDEX[0] = TYPE(1);\n" 15273 " }\n"; 15274 static const GLchar* output_use_one = " gokuINDEX = TYPE(0);\n" 15275 " if (vec4(0) == result)\n" 15276 " {\n" 15277 " gokuINDEX = TYPE(1);\n" 15278 " }\n"; 15279 static const GLchar* fs = "#version 430 core\n" 15280 "#extension GL_ARB_enhanced_layouts : require\n" 15281 "\n" 15282 "in vec4 gs_fs;\n" 15283 "out vec4 fs_out;\n" 15284 "\n" 15285 "void main()\n" 15286 "{\n" 15287 " fs_out = gs_fs;\n" 15288 "}\n" 15289 "\n"; 15290 static const GLchar* fs_tested = "#version 430 core\n" 15291 "#extension GL_ARB_enhanced_layouts : require\n" 15292 "\n" 15293 "VAR_DEFINITION" 15294 "\n" 15295 "in vec4 gs_fs;\n" 15296 "out vec4 fs_out;\n" 15297 "\n" 15298 "void main()\n" 15299 "{\n" 15300 " vec4 result = gs_fs;\n" 15301 "\n" 15302 "VARIABLE_USE" 15303 "\n" 15304 " fs_out += result;\n" 15305 "}\n" 15306 "\n"; 15307 static const GLchar* gs = "#version 430 core\n" 15308 "#extension GL_ARB_enhanced_layouts : require\n" 15309 "\n" 15310 "layout(points) in;\n" 15311 "layout(triangle_strip, max_vertices = 4) out;\n" 15312 "\n" 15313 "in vec4 tes_gs[];\n" 15314 "out vec4 gs_fs;\n" 15315 "\n" 15316 "void main()\n" 15317 "{\n" 15318 " gs_fs = tes_gs[0];\n" 15319 " gl_Position = vec4(-1, -1, 0, 1);\n" 15320 " EmitVertex();\n" 15321 " gs_fs = tes_gs[0];\n" 15322 " gl_Position = vec4(-1, 1, 0, 1);\n" 15323 " EmitVertex();\n" 15324 " gs_fs = tes_gs[0];\n" 15325 " gl_Position = vec4(1, -1, 0, 1);\n" 15326 " EmitVertex();\n" 15327 " gs_fs = tes_gs[0];\n" 15328 " gl_Position = vec4(1, 1, 0, 1);\n" 15329 " EmitVertex();\n" 15330 "}\n" 15331 "\n"; 15332 static const GLchar* gs_tested = "#version 430 core\n" 15333 "#extension GL_ARB_enhanced_layouts : require\n" 15334 "\n" 15335 "layout(points) in;\n" 15336 "layout(triangle_strip, max_vertices = 4) out;\n" 15337 "\n" 15338 "VAR_DEFINITION" 15339 "\n" 15340 "in vec4 tes_gs[];\n" 15341 "out vec4 gs_fs;\n" 15342 "\n" 15343 "void main()\n" 15344 "{\n" 15345 " vec4 result = tes_gs[0];\n" 15346 "\n" 15347 "VARIABLE_USE" 15348 "\n" 15349 " gs_fs = result;\n" 15350 " gl_Position = vec4(-1, -1, 0, 1);\n" 15351 " EmitVertex();\n" 15352 " gs_fs = result;\n" 15353 " gl_Position = vec4(-1, 1, 0, 1);\n" 15354 " EmitVertex();\n" 15355 " gs_fs = result;\n" 15356 " gl_Position = vec4(1, -1, 0, 1);\n" 15357 " EmitVertex();\n" 15358 " gs_fs = result;\n" 15359 " gl_Position = vec4(1, 1, 0, 1);\n" 15360 " EmitVertex();\n" 15361 "}\n" 15362 "\n"; 15363 static const GLchar* tcs = "#version 430 core\n" 15364 "#extension GL_ARB_enhanced_layouts : require\n" 15365 "\n" 15366 "layout(vertices = 1) out;\n" 15367 "\n" 15368 "in vec4 vs_tcs[];\n" 15369 "out vec4 tcs_tes[];\n" 15370 "\n" 15371 "void main()\n" 15372 "{\n" 15373 "\n" 15374 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 15375 "\n" 15376 " gl_TessLevelOuter[0] = 1.0;\n" 15377 " gl_TessLevelOuter[1] = 1.0;\n" 15378 " gl_TessLevelOuter[2] = 1.0;\n" 15379 " gl_TessLevelOuter[3] = 1.0;\n" 15380 " gl_TessLevelInner[0] = 1.0;\n" 15381 " gl_TessLevelInner[1] = 1.0;\n" 15382 "}\n" 15383 "\n"; 15384 static const GLchar* tcs_tested = "#version 430 core\n" 15385 "#extension GL_ARB_enhanced_layouts : require\n" 15386 "\n" 15387 "layout(vertices = 1) out;\n" 15388 "\n" 15389 "VAR_DEFINITION" 15390 "\n" 15391 "in vec4 vs_tcs[];\n" 15392 "out vec4 tcs_tes[];\n" 15393 "\n" 15394 "void main()\n" 15395 "{\n" 15396 " vec4 result = vs_tcs[gl_InvocationID];\n" 15397 "\n" 15398 "VARIABLE_USE" 15399 "\n" 15400 " tcs_tes[gl_InvocationID] = result;\n" 15401 "\n" 15402 " gl_TessLevelOuter[0] = 1.0;\n" 15403 " gl_TessLevelOuter[1] = 1.0;\n" 15404 " gl_TessLevelOuter[2] = 1.0;\n" 15405 " gl_TessLevelOuter[3] = 1.0;\n" 15406 " gl_TessLevelInner[0] = 1.0;\n" 15407 " gl_TessLevelInner[1] = 1.0;\n" 15408 "}\n" 15409 "\n"; 15410 static const GLchar* tes = "#version 430 core\n" 15411 "#extension GL_ARB_enhanced_layouts : require\n" 15412 "\n" 15413 "layout(isolines, point_mode) in;\n" 15414 "\n" 15415 "in vec4 tcs_tes[];\n" 15416 "out vec4 tes_gs;\n" 15417 "\n" 15418 "void main()\n" 15419 "{\n" 15420 " tes_gs = tcs_tes[0];\n" 15421 "}\n" 15422 "\n"; 15423 static const GLchar* tes_tested = "#version 430 core\n" 15424 "#extension GL_ARB_enhanced_layouts : require\n" 15425 "\n" 15426 "layout(isolines, point_mode) in;\n" 15427 "\n" 15428 "VAR_DEFINITION" 15429 "\n" 15430 "in vec4 tcs_tes[];\n" 15431 "out vec4 tes_gs;\n" 15432 "\n" 15433 "void main()\n" 15434 "{\n" 15435 " vec4 result = tcs_tes[0];\n" 15436 "\n" 15437 "VARIABLE_USE" 15438 "\n" 15439 " tes_gs += result;\n" 15440 "}\n" 15441 "\n"; 15442 static const GLchar* vs = "#version 430 core\n" 15443 "#extension GL_ARB_enhanced_layouts : require\n" 15444 "\n" 15445 "in vec4 in_vs;\n" 15446 "out vec4 vs_tcs;\n" 15447 "\n" 15448 "void main()\n" 15449 "{\n" 15450 " vs_tcs = in_vs;\n" 15451 "}\n" 15452 "\n"; 15453 static const GLchar* vs_tested = "#version 430 core\n" 15454 "#extension GL_ARB_enhanced_layouts : require\n" 15455 "\n" 15456 "VAR_DEFINITION" 15457 "\n" 15458 "in vec4 in_vs;\n" 15459 "out vec4 vs_tcs;\n" 15460 "\n" 15461 "void main()\n" 15462 "{\n" 15463 " vec4 result = in_vs;\n" 15464 "\n" 15465 "VARIABLE_USE" 15466 "\n" 15467 " vs_tcs += result;\n" 15468 "}\n" 15469 "\n"; 15470 15471 std::string source; 15472 testCase& test_case = m_test_cases[test_case_index]; 15473 15474 if (test_case.m_stage == stage) 15475 { 15476 const GLchar* array = ""; 15477 GLchar buffer[16]; 15478 const GLchar* var_definition = 0; 15479 const GLchar* direction = "in "; 15480 const GLchar* index = ""; 15481 size_t position = 0; 15482 size_t temp; 15483 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 15484 const GLchar* var_use = 0; 15485 15486 if (false == test_case.m_is_input) 15487 { 15488 direction = "out"; 15489 15490 if (false == test_case.m_is_array) 15491 { 15492 var_definition = var_definition_one; 15493 var_use = output_use_one; 15494 } 15495 else 15496 { 15497 var_definition = var_definition_arr; 15498 var_use = output_use_arr; 15499 } 15500 } 15501 else 15502 { 15503 if (false == test_case.m_is_array) 15504 { 15505 var_definition = var_definition_one; 15506 var_use = input_use_one; 15507 } 15508 else 15509 { 15510 var_definition = var_definition_arr; 15511 var_use = input_use_arr; 15512 } 15513 } 15514 15515 sprintf(buffer, "%d", test_case.m_component); 15516 15517 switch (stage) 15518 { 15519 case Utils::Shader::FRAGMENT: 15520 source = fs_tested; 15521 break; 15522 case Utils::Shader::GEOMETRY: 15523 source = gs_tested; 15524 array = "[]"; 15525 index = "[0]"; 15526 break; 15527 case Utils::Shader::TESS_CTRL: 15528 source = tcs_tested; 15529 array = "[]"; 15530 index = "[gl_InvocationID]"; 15531 break; 15532 case Utils::Shader::TESS_EVAL: 15533 source = tes_tested; 15534 array = "[]"; 15535 index = "[0]"; 15536 break; 15537 case Utils::Shader::VERTEX: 15538 source = vs_tested; 15539 break; 15540 default: 15541 TCU_FAIL("Invalid enum"); 15542 } 15543 15544 temp = position; 15545 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 15546 position = temp; 15547 Utils::replaceToken("COMPONENT", position, buffer, source); 15548 Utils::replaceToken("DIRECTION", position, direction, source); 15549 Utils::replaceToken("ARRAY", position, array, source); 15550 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 15551 15552 Utils::replaceAllTokens("TYPE", type_name, source); 15553 Utils::replaceAllTokens("INDEX", index, source); 15554 } 15555 else 15556 { 15557 switch (stage) 15558 { 15559 case Utils::Shader::FRAGMENT: 15560 source = fs; 15561 break; 15562 case Utils::Shader::GEOMETRY: 15563 source = gs; 15564 break; 15565 case Utils::Shader::TESS_CTRL: 15566 source = tcs; 15567 break; 15568 case Utils::Shader::TESS_EVAL: 15569 source = tes; 15570 break; 15571 case Utils::Shader::VERTEX: 15572 source = vs; 15573 break; 15574 default: 15575 TCU_FAIL("Invalid enum"); 15576 } 15577 } 15578 15579 return source; 15580 } 15581 15582 /** Get description of test case 15583 * 15584 * @param test_case_index Index of test case 15585 * 15586 * @return Test case description 15587 **/ 15588 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index) 15589 { 15590 std::stringstream stream; 15591 testCase& test_case = m_test_cases[test_case_index]; 15592 15593 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 15594 << " type: " << test_case.m_type.GetGLSLTypeName(); 15595 15596 if (true == test_case.m_is_array) 15597 { 15598 stream << "[1]"; 15599 } 15600 15601 stream << ", direction: "; 15602 15603 if (true == test_case.m_is_input) 15604 { 15605 stream << "input"; 15606 } 15607 else 15608 { 15609 stream << "output"; 15610 } 15611 15612 stream << ", component: " << test_case.m_component; 15613 15614 return stream.str(); 15615 } 15616 15617 /** Get number of test cases 15618 * 15619 * @return Number of test cases 15620 **/ 15621 GLuint VaryingExceedingComponentsTest::getTestCaseNumber() 15622 { 15623 return static_cast<GLuint>(m_test_cases.size()); 15624 } 15625 15626 /** Selects if "compute" stage is relevant for test 15627 * 15628 * @param ignored 15629 * 15630 * @return false 15631 **/ 15632 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */) 15633 { 15634 return false; 15635 } 15636 15637 /** Prepare all test cases 15638 * 15639 **/ 15640 void VaryingExceedingComponentsTest::testInit() 15641 { 15642 static const GLuint n_components_per_location = 4; 15643 const GLuint n_types = getTypesNumber(); 15644 15645 for (GLuint i = 0; i < n_types; ++i) 15646 { 15647 const Utils::Type& type = getType(i); 15648 const GLuint n_req_components = type.m_n_rows; 15649 const GLuint valid_component = n_components_per_location - n_req_components; 15650 const GLuint invalid_component = valid_component + 1; 15651 15652 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 15653 { 15654 if (Utils::Shader::COMPUTE == stage) 15655 { 15656 continue; 15657 } 15658 15659 /* Component cannot be used for matrices */ 15660 if (1 != type.m_n_columns) 15661 { 15662 continue; 15663 } 15664 15665 testCase test_case_in_arr = { invalid_component, true, true, (Utils::Shader::STAGES)stage, type }; 15666 testCase test_case_in_one = { invalid_component, true, false, (Utils::Shader::STAGES)stage, type }; 15667 testCase test_case_out_arr = { invalid_component, false, true, (Utils::Shader::STAGES)stage, type }; 15668 testCase test_case_out_one = { invalid_component, false, false, (Utils::Shader::STAGES)stage, type }; 15669 15670 m_test_cases.push_back(test_case_in_arr); 15671 m_test_cases.push_back(test_case_in_one); 15672 15673 if (Utils::Shader::FRAGMENT != stage) 15674 { 15675 m_test_cases.push_back(test_case_out_arr); 15676 m_test_cases.push_back(test_case_out_one); 15677 } 15678 } 15679 } 15680 } 15681 15682 /** Constructor 15683 * 15684 * @param context Test framework context 15685 **/ 15686 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context& context) 15687 : NegativeTestBase(context, "varying_component_without_location", 15688 "Test verifies that compiler reports error when component qualifier is used without location") 15689 { 15690 } 15691 15692 /** Source for given test case and stage 15693 * 15694 * @param test_case_index Index of test case 15695 * @param stage Shader stage 15696 * 15697 * @return Shader source 15698 **/ 15699 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 15700 { 15701 static const GLchar* var_definition = "layout (component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n"; 15702 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n" 15703 " {\n" 15704 " result += vec4(1, 0.5, 0.25, 0.125);\n" 15705 " }\n"; 15706 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n" 15707 " if (vec4(0) == result)\n" 15708 " {\n" 15709 " gokuINDEX = TYPE(1);\n" 15710 " }\n"; 15711 static const GLchar* fs = "#version 430 core\n" 15712 "#extension GL_ARB_enhanced_layouts : require\n" 15713 "\n" 15714 "in vec4 gs_fs;\n" 15715 "out vec4 fs_out;\n" 15716 "\n" 15717 "void main()\n" 15718 "{\n" 15719 " fs_out = gs_fs;\n" 15720 "}\n" 15721 "\n"; 15722 static const GLchar* fs_tested = "#version 430 core\n" 15723 "#extension GL_ARB_enhanced_layouts : require\n" 15724 "\n" 15725 "VAR_DEFINITION" 15726 "\n" 15727 "in vec4 gs_fs;\n" 15728 "out vec4 fs_out;\n" 15729 "\n" 15730 "void main()\n" 15731 "{\n" 15732 " vec4 result = gs_fs;\n" 15733 "\n" 15734 "VARIABLE_USE" 15735 "\n" 15736 " fs_out = result;\n" 15737 "}\n" 15738 "\n"; 15739 static const GLchar* gs = "#version 430 core\n" 15740 "#extension GL_ARB_enhanced_layouts : require\n" 15741 "\n" 15742 "layout(points) in;\n" 15743 "layout(triangle_strip, max_vertices = 4) out;\n" 15744 "\n" 15745 "in vec4 tes_gs[];\n" 15746 "out vec4 gs_fs;\n" 15747 "\n" 15748 "void main()\n" 15749 "{\n" 15750 " gs_fs = tes_gs[0];\n" 15751 " gl_Position = vec4(-1, -1, 0, 1);\n" 15752 " EmitVertex();\n" 15753 " gs_fs = tes_gs[0];\n" 15754 " gl_Position = vec4(-1, 1, 0, 1);\n" 15755 " EmitVertex();\n" 15756 " gs_fs = tes_gs[0];\n" 15757 " gl_Position = vec4(1, -1, 0, 1);\n" 15758 " EmitVertex();\n" 15759 " gs_fs = tes_gs[0];\n" 15760 " gl_Position = vec4(1, 1, 0, 1);\n" 15761 " EmitVertex();\n" 15762 "}\n" 15763 "\n"; 15764 static const GLchar* gs_tested = "#version 430 core\n" 15765 "#extension GL_ARB_enhanced_layouts : require\n" 15766 "\n" 15767 "layout(points) in;\n" 15768 "layout(triangle_strip, max_vertices = 4) out;\n" 15769 "\n" 15770 "VAR_DEFINITION" 15771 "\n" 15772 "in vec4 tes_gs[];\n" 15773 "out vec4 gs_fs;\n" 15774 "\n" 15775 "void main()\n" 15776 "{\n" 15777 " vec4 result = tes_gs[0];\n" 15778 "\n" 15779 "VARIABLE_USE" 15780 "\n" 15781 " gs_fs = result;\n" 15782 " gl_Position = vec4(-1, -1, 0, 1);\n" 15783 " EmitVertex();\n" 15784 " gs_fs = result;\n" 15785 " gl_Position = vec4(-1, 1, 0, 1);\n" 15786 " EmitVertex();\n" 15787 " gs_fs = result;\n" 15788 " gl_Position = vec4(1, -1, 0, 1);\n" 15789 " EmitVertex();\n" 15790 " gs_fs = result;\n" 15791 " gl_Position = vec4(1, 1, 0, 1);\n" 15792 " EmitVertex();\n" 15793 "}\n" 15794 "\n"; 15795 static const GLchar* tcs = "#version 430 core\n" 15796 "#extension GL_ARB_enhanced_layouts : require\n" 15797 "\n" 15798 "layout(vertices = 1) out;\n" 15799 "\n" 15800 "in vec4 vs_tcs[];\n" 15801 "out vec4 tcs_tes[];\n" 15802 "\n" 15803 "void main()\n" 15804 "{\n" 15805 "\n" 15806 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 15807 "\n" 15808 " gl_TessLevelOuter[0] = 1.0;\n" 15809 " gl_TessLevelOuter[1] = 1.0;\n" 15810 " gl_TessLevelOuter[2] = 1.0;\n" 15811 " gl_TessLevelOuter[3] = 1.0;\n" 15812 " gl_TessLevelInner[0] = 1.0;\n" 15813 " gl_TessLevelInner[1] = 1.0;\n" 15814 "}\n" 15815 "\n"; 15816 static const GLchar* tcs_tested = "#version 430 core\n" 15817 "#extension GL_ARB_enhanced_layouts : require\n" 15818 "\n" 15819 "layout(vertices = 1) out;\n" 15820 "\n" 15821 "VAR_DEFINITION" 15822 "\n" 15823 "in vec4 vs_tcs[];\n" 15824 "out vec4 tcs_tes[];\n" 15825 "\n" 15826 "void main()\n" 15827 "{\n" 15828 " vec4 result = vs_tcs[gl_InvocationID];\n" 15829 "\n" 15830 "VARIABLE_USE" 15831 "\n" 15832 " tcs_tes[gl_InvocationID] = result;\n" 15833 "\n" 15834 " gl_TessLevelOuter[0] = 1.0;\n" 15835 " gl_TessLevelOuter[1] = 1.0;\n" 15836 " gl_TessLevelOuter[2] = 1.0;\n" 15837 " gl_TessLevelOuter[3] = 1.0;\n" 15838 " gl_TessLevelInner[0] = 1.0;\n" 15839 " gl_TessLevelInner[1] = 1.0;\n" 15840 "}\n" 15841 "\n"; 15842 static const GLchar* tes = "#version 430 core\n" 15843 "#extension GL_ARB_enhanced_layouts : require\n" 15844 "\n" 15845 "layout(isolines, point_mode) in;\n" 15846 "\n" 15847 "in vec4 tcs_tes[];\n" 15848 "out vec4 tes_gs;\n" 15849 "\n" 15850 "void main()\n" 15851 "{\n" 15852 " tes_gs = tcs_tes[0];\n" 15853 "}\n" 15854 "\n"; 15855 static const GLchar* tes_tested = "#version 430 core\n" 15856 "#extension GL_ARB_enhanced_layouts : require\n" 15857 "\n" 15858 "layout(isolines, point_mode) in;\n" 15859 "\n" 15860 "VAR_DEFINITION" 15861 "\n" 15862 "in vec4 tcs_tes[];\n" 15863 "out vec4 tes_gs;\n" 15864 "\n" 15865 "void main()\n" 15866 "{\n" 15867 " vec4 result = tcs_tes[0];\n" 15868 "\n" 15869 "VARIABLE_USE" 15870 "\n" 15871 " tes_gs = result;\n" 15872 "}\n" 15873 "\n"; 15874 static const GLchar* vs = "#version 430 core\n" 15875 "#extension GL_ARB_enhanced_layouts : require\n" 15876 "\n" 15877 "in vec4 in_vs;\n" 15878 "out vec4 vs_tcs;\n" 15879 "\n" 15880 "void main()\n" 15881 "{\n" 15882 " vs_tcs = in_vs;\n" 15883 "}\n" 15884 "\n"; 15885 static const GLchar* vs_tested = "#version 430 core\n" 15886 "#extension GL_ARB_enhanced_layouts : require\n" 15887 "\n" 15888 "VAR_DEFINITION" 15889 "\n" 15890 "in vec4 in_vs;\n" 15891 "out vec4 vs_tcs;\n" 15892 "\n" 15893 "void main()\n" 15894 "{\n" 15895 " vec4 result = in_vs;\n" 15896 "\n" 15897 "VARIABLE_USE" 15898 "\n" 15899 " vs_tcs = result;\n" 15900 "}\n" 15901 "\n"; 15902 15903 std::string source; 15904 testCase& test_case = m_test_cases[test_case_index]; 15905 15906 if (test_case.m_stage == stage) 15907 { 15908 const GLchar* array = ""; 15909 GLchar buffer[16]; 15910 const GLchar* direction = "in "; 15911 const GLchar* index = ""; 15912 size_t position = 0; 15913 size_t temp; 15914 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 15915 const GLchar* var_use = input_use; 15916 const GLchar* flat = "flat"; 15917 15918 if (false == test_case.m_is_input) 15919 { 15920 direction = "out"; 15921 var_use = output_use; 15922 } 15923 15924 sprintf(buffer, "%d", test_case.m_component); 15925 15926 switch (stage) 15927 { 15928 case Utils::Shader::FRAGMENT: 15929 source = fs_tested; 15930 break; 15931 case Utils::Shader::GEOMETRY: 15932 source = gs_tested; 15933 array = "[]"; 15934 index = "[0]"; 15935 break; 15936 case Utils::Shader::TESS_CTRL: 15937 source = tcs_tested; 15938 array = "[]"; 15939 index = "[gl_InvocationID]"; 15940 break; 15941 case Utils::Shader::TESS_EVAL: 15942 source = tes_tested; 15943 array = "[]"; 15944 index = "[0]"; 15945 break; 15946 case Utils::Shader::VERTEX: 15947 source = vs_tested; 15948 flat = ""; 15949 break; 15950 default: 15951 TCU_FAIL("Invalid enum"); 15952 } 15953 15954 temp = position; 15955 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 15956 position = temp; 15957 Utils::replaceToken("COMPONENT", position, buffer, source); 15958 Utils::replaceToken("FLAT", position, flat, source); 15959 Utils::replaceToken("DIRECTION", position, direction, source); 15960 Utils::replaceToken("ARRAY", position, array, source); 15961 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 15962 15963 Utils::replaceAllTokens("TYPE", type_name, source); 15964 Utils::replaceAllTokens("INDEX", index, source); 15965 } 15966 else 15967 { 15968 switch (stage) 15969 { 15970 case Utils::Shader::FRAGMENT: 15971 source = fs; 15972 break; 15973 case Utils::Shader::GEOMETRY: 15974 source = gs; 15975 break; 15976 case Utils::Shader::TESS_CTRL: 15977 source = tcs; 15978 break; 15979 case Utils::Shader::TESS_EVAL: 15980 source = tes; 15981 break; 15982 case Utils::Shader::VERTEX: 15983 source = vs; 15984 break; 15985 default: 15986 TCU_FAIL("Invalid enum"); 15987 } 15988 } 15989 15990 return source; 15991 } 15992 15993 /** Get description of test case 15994 * 15995 * @param test_case_index Index of test case 15996 * 15997 * @return Test case description 15998 **/ 15999 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index) 16000 { 16001 std::stringstream stream; 16002 testCase& test_case = m_test_cases[test_case_index]; 16003 16004 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 16005 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: "; 16006 16007 if (true == test_case.m_is_input) 16008 { 16009 stream << "input"; 16010 } 16011 else 16012 { 16013 stream << "output"; 16014 } 16015 16016 stream << ", component: " << test_case.m_component; 16017 16018 return stream.str(); 16019 } 16020 16021 /** Get number of test cases 16022 * 16023 * @return Number of test cases 16024 **/ 16025 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber() 16026 { 16027 return static_cast<GLuint>(m_test_cases.size()); 16028 } 16029 16030 /** Selects if "compute" stage is relevant for test 16031 * 16032 * @param ignored 16033 * 16034 * @return false 16035 **/ 16036 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */) 16037 { 16038 return false; 16039 } 16040 16041 /** Prepare all test cases 16042 * 16043 **/ 16044 void VaryingComponentWithoutLocationTest::testInit() 16045 { 16046 static const GLuint n_components_per_location = 4; 16047 const GLuint n_types = getTypesNumber(); 16048 16049 for (GLuint i = 0; i < n_types; ++i) 16050 { 16051 const Utils::Type& type = getType(i); 16052 const GLuint n_req_components = type.m_n_rows; 16053 const GLuint valid_component = n_components_per_location - n_req_components; 16054 16055 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 16056 { 16057 if (Utils::Shader::COMPUTE == stage) 16058 { 16059 continue; 16060 } 16061 16062 /* Component cannot be used for matrices */ 16063 if (1 != type.m_n_columns) 16064 { 16065 continue; 16066 } 16067 16068 testCase test_case_in = { valid_component, true, (Utils::Shader::STAGES)stage, type }; 16069 testCase test_case_out = { valid_component, false, (Utils::Shader::STAGES)stage, type }; 16070 16071 m_test_cases.push_back(test_case_in); 16072 16073 if (Utils::Shader::FRAGMENT != stage) 16074 { 16075 m_test_cases.push_back(test_case_out); 16076 } 16077 } 16078 } 16079 } 16080 16081 /** Constructor 16082 * 16083 * @param context Test framework context 16084 **/ 16085 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context& context) 16086 : NegativeTestBase(context, "varying_component_of_invalid_type", 16087 "Test verifies that compiler reports error when component qualifier is used for invalid type") 16088 { 16089 } 16090 16091 /** Source for given test case and stage 16092 * 16093 * @param test_case_index Index of test case 16094 * @param stage Shader stage 16095 * 16096 * @return Shader source 16097 **/ 16098 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 16099 { 16100 static const GLchar* block_definition_arr = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n" 16101 " TYPE member;\n" 16102 "} gokuARRAY[1];\n"; 16103 static const GLchar* block_definition_one = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n" 16104 " TYPE member;\n" 16105 "} gokuARRAY;\n"; 16106 static const GLchar* matrix_definition_arr = 16107 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n"; 16108 static const GLchar* matrix_definition_one = 16109 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n"; 16110 static const GLchar* struct_definition_arr = 16111 "struct Goku {\n" 16112 " TYPE member;\n" 16113 "};\n" 16114 "\n" 16115 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY[1];\n"; 16116 static const GLchar* struct_definition_one = 16117 "struct Goku {\n" 16118 " TYPE member;\n" 16119 "};\n" 16120 "\n" 16121 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY;\n"; 16122 static const GLchar* matrix_input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n" 16123 " {\n" 16124 " result += vec4(1, 0.5, 0.25, 0.125);\n" 16125 " }\n"; 16126 static const GLchar* matrix_input_use_one = " if (TYPE(0) == gokuINDEX)\n" 16127 " {\n" 16128 " result += vec4(1, 0.5, 0.25, 0.125);\n" 16129 " }\n"; 16130 static const GLchar* matrix_output_use_arr = " gokuINDEX[0] = TYPE(0);\n" 16131 " if (vec4(0) == result)\n" 16132 " {\n" 16133 " gokuINDEX[0] = TYPE(1);\n" 16134 " }\n"; 16135 static const GLchar* matrix_output_use_one = " gokuINDEX = TYPE(0);\n" 16136 " if (vec4(0) == result)\n" 16137 " {\n" 16138 " gokuINDEX = TYPE(1);\n" 16139 " }\n"; 16140 static const GLchar* member_input_use_arr = " if (TYPE(0) == gokuINDEX[0].member)\n" 16141 " {\n" 16142 " result += vec4(1, 0.5, 0.25, 0.125);\n" 16143 " }\n"; 16144 static const GLchar* member_input_use_one = " if (TYPE(0) == gokuINDEX.member)\n" 16145 " {\n" 16146 " result += vec4(1, 0.5, 0.25, 0.125);\n" 16147 " }\n"; 16148 static const GLchar* member_output_use_arr = " gokuINDEX[0].member = TYPE(0);\n" 16149 " if (vec4(0) == result)\n" 16150 " {\n" 16151 " gokuINDEX[0].member = TYPE(1);\n" 16152 " }\n"; 16153 static const GLchar* member_output_use_one = " gokuINDEX.member = TYPE(0);\n" 16154 " if (vec4(0) == result)\n" 16155 " {\n" 16156 " gokuINDEX.member = TYPE(1);\n" 16157 " }\n"; 16158 static const GLchar* fs = "#version 430 core\n" 16159 "#extension GL_ARB_enhanced_layouts : require\n" 16160 "\n" 16161 "in vec4 gs_fs;\n" 16162 "out vec4 fs_out;\n" 16163 "\n" 16164 "void main()\n" 16165 "{\n" 16166 " fs_out = gs_fs;\n" 16167 "}\n" 16168 "\n"; 16169 static const GLchar* fs_tested = "#version 430 core\n" 16170 "#extension GL_ARB_enhanced_layouts : require\n" 16171 "\n" 16172 "VAR_DEFINITION" 16173 "\n" 16174 "in vec4 gs_fs;\n" 16175 "out vec4 fs_out;\n" 16176 "\n" 16177 "void main()\n" 16178 "{\n" 16179 " vec4 result = gs_fs;\n" 16180 "\n" 16181 "VARIABLE_USE" 16182 "\n" 16183 " fs_out += result;\n" 16184 "}\n" 16185 "\n"; 16186 static const GLchar* gs = "#version 430 core\n" 16187 "#extension GL_ARB_enhanced_layouts : require\n" 16188 "\n" 16189 "layout(points) in;\n" 16190 "layout(triangle_strip, max_vertices = 4) out;\n" 16191 "\n" 16192 "in vec4 tes_gs[];\n" 16193 "out vec4 gs_fs;\n" 16194 "\n" 16195 "void main()\n" 16196 "{\n" 16197 " gs_fs = tes_gs[0];\n" 16198 " gl_Position = vec4(-1, -1, 0, 1);\n" 16199 " EmitVertex();\n" 16200 " gs_fs = tes_gs[0];\n" 16201 " gl_Position = vec4(-1, 1, 0, 1);\n" 16202 " EmitVertex();\n" 16203 " gs_fs = tes_gs[0];\n" 16204 " gl_Position = vec4(1, -1, 0, 1);\n" 16205 " EmitVertex();\n" 16206 " gs_fs = tes_gs[0];\n" 16207 " gl_Position = vec4(1, 1, 0, 1);\n" 16208 " EmitVertex();\n" 16209 "}\n" 16210 "\n"; 16211 static const GLchar* gs_tested = "#version 430 core\n" 16212 "#extension GL_ARB_enhanced_layouts : require\n" 16213 "\n" 16214 "layout(points) in;\n" 16215 "layout(triangle_strip, max_vertices = 4) out;\n" 16216 "\n" 16217 "VAR_DEFINITION" 16218 "\n" 16219 "in vec4 tes_gs[];\n" 16220 "out vec4 gs_fs;\n" 16221 "\n" 16222 "void main()\n" 16223 "{\n" 16224 " vec4 result = tes_gs[0];\n" 16225 "\n" 16226 "VARIABLE_USE" 16227 "\n" 16228 " gs_fs = result;\n" 16229 " gl_Position = vec4(-1, -1, 0, 1);\n" 16230 " EmitVertex();\n" 16231 " gs_fs = result;\n" 16232 " gl_Position = vec4(-1, 1, 0, 1);\n" 16233 " EmitVertex();\n" 16234 " gs_fs = result;\n" 16235 " gl_Position = vec4(1, -1, 0, 1);\n" 16236 " EmitVertex();\n" 16237 " gs_fs = result;\n" 16238 " gl_Position = vec4(1, 1, 0, 1);\n" 16239 " EmitVertex();\n" 16240 "}\n" 16241 "\n"; 16242 static const GLchar* tcs = "#version 430 core\n" 16243 "#extension GL_ARB_enhanced_layouts : require\n" 16244 "\n" 16245 "layout(vertices = 1) out;\n" 16246 "\n" 16247 "in vec4 vs_tcs[];\n" 16248 "out vec4 tcs_tes[];\n" 16249 "\n" 16250 "void main()\n" 16251 "{\n" 16252 "\n" 16253 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 16254 "\n" 16255 " gl_TessLevelOuter[0] = 1.0;\n" 16256 " gl_TessLevelOuter[1] = 1.0;\n" 16257 " gl_TessLevelOuter[2] = 1.0;\n" 16258 " gl_TessLevelOuter[3] = 1.0;\n" 16259 " gl_TessLevelInner[0] = 1.0;\n" 16260 " gl_TessLevelInner[1] = 1.0;\n" 16261 "}\n" 16262 "\n"; 16263 static const GLchar* tcs_tested = "#version 430 core\n" 16264 "#extension GL_ARB_enhanced_layouts : require\n" 16265 "\n" 16266 "layout(vertices = 1) out;\n" 16267 "\n" 16268 "VAR_DEFINITION" 16269 "\n" 16270 "in vec4 vs_tcs[];\n" 16271 "out vec4 tcs_tes[];\n" 16272 "\n" 16273 "void main()\n" 16274 "{\n" 16275 " vec4 result = vs_tcs[gl_InvocationID];\n" 16276 "\n" 16277 "VARIABLE_USE" 16278 "\n" 16279 " tcs_tes[gl_InvocationID] = result;\n" 16280 "\n" 16281 " gl_TessLevelOuter[0] = 1.0;\n" 16282 " gl_TessLevelOuter[1] = 1.0;\n" 16283 " gl_TessLevelOuter[2] = 1.0;\n" 16284 " gl_TessLevelOuter[3] = 1.0;\n" 16285 " gl_TessLevelInner[0] = 1.0;\n" 16286 " gl_TessLevelInner[1] = 1.0;\n" 16287 "}\n" 16288 "\n"; 16289 static const GLchar* tes = "#version 430 core\n" 16290 "#extension GL_ARB_enhanced_layouts : require\n" 16291 "\n" 16292 "layout(isolines, point_mode) in;\n" 16293 "\n" 16294 "in vec4 tcs_tes[];\n" 16295 "out vec4 tes_gs;\n" 16296 "\n" 16297 "void main()\n" 16298 "{\n" 16299 " tes_gs = tcs_tes[0];\n" 16300 "}\n" 16301 "\n"; 16302 static const GLchar* tes_tested = "#version 430 core\n" 16303 "#extension GL_ARB_enhanced_layouts : require\n" 16304 "\n" 16305 "layout(isolines, point_mode) in;\n" 16306 "\n" 16307 "VAR_DEFINITION" 16308 "\n" 16309 "in vec4 tcs_tes[];\n" 16310 "out vec4 tes_gs;\n" 16311 "\n" 16312 "void main()\n" 16313 "{\n" 16314 " vec4 result = tcs_tes[0];\n" 16315 "\n" 16316 "VARIABLE_USE" 16317 "\n" 16318 " tes_gs += result;\n" 16319 "}\n" 16320 "\n"; 16321 static const GLchar* vs = "#version 430 core\n" 16322 "#extension GL_ARB_enhanced_layouts : require\n" 16323 "\n" 16324 "in vec4 in_vs;\n" 16325 "out vec4 vs_tcs;\n" 16326 "\n" 16327 "void main()\n" 16328 "{\n" 16329 " vs_tcs = in_vs;\n" 16330 "}\n" 16331 "\n"; 16332 static const GLchar* vs_tested = "#version 430 core\n" 16333 "#extension GL_ARB_enhanced_layouts : require\n" 16334 "\n" 16335 "VAR_DEFINITION" 16336 "\n" 16337 "in vec4 in_vs;\n" 16338 "out vec4 vs_tcs;\n" 16339 "\n" 16340 "void main()\n" 16341 "{\n" 16342 " vec4 result = in_vs;\n" 16343 "\n" 16344 "VARIABLE_USE" 16345 "\n" 16346 " vs_tcs += result;\n" 16347 "}\n" 16348 "\n"; 16349 16350 std::string source; 16351 testCase& test_case = m_test_cases[test_case_index]; 16352 16353 if (test_case.m_stage == stage) 16354 { 16355 const GLchar* array = ""; 16356 GLchar buffer[16]; 16357 const GLchar* var_definition = 0; 16358 const GLchar* direction = "in "; 16359 const GLchar* index = ""; 16360 size_t position = 0; 16361 size_t temp; 16362 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 16363 const GLchar* var_use = 0; 16364 16365 if (false == test_case.m_is_input) 16366 { 16367 direction = "out"; 16368 16369 if (false == test_case.m_is_array) 16370 { 16371 switch (test_case.m_case) 16372 { 16373 case BLOCK: 16374 var_definition = block_definition_one; 16375 var_use = member_output_use_one; 16376 break; 16377 case MATRIX: 16378 var_definition = matrix_definition_one; 16379 var_use = matrix_output_use_one; 16380 break; 16381 case STRUCT: 16382 var_definition = struct_definition_one; 16383 var_use = member_output_use_one; 16384 break; 16385 default: 16386 TCU_FAIL("Invalid enum"); 16387 } 16388 } 16389 else 16390 { 16391 switch (test_case.m_case) 16392 { 16393 case BLOCK: 16394 var_definition = block_definition_arr; 16395 var_use = member_output_use_arr; 16396 break; 16397 case MATRIX: 16398 var_definition = matrix_definition_arr; 16399 var_use = matrix_output_use_arr; 16400 break; 16401 case STRUCT: 16402 var_definition = struct_definition_arr; 16403 var_use = member_output_use_arr; 16404 break; 16405 default: 16406 TCU_FAIL("Invalid enum"); 16407 } 16408 } 16409 } 16410 else 16411 { 16412 if (false == test_case.m_is_array) 16413 { 16414 switch (test_case.m_case) 16415 { 16416 case BLOCK: 16417 var_definition = block_definition_one; 16418 var_use = member_input_use_one; 16419 break; 16420 case MATRIX: 16421 var_definition = matrix_definition_one; 16422 var_use = matrix_input_use_one; 16423 break; 16424 case STRUCT: 16425 var_definition = struct_definition_one; 16426 var_use = member_input_use_one; 16427 break; 16428 default: 16429 TCU_FAIL("Invalid enum"); 16430 } 16431 } 16432 else 16433 { 16434 switch (test_case.m_case) 16435 { 16436 case BLOCK: 16437 var_definition = block_definition_arr; 16438 var_use = member_input_use_arr; 16439 break; 16440 case MATRIX: 16441 var_definition = matrix_definition_arr; 16442 var_use = matrix_input_use_arr; 16443 break; 16444 case STRUCT: 16445 var_definition = struct_definition_arr; 16446 var_use = member_input_use_arr; 16447 break; 16448 default: 16449 TCU_FAIL("Invalid enum"); 16450 } 16451 } 16452 } 16453 16454 sprintf(buffer, "%d", test_case.m_component); 16455 16456 switch (stage) 16457 { 16458 case Utils::Shader::FRAGMENT: 16459 source = fs_tested; 16460 break; 16461 case Utils::Shader::GEOMETRY: 16462 source = gs_tested; 16463 array = "[]"; 16464 index = "[0]"; 16465 break; 16466 case Utils::Shader::TESS_CTRL: 16467 source = tcs_tested; 16468 array = "[]"; 16469 index = "[gl_InvocationID]"; 16470 break; 16471 case Utils::Shader::TESS_EVAL: 16472 source = tes_tested; 16473 array = "[]"; 16474 index = "[0]"; 16475 break; 16476 case Utils::Shader::VERTEX: 16477 source = vs_tested; 16478 break; 16479 default: 16480 TCU_FAIL("Invalid enum"); 16481 } 16482 16483 temp = position; 16484 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 16485 position = temp; 16486 Utils::replaceToken("COMPONENT", position, buffer, source); 16487 Utils::replaceToken("DIRECTION", position, direction, source); 16488 Utils::replaceToken("ARRAY", position, array, source); 16489 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 16490 16491 Utils::replaceAllTokens("TYPE", type_name, source); 16492 Utils::replaceAllTokens("INDEX", index, source); 16493 } 16494 else 16495 { 16496 switch (stage) 16497 { 16498 case Utils::Shader::FRAGMENT: 16499 source = fs; 16500 break; 16501 case Utils::Shader::GEOMETRY: 16502 source = gs; 16503 break; 16504 case Utils::Shader::TESS_CTRL: 16505 source = tcs; 16506 break; 16507 case Utils::Shader::TESS_EVAL: 16508 source = tes; 16509 break; 16510 case Utils::Shader::VERTEX: 16511 source = vs; 16512 break; 16513 default: 16514 TCU_FAIL("Invalid enum"); 16515 } 16516 } 16517 16518 return source; 16519 } 16520 16521 /** Get description of test case 16522 * 16523 * @param test_case_index Index of test case 16524 * 16525 * @return Test case description 16526 **/ 16527 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index) 16528 { 16529 std::stringstream stream; 16530 testCase& test_case = m_test_cases[test_case_index]; 16531 16532 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 16533 << " type: " << test_case.m_type.GetGLSLTypeName(); 16534 16535 if (true == test_case.m_is_array) 16536 { 16537 stream << "[1]"; 16538 } 16539 16540 stream << ", direction: "; 16541 16542 if (true == test_case.m_is_input) 16543 { 16544 stream << "input"; 16545 } 16546 else 16547 { 16548 stream << "output"; 16549 } 16550 16551 stream << ", component: " << test_case.m_component; 16552 16553 return stream.str(); 16554 } 16555 16556 /** Get number of test cases 16557 * 16558 * @return Number of test cases 16559 **/ 16560 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber() 16561 { 16562 return static_cast<GLuint>(m_test_cases.size()); 16563 } 16564 16565 /** Selects if "compute" stage is relevant for test 16566 * 16567 * @param ignored 16568 * 16569 * @return false 16570 **/ 16571 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */) 16572 { 16573 return false; 16574 } 16575 16576 /** Prepare all test cases 16577 * 16578 **/ 16579 void VaryingComponentOfInvalidTypeTest::testInit() 16580 { 16581 static const GLuint n_components_per_location = 4; 16582 const GLuint n_types = getTypesNumber(); 16583 16584 for (GLuint i = 0; i < n_types; ++i) 16585 { 16586 const Utils::Type& type = getType(i); 16587 const GLuint n_req_components = type.m_n_rows; 16588 const GLuint valid_component = n_components_per_location - n_req_components; 16589 16590 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 16591 { 16592 if (Utils::Shader::COMPUTE == stage) 16593 { 16594 continue; 16595 } 16596 16597 /* Use different CASE for matrices */ 16598 if (1 != type.m_n_columns) 16599 { 16600 testCase test_case_in_arr = { MATRIX, valid_component, true, true, (Utils::Shader::STAGES)stage, type }; 16601 testCase test_case_in_one = { 16602 MATRIX, valid_component, false, true, (Utils::Shader::STAGES)stage, type 16603 }; 16604 testCase test_case_out_arr = { 16605 MATRIX, valid_component, true, false, (Utils::Shader::STAGES)stage, type 16606 }; 16607 testCase test_case_out_one = { 16608 MATRIX, valid_component, false, false, (Utils::Shader::STAGES)stage, type 16609 }; 16610 16611 m_test_cases.push_back(test_case_in_arr); 16612 m_test_cases.push_back(test_case_in_one); 16613 16614 if (Utils::Shader::FRAGMENT != stage) 16615 { 16616 m_test_cases.push_back(test_case_out_arr); 16617 m_test_cases.push_back(test_case_out_one); 16618 } 16619 } 16620 else 16621 { 16622 for (GLuint c = BLOCK; c < MAX_CASES; ++c) 16623 { 16624 testCase test_case_in_arr = { (CASES)c, valid_component, true, true, (Utils::Shader::STAGES)stage, 16625 type }; 16626 testCase test_case_in_one = { (CASES)c, valid_component, false, true, (Utils::Shader::STAGES)stage, 16627 type }; 16628 testCase test_case_out_arr = { (CASES)c, valid_component, true, false, (Utils::Shader::STAGES)stage, 16629 type }; 16630 testCase test_case_out_one = { 16631 (CASES)c, valid_component, false, false, (Utils::Shader::STAGES)stage, type 16632 }; 16633 16634 if (Utils::Shader::VERTEX != stage) 16635 { 16636 m_test_cases.push_back(test_case_in_arr); 16637 m_test_cases.push_back(test_case_in_one); 16638 } 16639 16640 if (Utils::Shader::FRAGMENT != stage) 16641 { 16642 m_test_cases.push_back(test_case_out_arr); 16643 m_test_cases.push_back(test_case_out_one); 16644 } 16645 } 16646 } 16647 } 16648 } 16649 } 16650 16651 /** Constructor 16652 * 16653 * @param context Test framework context 16654 **/ 16655 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context& context) 16656 : NegativeTestBase(context, "input_component_aliasing", 16657 "Test verifies that compiler reports component aliasing as error") 16658 { 16659 } 16660 16661 /** Source for given test case and stage 16662 * 16663 * @param test_case_index Index of test case 16664 * @param stage Shader stage 16665 * 16666 * @return Shader source 16667 **/ 16668 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 16669 { 16670 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n" 16671 "layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n"; 16672 static const GLchar* test_one = " if (TYPE(0) == gohanINDEX)\n" 16673 " {\n" 16674 " result += vec4(1, 0.5, 0.25, 0.125);\n" 16675 " }\n"; 16676 static const GLchar* fs = "#version 430 core\n" 16677 "#extension GL_ARB_enhanced_layouts : require\n" 16678 "\n" 16679 "in vec4 gs_fs;\n" 16680 "out vec4 fs_out;\n" 16681 "\n" 16682 "void main()\n" 16683 "{\n" 16684 " fs_out = gs_fs;\n" 16685 "}\n" 16686 "\n"; 16687 static const GLchar* fs_tested = "#version 430 core\n" 16688 "#extension GL_ARB_enhanced_layouts : require\n" 16689 "\n" 16690 "VAR_DEFINITION" 16691 "\n" 16692 "in vec4 gs_fs;\n" 16693 "out vec4 fs_out;\n" 16694 "\n" 16695 "void main()\n" 16696 "{\n" 16697 " vec4 result = gs_fs;\n" 16698 "\n" 16699 "VARIABLE_USE" 16700 "\n" 16701 " fs_out += result;\n" 16702 "}\n" 16703 "\n"; 16704 static const GLchar* gs = "#version 430 core\n" 16705 "#extension GL_ARB_enhanced_layouts : require\n" 16706 "\n" 16707 "layout(points) in;\n" 16708 "layout(triangle_strip, max_vertices = 4) out;\n" 16709 "\n" 16710 "in vec4 tes_gs[];\n" 16711 "out vec4 gs_fs;\n" 16712 "\n" 16713 "void main()\n" 16714 "{\n" 16715 " gs_fs = tes_gs[0];\n" 16716 " gl_Position = vec4(-1, -1, 0, 1);\n" 16717 " EmitVertex();\n" 16718 " gs_fs = tes_gs[0];\n" 16719 " gl_Position = vec4(-1, 1, 0, 1);\n" 16720 " EmitVertex();\n" 16721 " gs_fs = tes_gs[0];\n" 16722 " gl_Position = vec4(1, -1, 0, 1);\n" 16723 " EmitVertex();\n" 16724 " gs_fs = tes_gs[0];\n" 16725 " gl_Position = vec4(1, 1, 0, 1);\n" 16726 " EmitVertex();\n" 16727 "}\n" 16728 "\n"; 16729 static const GLchar* gs_tested = "#version 430 core\n" 16730 "#extension GL_ARB_enhanced_layouts : require\n" 16731 "\n" 16732 "layout(points) in;\n" 16733 "layout(triangle_strip, max_vertices = 4) out;\n" 16734 "\n" 16735 "VAR_DEFINITION" 16736 "\n" 16737 "in vec4 tes_gs[];\n" 16738 "out vec4 gs_fs;\n" 16739 "\n" 16740 "void main()\n" 16741 "{\n" 16742 " vec4 result = tes_gs[0];\n" 16743 "\n" 16744 "VARIABLE_USE" 16745 "\n" 16746 " gs_fs = result;\n" 16747 " gl_Position = vec4(-1, -1, 0, 1);\n" 16748 " EmitVertex();\n" 16749 " gs_fs = result;\n" 16750 " gl_Position = vec4(-1, 1, 0, 1);\n" 16751 " EmitVertex();\n" 16752 " gs_fs = result;\n" 16753 " gl_Position = vec4(1, -1, 0, 1);\n" 16754 " EmitVertex();\n" 16755 " gs_fs = result;\n" 16756 " gl_Position = vec4(1, 1, 0, 1);\n" 16757 " EmitVertex();\n" 16758 "}\n" 16759 "\n"; 16760 static const GLchar* tcs = "#version 430 core\n" 16761 "#extension GL_ARB_enhanced_layouts : require\n" 16762 "\n" 16763 "layout(vertices = 1) out;\n" 16764 "\n" 16765 "in vec4 vs_tcs[];\n" 16766 "out vec4 tcs_tes[];\n" 16767 "\n" 16768 "void main()\n" 16769 "{\n" 16770 "\n" 16771 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 16772 "\n" 16773 " gl_TessLevelOuter[0] = 1.0;\n" 16774 " gl_TessLevelOuter[1] = 1.0;\n" 16775 " gl_TessLevelOuter[2] = 1.0;\n" 16776 " gl_TessLevelOuter[3] = 1.0;\n" 16777 " gl_TessLevelInner[0] = 1.0;\n" 16778 " gl_TessLevelInner[1] = 1.0;\n" 16779 "}\n" 16780 "\n"; 16781 static const GLchar* tcs_tested = "#version 430 core\n" 16782 "#extension GL_ARB_enhanced_layouts : require\n" 16783 "\n" 16784 "layout(vertices = 1) out;\n" 16785 "\n" 16786 "VAR_DEFINITION" 16787 "\n" 16788 "in vec4 vs_tcs[];\n" 16789 "out vec4 tcs_tes[];\n" 16790 "\n" 16791 "void main()\n" 16792 "{\n" 16793 " vec4 result = vs_tcs[gl_InvocationID];\n" 16794 "\n" 16795 "VARIABLE_USE" 16796 "\n" 16797 " tcs_tes[gl_InvocationID] = result;\n" 16798 "\n" 16799 " gl_TessLevelOuter[0] = 1.0;\n" 16800 " gl_TessLevelOuter[1] = 1.0;\n" 16801 " gl_TessLevelOuter[2] = 1.0;\n" 16802 " gl_TessLevelOuter[3] = 1.0;\n" 16803 " gl_TessLevelInner[0] = 1.0;\n" 16804 " gl_TessLevelInner[1] = 1.0;\n" 16805 "}\n" 16806 "\n"; 16807 static const GLchar* tes = "#version 430 core\n" 16808 "#extension GL_ARB_enhanced_layouts : require\n" 16809 "\n" 16810 "layout(isolines, point_mode) in;\n" 16811 "\n" 16812 "in vec4 tcs_tes[];\n" 16813 "out vec4 tes_gs;\n" 16814 "\n" 16815 "void main()\n" 16816 "{\n" 16817 " tes_gs = tcs_tes[0];\n" 16818 "}\n" 16819 "\n"; 16820 static const GLchar* tes_tested = "#version 430 core\n" 16821 "#extension GL_ARB_enhanced_layouts : require\n" 16822 "\n" 16823 "layout(isolines, point_mode) in;\n" 16824 "\n" 16825 "VAR_DEFINITION" 16826 "\n" 16827 "in vec4 tcs_tes[];\n" 16828 "out vec4 tes_gs;\n" 16829 "\n" 16830 "void main()\n" 16831 "{\n" 16832 " vec4 result = tcs_tes[0];\n" 16833 "\n" 16834 "VARIABLE_USE" 16835 "\n" 16836 " tes_gs += result;\n" 16837 "}\n" 16838 "\n"; 16839 static const GLchar* vs = "#version 430 core\n" 16840 "#extension GL_ARB_enhanced_layouts : require\n" 16841 "\n" 16842 "in vec4 in_vs;\n" 16843 "out vec4 vs_tcs;\n" 16844 "\n" 16845 "void main()\n" 16846 "{\n" 16847 " vs_tcs = in_vs;\n" 16848 "}\n" 16849 "\n"; 16850 static const GLchar* vs_tested = "#version 430 core\n" 16851 "#extension GL_ARB_enhanced_layouts : require\n" 16852 "\n" 16853 "VAR_DEFINITION" 16854 "\n" 16855 "in vec4 in_vs;\n" 16856 "out vec4 vs_tcs;\n" 16857 "\n" 16858 "void main()\n" 16859 "{\n" 16860 " vec4 result = in_vs;\n" 16861 "\n" 16862 "VARIABLE_USE" 16863 "\n" 16864 " vs_tcs += result;\n" 16865 "}\n" 16866 "\n"; 16867 16868 std::string source; 16869 testCase& test_case = m_test_cases[test_case_index]; 16870 16871 if (test_case.m_stage == stage) 16872 { 16873 const GLchar* array = ""; 16874 GLchar buffer_gohan[16]; 16875 GLchar buffer_goten[16]; 16876 const GLchar* flat = ""; 16877 const GLchar* index = ""; 16878 const bool is_flat_req = isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT); 16879 size_t position = 0; 16880 size_t temp; 16881 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 16882 const GLchar* var_use = test_one; 16883 16884 if (true == is_flat_req) 16885 { 16886 flat = "flat"; 16887 } 16888 16889 sprintf(buffer_gohan, "%d", test_case.m_component_gohan); 16890 sprintf(buffer_goten, "%d", test_case.m_component_goten); 16891 16892 switch (stage) 16893 { 16894 case Utils::Shader::FRAGMENT: 16895 source = fs_tested; 16896 break; 16897 case Utils::Shader::GEOMETRY: 16898 source = gs_tested; 16899 array = "[]"; 16900 index = "[0]"; 16901 break; 16902 case Utils::Shader::TESS_CTRL: 16903 source = tcs_tested; 16904 array = "[]"; 16905 index = "[gl_InvocationID]"; 16906 break; 16907 case Utils::Shader::TESS_EVAL: 16908 source = tes_tested; 16909 array = "[]"; 16910 index = "[0]"; 16911 break; 16912 case Utils::Shader::VERTEX: 16913 source = vs_tested; 16914 break; 16915 default: 16916 TCU_FAIL("Invalid enum"); 16917 } 16918 16919 temp = position; 16920 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 16921 position = temp; 16922 Utils::replaceToken("COMPONENT", position, buffer_gohan, source); 16923 Utils::replaceToken("ARRAY", position, array, source); 16924 Utils::replaceToken("COMPONENT", position, buffer_goten, source); 16925 Utils::replaceToken("ARRAY", position, array, source); 16926 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 16927 16928 Utils::replaceAllTokens("FLAT", flat, source); 16929 Utils::replaceAllTokens("TYPE", type_name, source); 16930 Utils::replaceAllTokens("INDEX", index, source); 16931 } 16932 else 16933 { 16934 switch (stage) 16935 { 16936 case Utils::Shader::FRAGMENT: 16937 source = fs; 16938 break; 16939 case Utils::Shader::GEOMETRY: 16940 source = gs; 16941 break; 16942 case Utils::Shader::TESS_CTRL: 16943 source = tcs; 16944 break; 16945 case Utils::Shader::TESS_EVAL: 16946 source = tes; 16947 break; 16948 case Utils::Shader::VERTEX: 16949 source = vs; 16950 break; 16951 default: 16952 TCU_FAIL("Invalid enum"); 16953 } 16954 } 16955 16956 return source; 16957 } 16958 16959 /** Get description of test case 16960 * 16961 * @param test_case_index Index of test case 16962 * 16963 * @return Test case description 16964 **/ 16965 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index) 16966 { 16967 std::stringstream stream; 16968 testCase& test_case = m_test_cases[test_case_index]; 16969 16970 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 16971 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan 16972 << " & " << test_case.m_component_goten; 16973 16974 return stream.str(); 16975 } 16976 16977 /** Get number of test cases 16978 * 16979 * @return Number of test cases 16980 **/ 16981 GLuint InputComponentAliasingTest::getTestCaseNumber() 16982 { 16983 return static_cast<GLuint>(m_test_cases.size()); 16984 } 16985 16986 /** Selects if "compute" stage is relevant for test 16987 * 16988 * @param ignored 16989 * 16990 * @return false 16991 **/ 16992 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */) 16993 { 16994 return false; 16995 } 16996 16997 /** Selects if compilation failure is expected result 16998 * 16999 * @param test_case_index Index of test case 17000 * 17001 * @return false for VS that use only single variable, true otherwise 17002 **/ 17003 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index) 17004 { 17005 testCase& test_case = m_test_cases[test_case_index]; 17006 17007 return (Utils::Shader::VERTEX != test_case.m_stage); 17008 } 17009 17010 /** Prepare all test cases 17011 * 17012 **/ 17013 void InputComponentAliasingTest::testInit() 17014 { 17015 const GLuint n_types = getTypesNumber(); 17016 17017 for (GLuint i = 0; i < n_types; ++i) 17018 { 17019 const Utils::Type& type = getType(i); 17020 const bool use_double = (Utils::Type::Double == type.m_basic_type); 17021 const GLuint n_components_per_location = use_double ? 2 : 4; 17022 const GLuint n_req_components = type.m_n_rows; 17023 const GLint valid_component = (GLint)n_components_per_location - (GLint)n_req_components; 17024 const GLuint component_size = use_double ? 2 : 1; 17025 /* Skip matrices */ 17026 if (1 != type.m_n_columns) 17027 { 17028 continue; 17029 } 17030 /* Skip dvec3/dvec4 which doesn't support the component qualifier */ 17031 if (valid_component < 0) 17032 { 17033 continue; 17034 } 17035 17036 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 17037 { 17038 if (Utils::Shader::COMPUTE == stage) 17039 { 17040 continue; 17041 } 17042 17043 for (GLuint gohan = 0; gohan <= (GLuint)valid_component; ++gohan) 17044 { 17045 const GLint first_aliasing = gohan - n_req_components + 1; 17046 const GLint last_aliasing = gohan + n_req_components - 1; 17047 17048 const GLuint goten_start = std::max(0, first_aliasing); 17049 const GLuint goten_stop = std::min(valid_component, last_aliasing); 17050 17051 for (GLuint goten = goten_start; goten <= goten_stop; ++goten) 17052 { 17053 testCase test_case = { gohan * component_size, goten * component_size, (Utils::Shader::STAGES)stage, 17054 type }; 17055 17056 m_test_cases.push_back(test_case); 17057 } 17058 } 17059 } 17060 } 17061 } 17062 17063 /** Constructor 17064 * 17065 * @param context Test framework context 17066 **/ 17067 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context& context) 17068 : NegativeTestBase(context, "output_component_aliasing", 17069 "Test verifies that compiler reports component aliasing as error") 17070 { 17071 } 17072 17073 /** Source for given test case and stage 17074 * 17075 * @param test_case_index Index of test case 17076 * @param stage Shader stage 17077 * 17078 * @return Shader source 17079 **/ 17080 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 17081 { 17082 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) flat out TYPE gohanARRAY;\n" 17083 "layout (location = 1, component = COMPONENT) flat out TYPE gotenARRAY;\n"; 17084 static const GLchar* l_test = " gohanINDEX = TYPE(1);\n" 17085 " gotenINDEX = TYPE(0);\n"; 17086 static const GLchar* fs = "#version 430 core\n" 17087 "#extension GL_ARB_enhanced_layouts : require\n" 17088 "\n" 17089 "in vec4 gs_fs;\n" 17090 "out vec4 fs_out;\n" 17091 "\n" 17092 "void main()\n" 17093 "{\n" 17094 " fs_out = gs_fs;\n" 17095 "}\n" 17096 "\n"; 17097 static const GLchar* fs_tested = "#version 430 core\n" 17098 "#extension GL_ARB_enhanced_layouts : require\n" 17099 "\n" 17100 "VAR_DEFINITION" 17101 "\n" 17102 "in vec4 gs_fs;\n" 17103 "out vec4 fs_out;\n" 17104 "\n" 17105 "void main()\n" 17106 "{\n" 17107 " vec4 result = gs_fs;\n" 17108 "\n" 17109 "VARIABLE_USE" 17110 "\n" 17111 " fs_out += result;\n" 17112 "}\n" 17113 "\n"; 17114 static const GLchar* gs = "#version 430 core\n" 17115 "#extension GL_ARB_enhanced_layouts : require\n" 17116 "\n" 17117 "layout(points) in;\n" 17118 "layout(triangle_strip, max_vertices = 4) out;\n" 17119 "\n" 17120 "in vec4 tes_gs[];\n" 17121 "out vec4 gs_fs;\n" 17122 "\n" 17123 "void main()\n" 17124 "{\n" 17125 " gs_fs = tes_gs[0];\n" 17126 " gl_Position = vec4(-1, -1, 0, 1);\n" 17127 " EmitVertex();\n" 17128 " gs_fs = tes_gs[0];\n" 17129 " gl_Position = vec4(-1, 1, 0, 1);\n" 17130 " EmitVertex();\n" 17131 " gs_fs = tes_gs[0];\n" 17132 " gl_Position = vec4(1, -1, 0, 1);\n" 17133 " EmitVertex();\n" 17134 " gs_fs = tes_gs[0];\n" 17135 " gl_Position = vec4(1, 1, 0, 1);\n" 17136 " EmitVertex();\n" 17137 "}\n" 17138 "\n"; 17139 static const GLchar* gs_tested = "#version 430 core\n" 17140 "#extension GL_ARB_enhanced_layouts : require\n" 17141 "\n" 17142 "layout(points) in;\n" 17143 "layout(triangle_strip, max_vertices = 4) out;\n" 17144 "\n" 17145 "VAR_DEFINITION" 17146 "\n" 17147 "in vec4 tes_gs[];\n" 17148 "out vec4 gs_fs;\n" 17149 "\n" 17150 "void main()\n" 17151 "{\n" 17152 " vec4 result = tes_gs[0];\n" 17153 "\n" 17154 "VARIABLE_USE" 17155 "\n" 17156 " gs_fs = result;\n" 17157 " gl_Position = vec4(-1, -1, 0, 1);\n" 17158 " EmitVertex();\n" 17159 " gs_fs = result;\n" 17160 " gl_Position = vec4(-1, 1, 0, 1);\n" 17161 " EmitVertex();\n" 17162 " gs_fs = result;\n" 17163 " gl_Position = vec4(1, -1, 0, 1);\n" 17164 " EmitVertex();\n" 17165 " gs_fs = result;\n" 17166 " gl_Position = vec4(1, 1, 0, 1);\n" 17167 " EmitVertex();\n" 17168 "}\n" 17169 "\n"; 17170 static const GLchar* tcs = "#version 430 core\n" 17171 "#extension GL_ARB_enhanced_layouts : require\n" 17172 "\n" 17173 "layout(vertices = 1) out;\n" 17174 "\n" 17175 "in vec4 vs_tcs[];\n" 17176 "out vec4 tcs_tes[];\n" 17177 "\n" 17178 "void main()\n" 17179 "{\n" 17180 "\n" 17181 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 17182 "\n" 17183 " gl_TessLevelOuter[0] = 1.0;\n" 17184 " gl_TessLevelOuter[1] = 1.0;\n" 17185 " gl_TessLevelOuter[2] = 1.0;\n" 17186 " gl_TessLevelOuter[3] = 1.0;\n" 17187 " gl_TessLevelInner[0] = 1.0;\n" 17188 " gl_TessLevelInner[1] = 1.0;\n" 17189 "}\n" 17190 "\n"; 17191 static const GLchar* tcs_tested = "#version 430 core\n" 17192 "#extension GL_ARB_enhanced_layouts : require\n" 17193 "\n" 17194 "layout(vertices = 1) out;\n" 17195 "\n" 17196 "VAR_DEFINITION" 17197 "\n" 17198 "in vec4 vs_tcs[];\n" 17199 "out vec4 tcs_tes[];\n" 17200 "\n" 17201 "void main()\n" 17202 "{\n" 17203 " vec4 result = vs_tcs[gl_InvocationID];\n" 17204 "\n" 17205 "VARIABLE_USE" 17206 "\n" 17207 " tcs_tes[gl_InvocationID] = result;\n" 17208 "\n" 17209 " gl_TessLevelOuter[0] = 1.0;\n" 17210 " gl_TessLevelOuter[1] = 1.0;\n" 17211 " gl_TessLevelOuter[2] = 1.0;\n" 17212 " gl_TessLevelOuter[3] = 1.0;\n" 17213 " gl_TessLevelInner[0] = 1.0;\n" 17214 " gl_TessLevelInner[1] = 1.0;\n" 17215 "}\n" 17216 "\n"; 17217 static const GLchar* tes = "#version 430 core\n" 17218 "#extension GL_ARB_enhanced_layouts : require\n" 17219 "\n" 17220 "layout(isolines, point_mode) in;\n" 17221 "\n" 17222 "in vec4 tcs_tes[];\n" 17223 "out vec4 tes_gs;\n" 17224 "\n" 17225 "void main()\n" 17226 "{\n" 17227 " tes_gs = tcs_tes[0];\n" 17228 "}\n" 17229 "\n"; 17230 static const GLchar* tes_tested = "#version 430 core\n" 17231 "#extension GL_ARB_enhanced_layouts : require\n" 17232 "\n" 17233 "layout(isolines, point_mode) in;\n" 17234 "\n" 17235 "VAR_DEFINITION" 17236 "\n" 17237 "in vec4 tcs_tes[];\n" 17238 "out vec4 tes_gs;\n" 17239 "\n" 17240 "void main()\n" 17241 "{\n" 17242 " vec4 result = tcs_tes[0];\n" 17243 "\n" 17244 "VARIABLE_USE" 17245 "\n" 17246 " tes_gs += result;\n" 17247 "}\n" 17248 "\n"; 17249 static const GLchar* vs = "#version 430 core\n" 17250 "#extension GL_ARB_enhanced_layouts : require\n" 17251 "\n" 17252 "in vec4 in_vs;\n" 17253 "out vec4 vs_tcs;\n" 17254 "\n" 17255 "void main()\n" 17256 "{\n" 17257 " vs_tcs = in_vs;\n" 17258 "}\n" 17259 "\n"; 17260 static const GLchar* vs_tested = "#version 430 core\n" 17261 "#extension GL_ARB_enhanced_layouts : require\n" 17262 "\n" 17263 "VAR_DEFINITION" 17264 "\n" 17265 "in vec4 in_vs;\n" 17266 "out vec4 vs_tcs;\n" 17267 "\n" 17268 "void main()\n" 17269 "{\n" 17270 " vec4 result = in_vs;\n" 17271 "\n" 17272 "VARIABLE_USE" 17273 "\n" 17274 " vs_tcs += result;\n" 17275 "}\n" 17276 "\n"; 17277 17278 std::string source; 17279 testCase& test_case = m_test_cases[test_case_index]; 17280 17281 if (test_case.m_stage == stage) 17282 { 17283 const GLchar* array = ""; 17284 GLchar buffer_gohan[16]; 17285 GLchar buffer_goten[16]; 17286 const GLchar* index = ""; 17287 size_t position = 0; 17288 size_t temp; 17289 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 17290 17291 sprintf(buffer_gohan, "%d", test_case.m_component_gohan); 17292 sprintf(buffer_goten, "%d", test_case.m_component_goten); 17293 17294 switch (stage) 17295 { 17296 case Utils::Shader::FRAGMENT: 17297 source = fs_tested; 17298 break; 17299 case Utils::Shader::GEOMETRY: 17300 source = gs_tested; 17301 array = "[]"; 17302 index = "[0]"; 17303 break; 17304 case Utils::Shader::TESS_CTRL: 17305 source = tcs_tested; 17306 array = "[]"; 17307 index = "[gl_InvocationID]"; 17308 break; 17309 case Utils::Shader::TESS_EVAL: 17310 source = tes_tested; 17311 array = "[]"; 17312 index = "[0]"; 17313 break; 17314 case Utils::Shader::VERTEX: 17315 source = vs_tested; 17316 break; 17317 default: 17318 TCU_FAIL("Invalid enum"); 17319 } 17320 17321 temp = position; 17322 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 17323 position = temp; 17324 Utils::replaceToken("COMPONENT", position, buffer_gohan, source); 17325 Utils::replaceToken("ARRAY", position, array, source); 17326 Utils::replaceToken("COMPONENT", position, buffer_goten, source); 17327 Utils::replaceToken("ARRAY", position, array, source); 17328 Utils::replaceToken("VARIABLE_USE", position, l_test, source); 17329 17330 Utils::replaceAllTokens("TYPE", type_name, source); 17331 Utils::replaceAllTokens("INDEX", index, source); 17332 } 17333 else 17334 { 17335 switch (stage) 17336 { 17337 case Utils::Shader::FRAGMENT: 17338 source = fs; 17339 break; 17340 case Utils::Shader::GEOMETRY: 17341 source = gs; 17342 break; 17343 case Utils::Shader::TESS_CTRL: 17344 source = tcs; 17345 break; 17346 case Utils::Shader::TESS_EVAL: 17347 source = tes; 17348 break; 17349 case Utils::Shader::VERTEX: 17350 source = vs; 17351 break; 17352 default: 17353 TCU_FAIL("Invalid enum"); 17354 } 17355 } 17356 17357 return source; 17358 } 17359 17360 /** Get description of test case 17361 * 17362 * @param test_case_index Index of test case 17363 * 17364 * @return Test case description 17365 **/ 17366 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index) 17367 { 17368 std::stringstream stream; 17369 testCase& test_case = m_test_cases[test_case_index]; 17370 17371 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 17372 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan 17373 << " & " << test_case.m_component_goten; 17374 17375 return stream.str(); 17376 } 17377 17378 /** Get number of test cases 17379 * 17380 * @return Number of test cases 17381 **/ 17382 GLuint OutputComponentAliasingTest::getTestCaseNumber() 17383 { 17384 return static_cast<GLuint>(m_test_cases.size()); 17385 } 17386 17387 /** Selects if "compute" stage is relevant for test 17388 * 17389 * @param ignored 17390 * 17391 * @return false 17392 **/ 17393 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */) 17394 { 17395 return false; 17396 } 17397 17398 /** Prepare all test cases 17399 * 17400 **/ 17401 void OutputComponentAliasingTest::testInit() 17402 { 17403 static const GLuint n_components_per_location = 4; 17404 const GLuint n_types = getTypesNumber(); 17405 17406 for (GLuint i = 0; i < n_types; ++i) 17407 { 17408 const Utils::Type& type = getType(i); 17409 const GLuint n_req_components = type.m_n_rows; 17410 const GLuint valid_component = n_components_per_location - n_req_components; 17411 17412 /* Skip matrices */ 17413 if (1 != type.m_n_columns) 17414 { 17415 continue; 17416 } 17417 17418 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 17419 { 17420 if (Utils::Shader::COMPUTE == stage) 17421 { 17422 continue; 17423 } 17424 17425 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type)) 17426 { 17427 continue; 17428 } 17429 17430 for (GLuint gohan = 0; gohan <= valid_component; ++gohan) 17431 { 17432 const GLint first_aliasing = gohan - n_req_components + 1; 17433 const GLint last_aliasing = gohan + n_req_components - 1; 17434 17435 const GLuint goten_start = std::max(0, first_aliasing); 17436 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing); 17437 17438 for (GLuint goten = goten_start; goten <= goten_stop; ++goten) 17439 { 17440 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type }; 17441 17442 m_test_cases.push_back(test_case); 17443 } 17444 } 17445 } 17446 } 17447 } 17448 17449 /** Constructor 17450 * 17451 * @param context Test framework context 17452 **/ 17453 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context& context) 17454 : NegativeTestBase(context, "varying_location_aliasing_with_mixed_types", 17455 "Test verifies that compiler reports error when float/int types are mixed at one location") 17456 { 17457 } 17458 17459 /** Source for given test case and stage 17460 * 17461 * @param test_case_index Index of test case 17462 * @param stage Shader stage 17463 * 17464 * @return Shader source 17465 **/ 17466 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint test_case_index, 17467 Utils::Shader::STAGES stage) 17468 { 17469 static const GLchar* var_definition = 17470 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n" 17471 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n"; 17472 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n" 17473 " (TYPE(1) == gotenINDEX) )\n" 17474 " {\n" 17475 " result += vec4(1, 0.5, 0.25, 0.125);\n" 17476 " }\n"; 17477 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n" 17478 " gotenINDEX = TYPE(1);\n" 17479 " if (vec4(0) == result)\n" 17480 " {\n" 17481 " gohanINDEX = TYPE(1);\n" 17482 " gotenINDEX = TYPE(0);\n" 17483 " }\n"; 17484 static const GLchar* fs = "#version 430 core\n" 17485 "#extension GL_ARB_enhanced_layouts : require\n" 17486 "\n" 17487 "in vec4 gs_fs;\n" 17488 "out vec4 fs_out;\n" 17489 "\n" 17490 "void main()\n" 17491 "{\n" 17492 " fs_out = gs_fs;\n" 17493 "}\n" 17494 "\n"; 17495 static const GLchar* fs_tested = "#version 430 core\n" 17496 "#extension GL_ARB_enhanced_layouts : require\n" 17497 "\n" 17498 "VAR_DEFINITION" 17499 "\n" 17500 "in vec4 gs_fs;\n" 17501 "out vec4 fs_out;\n" 17502 "\n" 17503 "void main()\n" 17504 "{\n" 17505 " vec4 result = gs_fs;\n" 17506 "\n" 17507 "VARIABLE_USE" 17508 "\n" 17509 " fs_out += result;\n" 17510 "}\n" 17511 "\n"; 17512 static const GLchar* gs = "#version 430 core\n" 17513 "#extension GL_ARB_enhanced_layouts : require\n" 17514 "\n" 17515 "layout(points) in;\n" 17516 "layout(triangle_strip, max_vertices = 4) out;\n" 17517 "\n" 17518 "in vec4 tes_gs[];\n" 17519 "out vec4 gs_fs;\n" 17520 "\n" 17521 "void main()\n" 17522 "{\n" 17523 " gs_fs = tes_gs[0];\n" 17524 " gl_Position = vec4(-1, -1, 0, 1);\n" 17525 " EmitVertex();\n" 17526 " gs_fs = tes_gs[0];\n" 17527 " gl_Position = vec4(-1, 1, 0, 1);\n" 17528 " EmitVertex();\n" 17529 " gs_fs = tes_gs[0];\n" 17530 " gl_Position = vec4(1, -1, 0, 1);\n" 17531 " EmitVertex();\n" 17532 " gs_fs = tes_gs[0];\n" 17533 " gl_Position = vec4(1, 1, 0, 1);\n" 17534 " EmitVertex();\n" 17535 "}\n" 17536 "\n"; 17537 static const GLchar* gs_tested = "#version 430 core\n" 17538 "#extension GL_ARB_enhanced_layouts : require\n" 17539 "\n" 17540 "layout(points) in;\n" 17541 "layout(triangle_strip, max_vertices = 4) out;\n" 17542 "\n" 17543 "VAR_DEFINITION" 17544 "\n" 17545 "in vec4 tes_gs[];\n" 17546 "out vec4 gs_fs;\n" 17547 "\n" 17548 "void main()\n" 17549 "{\n" 17550 " vec4 result = tes_gs[0];\n" 17551 "\n" 17552 "VARIABLE_USE" 17553 "\n" 17554 " gs_fs = result;\n" 17555 " gl_Position = vec4(-1, -1, 0, 1);\n" 17556 " EmitVertex();\n" 17557 " gs_fs = result;\n" 17558 " gl_Position = vec4(-1, 1, 0, 1);\n" 17559 " EmitVertex();\n" 17560 " gs_fs = result;\n" 17561 " gl_Position = vec4(1, -1, 0, 1);\n" 17562 " EmitVertex();\n" 17563 " gs_fs = result;\n" 17564 " gl_Position = vec4(1, 1, 0, 1);\n" 17565 " EmitVertex();\n" 17566 "}\n" 17567 "\n"; 17568 static const GLchar* tcs = "#version 430 core\n" 17569 "#extension GL_ARB_enhanced_layouts : require\n" 17570 "\n" 17571 "layout(vertices = 1) out;\n" 17572 "\n" 17573 "in vec4 vs_tcs[];\n" 17574 "out vec4 tcs_tes[];\n" 17575 "\n" 17576 "void main()\n" 17577 "{\n" 17578 "\n" 17579 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 17580 "\n" 17581 " gl_TessLevelOuter[0] = 1.0;\n" 17582 " gl_TessLevelOuter[1] = 1.0;\n" 17583 " gl_TessLevelOuter[2] = 1.0;\n" 17584 " gl_TessLevelOuter[3] = 1.0;\n" 17585 " gl_TessLevelInner[0] = 1.0;\n" 17586 " gl_TessLevelInner[1] = 1.0;\n" 17587 "}\n" 17588 "\n"; 17589 static const GLchar* tcs_tested = "#version 430 core\n" 17590 "#extension GL_ARB_enhanced_layouts : require\n" 17591 "\n" 17592 "layout(vertices = 1) out;\n" 17593 "\n" 17594 "VAR_DEFINITION" 17595 "\n" 17596 "in vec4 vs_tcs[];\n" 17597 "out vec4 tcs_tes[];\n" 17598 "\n" 17599 "void main()\n" 17600 "{\n" 17601 " vec4 result = vs_tcs[gl_InvocationID];\n" 17602 "\n" 17603 "VARIABLE_USE" 17604 "\n" 17605 " tcs_tes[gl_InvocationID] = result;\n" 17606 "\n" 17607 " gl_TessLevelOuter[0] = 1.0;\n" 17608 " gl_TessLevelOuter[1] = 1.0;\n" 17609 " gl_TessLevelOuter[2] = 1.0;\n" 17610 " gl_TessLevelOuter[3] = 1.0;\n" 17611 " gl_TessLevelInner[0] = 1.0;\n" 17612 " gl_TessLevelInner[1] = 1.0;\n" 17613 "}\n" 17614 "\n"; 17615 static const GLchar* tes = "#version 430 core\n" 17616 "#extension GL_ARB_enhanced_layouts : require\n" 17617 "\n" 17618 "layout(isolines, point_mode) in;\n" 17619 "\n" 17620 "in vec4 tcs_tes[];\n" 17621 "out vec4 tes_gs;\n" 17622 "\n" 17623 "void main()\n" 17624 "{\n" 17625 " tes_gs = tcs_tes[0];\n" 17626 "}\n" 17627 "\n"; 17628 static const GLchar* tes_tested = "#version 430 core\n" 17629 "#extension GL_ARB_enhanced_layouts : require\n" 17630 "\n" 17631 "layout(isolines, point_mode) in;\n" 17632 "\n" 17633 "VAR_DEFINITION" 17634 "\n" 17635 "in vec4 tcs_tes[];\n" 17636 "out vec4 tes_gs;\n" 17637 "\n" 17638 "void main()\n" 17639 "{\n" 17640 " vec4 result = tcs_tes[0];\n" 17641 "\n" 17642 "VARIABLE_USE" 17643 "\n" 17644 " tes_gs += result;\n" 17645 "}\n" 17646 "\n"; 17647 static const GLchar* vs = "#version 430 core\n" 17648 "#extension GL_ARB_enhanced_layouts : require\n" 17649 "\n" 17650 "in vec4 in_vs;\n" 17651 "out vec4 vs_tcs;\n" 17652 "\n" 17653 "void main()\n" 17654 "{\n" 17655 " vs_tcs = in_vs;\n" 17656 "}\n" 17657 "\n"; 17658 static const GLchar* vs_tested = "#version 430 core\n" 17659 "#extension GL_ARB_enhanced_layouts : require\n" 17660 "\n" 17661 "VAR_DEFINITION" 17662 "\n" 17663 "in vec4 in_vs;\n" 17664 "out vec4 vs_tcs;\n" 17665 "\n" 17666 "void main()\n" 17667 "{\n" 17668 " vec4 result = in_vs;\n" 17669 "\n" 17670 "VARIABLE_USE" 17671 "\n" 17672 " vs_tcs += result;\n" 17673 "}\n" 17674 "\n"; 17675 17676 std::string source; 17677 testCase& test_case = m_test_cases[test_case_index]; 17678 17679 if (test_case.m_stage == stage) 17680 { 17681 const GLchar* array = ""; 17682 GLchar buffer_gohan[16]; 17683 GLchar buffer_goten[16]; 17684 const GLchar* direction = "in "; 17685 const GLchar* flat_gohan = ""; 17686 const GLchar* flat_goten = ""; 17687 const GLchar* index = ""; 17688 size_t position = 0; 17689 size_t temp; 17690 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName(); 17691 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName(); 17692 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT; 17693 const GLchar* var_use = input_use; 17694 17695 if (false == test_case.m_is_input) 17696 { 17697 direction = "out"; 17698 storage = Utils::Variable::VARYING_OUTPUT; 17699 var_use = output_use; 17700 } 17701 17702 if (true == isFlatRequired(stage, test_case.m_type_gohan, storage)) 17703 { 17704 flat_gohan = "flat"; 17705 } 17706 17707 if (true == isFlatRequired(stage, test_case.m_type_goten, storage)) 17708 { 17709 flat_goten = "flat"; 17710 } 17711 17712 sprintf(buffer_gohan, "%d", test_case.m_component_gohan); 17713 sprintf(buffer_goten, "%d", test_case.m_component_goten); 17714 17715 switch (stage) 17716 { 17717 case Utils::Shader::FRAGMENT: 17718 source = fs_tested; 17719 break; 17720 case Utils::Shader::GEOMETRY: 17721 source = gs_tested; 17722 array = "[]"; 17723 index = "[0]"; 17724 break; 17725 case Utils::Shader::TESS_CTRL: 17726 source = tcs_tested; 17727 array = "[]"; 17728 index = "[gl_InvocationID]"; 17729 break; 17730 case Utils::Shader::TESS_EVAL: 17731 source = tes_tested; 17732 array = "[]"; 17733 index = "[0]"; 17734 break; 17735 case Utils::Shader::VERTEX: 17736 source = vs_tested; 17737 break; 17738 default: 17739 TCU_FAIL("Invalid enum"); 17740 } 17741 17742 temp = position; 17743 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 17744 position = temp; 17745 Utils::replaceToken("COMPONENT", position, buffer_gohan, source); 17746 Utils::replaceToken("FLAT", position, flat_gohan, source); 17747 Utils::replaceToken("DIRECTION", position, direction, source); 17748 Utils::replaceToken("TYPE", position, type_gohan_name, source); 17749 Utils::replaceToken("ARRAY", position, array, source); 17750 Utils::replaceToken("COMPONENT", position, buffer_goten, source); 17751 Utils::replaceToken("FLAT", position, flat_goten, source); 17752 Utils::replaceToken("DIRECTION", position, direction, source); 17753 Utils::replaceToken("TYPE", position, type_goten_name, source); 17754 Utils::replaceToken("ARRAY", position, array, source); 17755 17756 temp = position; 17757 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 17758 position = temp; 17759 if (true == test_case.m_is_input) 17760 { 17761 Utils::replaceToken("TYPE", position, type_gohan_name, source); 17762 Utils::replaceToken("TYPE", position, type_goten_name, source); 17763 } 17764 else 17765 { 17766 Utils::replaceToken("TYPE", position, type_gohan_name, source); 17767 Utils::replaceToken("TYPE", position, type_goten_name, source); 17768 Utils::replaceToken("TYPE", position, type_gohan_name, source); 17769 Utils::replaceToken("TYPE", position, type_goten_name, source); 17770 } 17771 17772 Utils::replaceAllTokens("INDEX", index, source); 17773 } 17774 else 17775 { 17776 switch (stage) 17777 { 17778 case Utils::Shader::FRAGMENT: 17779 source = fs; 17780 break; 17781 case Utils::Shader::GEOMETRY: 17782 source = gs; 17783 break; 17784 case Utils::Shader::TESS_CTRL: 17785 source = tcs; 17786 break; 17787 case Utils::Shader::TESS_EVAL: 17788 source = tes; 17789 break; 17790 case Utils::Shader::VERTEX: 17791 source = vs; 17792 break; 17793 default: 17794 TCU_FAIL("Invalid enum"); 17795 } 17796 } 17797 17798 return source; 17799 } 17800 17801 /** Get description of test case 17802 * 17803 * @param test_case_index Index of test case 17804 * 17805 * @return Test case description 17806 **/ 17807 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index) 17808 { 17809 std::stringstream stream; 17810 testCase& test_case = m_test_cases[test_case_index]; 17811 17812 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", " 17813 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", " 17814 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: "; 17815 17816 if (true == test_case.m_is_input) 17817 { 17818 stream << "input"; 17819 } 17820 else 17821 { 17822 stream << "output"; 17823 } 17824 17825 return stream.str(); 17826 } 17827 17828 /** Get number of test cases 17829 * 17830 * @return Number of test cases 17831 **/ 17832 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber() 17833 { 17834 return static_cast<GLuint>(m_test_cases.size()); 17835 } 17836 17837 /** Selects if "compute" stage is relevant for test 17838 * 17839 * @param ignored 17840 * 17841 * @return false 17842 **/ 17843 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */) 17844 { 17845 return false; 17846 } 17847 17848 /** Prepare all test cases 17849 * 17850 **/ 17851 void VaryingLocationAliasingWithMixedTypesTest::testInit() 17852 { 17853 static const GLuint n_components_per_location = 4; 17854 const GLuint n_types = getTypesNumber(); 17855 17856 for (GLuint i = 0; i < n_types; ++i) 17857 { 17858 const Utils::Type& type_gohan = getType(i); 17859 const bool is_float_type_gohan = isFloatType(type_gohan); 17860 17861 /* Skip matrices */ 17862 if (1 != type_gohan.m_n_columns) 17863 { 17864 continue; 17865 } 17866 17867 for (GLuint j = 0; j < n_types; ++j) 17868 { 17869 const Utils::Type& type_goten = getType(j); 17870 const bool is_float_type_goten = isFloatType(type_goten); 17871 17872 /* Skip matrices */ 17873 if (1 != type_goten.m_n_columns) 17874 { 17875 continue; 17876 } 17877 17878 /* Skip valid combinations */ 17879 if (is_float_type_gohan == is_float_type_goten) 17880 { 17881 continue; 17882 } 17883 17884 const GLuint n_req_components_gohan = type_gohan.m_n_rows; 17885 const GLuint n_req_components_goten = type_goten.m_n_rows; 17886 const GLuint valid_component_gohan = n_components_per_location - n_req_components_gohan; 17887 const GLuint valid_component_goten = n_components_per_location - n_req_components_goten; 17888 17889 /* Skip pairs that cannot fit into one location */ 17890 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten)) 17891 { 17892 continue; 17893 } 17894 17895 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 17896 { 17897 /* Skip compute shader */ 17898 if (Utils::Shader::COMPUTE == stage) 17899 { 17900 continue; 17901 } 17902 17903 for (GLuint gohan = 0; gohan <= valid_component_gohan; ++gohan) 17904 { 17905 const GLint first_aliasing = gohan - n_req_components_goten + 1; 17906 const GLint last_aliasing = gohan + n_req_components_gohan - 1; 17907 17908 const GLuint goten_lower_limit = std::max(0, first_aliasing); 17909 const GLuint goten_upper_limit = last_aliasing + 1; 17910 17911 /* Compoennets before gohan */ 17912 for (GLuint goten = 0; goten < goten_lower_limit; ++goten) 17913 { 17914 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage, 17915 type_gohan, type_goten }; 17916 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage, 17917 type_gohan, type_goten }; 17918 17919 if (Utils::Shader::VERTEX != stage) 17920 m_test_cases.push_back(test_case_in); 17921 17922 /* Skip double outputs in fragment shader */ 17923 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) && 17924 (Utils::Type::Double != type_goten.m_basic_type))) 17925 { 17926 m_test_cases.push_back(test_case_out); 17927 } 17928 } 17929 17930 /* Components after gohan */ 17931 for (GLuint goten = goten_upper_limit; goten <= valid_component_goten; ++goten) 17932 { 17933 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage, 17934 type_gohan, type_goten }; 17935 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage, 17936 type_gohan, type_goten }; 17937 17938 if (Utils::Shader::VERTEX != stage) 17939 m_test_cases.push_back(test_case_in); 17940 17941 /* Skip double outputs in fragment shader */ 17942 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) && 17943 (Utils::Type::Double != type_goten.m_basic_type))) 17944 { 17945 m_test_cases.push_back(test_case_out); 17946 } 17947 } 17948 } 17949 } 17950 } 17951 } 17952 } 17953 17954 /** Check if given type is float 17955 * 17956 * @param type Type in question 17957 * 17958 * @return true if tpye is float, false otherwise 17959 **/ 17960 bool VaryingLocationAliasingWithMixedTypesTest::isFloatType(const Utils::Type& type) 17961 { 17962 bool is_float = false; 17963 17964 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type)) 17965 { 17966 is_float = true; 17967 } 17968 17969 return is_float; 17970 } 17971 17972 /** Constructor 17973 * 17974 * @param context Test framework context 17975 **/ 17976 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest( 17977 deqp::Context& context) 17978 : NegativeTestBase( 17979 context, "varying_location_aliasing_with_mixed_interpolation", 17980 "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location") 17981 { 17982 } 17983 17984 /** Source for given test case and stage 17985 * 17986 * @param test_case_index Index of test case 17987 * @param stage Shader stage 17988 * 17989 * @return Shader source 17990 **/ 17991 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint test_case_index, 17992 Utils::Shader::STAGES stage) 17993 { 17994 static const GLchar* var_definition = 17995 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n" 17996 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n"; 17997 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n" 17998 " (TYPE(1) == gotenINDEX) )\n" 17999 " {\n" 18000 " result += vec4(1, 0.5, 0.25, 0.125);\n" 18001 " }\n"; 18002 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n" 18003 " gotenINDEX = TYPE(1);\n" 18004 " if (vec4(0) == result)\n" 18005 " {\n" 18006 " gohanINDEX = TYPE(1);\n" 18007 " gotenINDEX = TYPE(0);\n" 18008 " }\n"; 18009 static const GLchar* fs = "#version 430 core\n" 18010 "#extension GL_ARB_enhanced_layouts : require\n" 18011 "\n" 18012 "in vec4 gs_fs;\n" 18013 "out vec4 fs_out;\n" 18014 "\n" 18015 "void main()\n" 18016 "{\n" 18017 " fs_out = gs_fs;\n" 18018 "}\n" 18019 "\n"; 18020 static const GLchar* fs_tested = "#version 430 core\n" 18021 "#extension GL_ARB_enhanced_layouts : require\n" 18022 "\n" 18023 "VAR_DEFINITION" 18024 "\n" 18025 "in vec4 gs_fs;\n" 18026 "out vec4 fs_out;\n" 18027 "\n" 18028 "void main()\n" 18029 "{\n" 18030 " vec4 result = gs_fs;\n" 18031 "\n" 18032 "VARIABLE_USE" 18033 "\n" 18034 " fs_out = result;\n" 18035 "}\n" 18036 "\n"; 18037 static const GLchar* gs = "#version 430 core\n" 18038 "#extension GL_ARB_enhanced_layouts : require\n" 18039 "\n" 18040 "layout(points) in;\n" 18041 "layout(triangle_strip, max_vertices = 4) out;\n" 18042 "\n" 18043 "in vec4 tes_gs[];\n" 18044 "out vec4 gs_fs;\n" 18045 "\n" 18046 "void main()\n" 18047 "{\n" 18048 " gs_fs = tes_gs[0];\n" 18049 " gl_Position = vec4(-1, -1, 0, 1);\n" 18050 " EmitVertex();\n" 18051 " gs_fs = tes_gs[0];\n" 18052 " gl_Position = vec4(-1, 1, 0, 1);\n" 18053 " EmitVertex();\n" 18054 " gs_fs = tes_gs[0];\n" 18055 " gl_Position = vec4(1, -1, 0, 1);\n" 18056 " EmitVertex();\n" 18057 " gs_fs = tes_gs[0];\n" 18058 " gl_Position = vec4(1, 1, 0, 1);\n" 18059 " EmitVertex();\n" 18060 "}\n" 18061 "\n"; 18062 static const GLchar* gs_tested = "#version 430 core\n" 18063 "#extension GL_ARB_enhanced_layouts : require\n" 18064 "\n" 18065 "layout(points) in;\n" 18066 "layout(triangle_strip, max_vertices = 4) out;\n" 18067 "\n" 18068 "VAR_DEFINITION" 18069 "\n" 18070 "in vec4 tes_gs[];\n" 18071 "out vec4 gs_fs;\n" 18072 "\n" 18073 "void main()\n" 18074 "{\n" 18075 " vec4 result = tes_gs[0];\n" 18076 "\n" 18077 "VARIABLE_USE" 18078 "\n" 18079 " gs_fs = result;\n" 18080 " gl_Position = vec4(-1, -1, 0, 1);\n" 18081 " EmitVertex();\n" 18082 " gs_fs = result;\n" 18083 " gl_Position = vec4(-1, 1, 0, 1);\n" 18084 " EmitVertex();\n" 18085 " gs_fs = result;\n" 18086 " gl_Position = vec4(1, -1, 0, 1);\n" 18087 " EmitVertex();\n" 18088 " gs_fs = result;\n" 18089 " gl_Position = vec4(1, 1, 0, 1);\n" 18090 " EmitVertex();\n" 18091 "}\n" 18092 "\n"; 18093 static const GLchar* tcs = "#version 430 core\n" 18094 "#extension GL_ARB_enhanced_layouts : require\n" 18095 "\n" 18096 "layout(vertices = 1) out;\n" 18097 "\n" 18098 "in vec4 vs_tcs[];\n" 18099 "out vec4 tcs_tes[];\n" 18100 "\n" 18101 "void main()\n" 18102 "{\n" 18103 "\n" 18104 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 18105 "\n" 18106 " gl_TessLevelOuter[0] = 1.0;\n" 18107 " gl_TessLevelOuter[1] = 1.0;\n" 18108 " gl_TessLevelOuter[2] = 1.0;\n" 18109 " gl_TessLevelOuter[3] = 1.0;\n" 18110 " gl_TessLevelInner[0] = 1.0;\n" 18111 " gl_TessLevelInner[1] = 1.0;\n" 18112 "}\n" 18113 "\n"; 18114 static const GLchar* tcs_tested = "#version 430 core\n" 18115 "#extension GL_ARB_enhanced_layouts : require\n" 18116 "\n" 18117 "layout(vertices = 1) out;\n" 18118 "\n" 18119 "VAR_DEFINITION" 18120 "\n" 18121 "in vec4 vs_tcs[];\n" 18122 "out vec4 tcs_tes[];\n" 18123 "\n" 18124 "void main()\n" 18125 "{\n" 18126 " vec4 result = vs_tcs[gl_InvocationID];\n" 18127 "\n" 18128 "VARIABLE_USE" 18129 "\n" 18130 " tcs_tes[gl_InvocationID] = result;\n" 18131 "\n" 18132 " gl_TessLevelOuter[0] = 1.0;\n" 18133 " gl_TessLevelOuter[1] = 1.0;\n" 18134 " gl_TessLevelOuter[2] = 1.0;\n" 18135 " gl_TessLevelOuter[3] = 1.0;\n" 18136 " gl_TessLevelInner[0] = 1.0;\n" 18137 " gl_TessLevelInner[1] = 1.0;\n" 18138 "}\n" 18139 "\n"; 18140 static const GLchar* tes = "#version 430 core\n" 18141 "#extension GL_ARB_enhanced_layouts : require\n" 18142 "\n" 18143 "layout(isolines, point_mode) in;\n" 18144 "\n" 18145 "in vec4 tcs_tes[];\n" 18146 "out vec4 tes_gs;\n" 18147 "\n" 18148 "void main()\n" 18149 "{\n" 18150 " tes_gs = tcs_tes[0];\n" 18151 "}\n" 18152 "\n"; 18153 static const GLchar* tes_tested = "#version 430 core\n" 18154 "#extension GL_ARB_enhanced_layouts : require\n" 18155 "\n" 18156 "layout(isolines, point_mode) in;\n" 18157 "\n" 18158 "VAR_DEFINITION" 18159 "\n" 18160 "in vec4 tcs_tes[];\n" 18161 "out vec4 tes_gs;\n" 18162 "\n" 18163 "void main()\n" 18164 "{\n" 18165 " vec4 result = tcs_tes[0];\n" 18166 "\n" 18167 "VARIABLE_USE" 18168 "\n" 18169 " tes_gs += result;\n" 18170 "}\n" 18171 "\n"; 18172 static const GLchar* vs = "#version 430 core\n" 18173 "#extension GL_ARB_enhanced_layouts : require\n" 18174 "\n" 18175 "in vec4 in_vs;\n" 18176 "out vec4 vs_tcs;\n" 18177 "\n" 18178 "void main()\n" 18179 "{\n" 18180 " vs_tcs = in_vs;\n" 18181 "}\n" 18182 "\n"; 18183 static const GLchar* vs_tested = "#version 430 core\n" 18184 "#extension GL_ARB_enhanced_layouts : require\n" 18185 "\n" 18186 "VAR_DEFINITION" 18187 "\n" 18188 "in vec4 in_vs;\n" 18189 "out vec4 vs_tcs;\n" 18190 "\n" 18191 "void main()\n" 18192 "{\n" 18193 " vec4 result = in_vs;\n" 18194 "\n" 18195 "VARIABLE_USE" 18196 "\n" 18197 " vs_tcs += result;\n" 18198 "}\n" 18199 "\n"; 18200 18201 std::string source; 18202 testCase& test_case = m_test_cases[test_case_index]; 18203 18204 if (test_case.m_stage == stage) 18205 { 18206 const GLchar* array = ""; 18207 GLchar buffer_gohan[16]; 18208 GLchar buffer_goten[16]; 18209 const GLchar* direction = "in "; 18210 const GLchar* index = ""; 18211 const GLchar* int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan); 18212 const GLchar* int_goten = getInterpolationQualifier(test_case.m_interpolation_goten); 18213 size_t position = 0; 18214 size_t temp; 18215 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName(); 18216 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName(); 18217 const GLchar* var_use = input_use; 18218 18219 if (false == test_case.m_is_input) 18220 { 18221 direction = "out"; 18222 18223 var_use = output_use; 18224 } 18225 18226 sprintf(buffer_gohan, "%d", test_case.m_component_gohan); 18227 sprintf(buffer_goten, "%d", test_case.m_component_goten); 18228 18229 switch (stage) 18230 { 18231 case Utils::Shader::FRAGMENT: 18232 source = fs_tested; 18233 break; 18234 case Utils::Shader::GEOMETRY: 18235 source = gs_tested; 18236 array = "[]"; 18237 index = "[0]"; 18238 break; 18239 case Utils::Shader::TESS_CTRL: 18240 source = tcs_tested; 18241 array = "[]"; 18242 index = "[gl_InvocationID]"; 18243 break; 18244 case Utils::Shader::TESS_EVAL: 18245 source = tes_tested; 18246 array = "[]"; 18247 index = "[0]"; 18248 break; 18249 case Utils::Shader::VERTEX: 18250 source = vs_tested; 18251 break; 18252 default: 18253 TCU_FAIL("Invalid enum"); 18254 } 18255 18256 temp = position; 18257 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 18258 position = temp; 18259 Utils::replaceToken("COMPONENT", position, buffer_gohan, source); 18260 Utils::replaceToken("INTERPOLATION", position, int_gohan, source); 18261 Utils::replaceToken("DIRECTION", position, direction, source); 18262 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18263 Utils::replaceToken("ARRAY", position, array, source); 18264 Utils::replaceToken("COMPONENT", position, buffer_goten, source); 18265 Utils::replaceToken("INTERPOLATION", position, int_goten, source); 18266 Utils::replaceToken("DIRECTION", position, direction, source); 18267 Utils::replaceToken("TYPE", position, type_goten_name, source); 18268 Utils::replaceToken("ARRAY", position, array, source); 18269 18270 temp = position; 18271 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 18272 position = temp; 18273 if (true == test_case.m_is_input) 18274 { 18275 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18276 Utils::replaceToken("TYPE", position, type_goten_name, source); 18277 } 18278 else 18279 { 18280 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18281 Utils::replaceToken("TYPE", position, type_goten_name, source); 18282 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18283 Utils::replaceToken("TYPE", position, type_goten_name, source); 18284 } 18285 18286 Utils::replaceAllTokens("INDEX", index, source); 18287 } 18288 else 18289 { 18290 switch (stage) 18291 { 18292 case Utils::Shader::FRAGMENT: 18293 source = fs; 18294 break; 18295 case Utils::Shader::GEOMETRY: 18296 source = gs; 18297 break; 18298 case Utils::Shader::TESS_CTRL: 18299 source = tcs; 18300 break; 18301 case Utils::Shader::TESS_EVAL: 18302 source = tes; 18303 break; 18304 case Utils::Shader::VERTEX: 18305 source = vs; 18306 break; 18307 default: 18308 TCU_FAIL("Invalid enum"); 18309 } 18310 } 18311 18312 return source; 18313 } 18314 18315 /** Get description of test case 18316 * 18317 * @param test_case_index Index of test case 18318 * 18319 * @return Test case description 18320 **/ 18321 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index) 18322 { 18323 std::stringstream stream; 18324 testCase& test_case = m_test_cases[test_case_index]; 18325 18326 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", " 18327 << getInterpolationQualifier(test_case.m_interpolation_gohan) << " " 18328 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", " 18329 << getInterpolationQualifier(test_case.m_interpolation_goten) << " " 18330 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: "; 18331 18332 if (true == test_case.m_is_input) 18333 { 18334 stream << "input"; 18335 } 18336 else 18337 { 18338 stream << "output"; 18339 } 18340 18341 return stream.str(); 18342 } 18343 18344 /** Get number of test cases 18345 * 18346 * @return Number of test cases 18347 **/ 18348 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber() 18349 { 18350 return static_cast<GLuint>(m_test_cases.size()); 18351 } 18352 18353 /** Selects if "compute" stage is relevant for test 18354 * 18355 * @param ignored 18356 * 18357 * @return false 18358 **/ 18359 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */) 18360 { 18361 return false; 18362 } 18363 18364 /** Prepare all test cases 18365 * 18366 **/ 18367 void VaryingLocationAliasingWithMixedInterpolationTest::testInit() 18368 { 18369 static const GLuint n_components_per_location = 4; 18370 const GLuint n_types = getTypesNumber(); 18371 18372 for (GLuint i = 0; i < n_types; ++i) 18373 { 18374 const Utils::Type& type_gohan = getType(i); 18375 const bool is_float_type_gohan = isFloatType(type_gohan); 18376 18377 /* Skip matrices */ 18378 if (1 != type_gohan.m_n_columns) 18379 { 18380 continue; 18381 } 18382 18383 for (GLuint j = 0; j < n_types; ++j) 18384 { 18385 const Utils::Type& type_goten = getType(j); 18386 const bool is_float_type_goten = isFloatType(type_goten); 18387 18388 /* Skip matrices */ 18389 if (1 != type_goten.m_n_columns) 18390 { 18391 continue; 18392 } 18393 18394 /* Skip invalid combinations */ 18395 if (is_float_type_gohan != is_float_type_goten) 18396 { 18397 continue; 18398 } 18399 18400 const GLuint n_req_components_gohan = type_gohan.m_n_rows; 18401 const GLuint n_req_components_goten = type_goten.m_n_rows; 18402 18403 /* Skip pairs that cannot fit into one location */ 18404 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten)) 18405 { 18406 continue; 18407 } 18408 18409 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 18410 { 18411 /* Skip compute shader */ 18412 if (Utils::Shader::COMPUTE == stage) 18413 { 18414 continue; 18415 } 18416 18417 const GLuint gohan = 0; 18418 const GLuint goten = gohan + n_req_components_gohan; 18419 18420 for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan) 18421 { 18422 for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten) 18423 { 18424 const bool is_gohan_double = (Utils::Type::Double == type_gohan.m_basic_type) ? true : false; 18425 const bool is_goten_double = (Utils::Type::Double == type_goten.m_basic_type) ? true : false; 18426 const bool is_gohan_flat = (FLAT == int_gohan) ? true : false; 18427 const bool is_goten_flat = (FLAT == int_goten) ? true : false; 18428 const bool is_gohan_accepted_as_fs_in = 18429 (is_gohan_double && is_gohan_flat) || (!is_gohan_double); 18430 const bool is_goten_accepted_as_fs_in = 18431 (is_goten_double && is_goten_flat) || (!is_goten_double); 18432 const bool is_comb_accepted_as_fs_in = is_gohan_accepted_as_fs_in && is_goten_accepted_as_fs_in; 18433 18434 /* Skip when both are the same */ 18435 if (int_gohan == int_goten) 18436 { 18437 continue; 18438 } 18439 18440 testCase test_case_in = { gohan, 18441 goten, 18442 (INTERPOLATIONS)int_gohan, 18443 (INTERPOLATIONS)int_goten, 18444 true, 18445 (Utils::Shader::STAGES)stage, 18446 type_gohan, 18447 type_goten }; 18448 18449 testCase test_case_out = { gohan, 18450 goten, 18451 (INTERPOLATIONS)int_gohan, 18452 (INTERPOLATIONS)int_goten, 18453 false, 18454 (Utils::Shader::STAGES)stage, 18455 type_gohan, 18456 type_goten }; 18457 18458 /* Skip inputs in: 18459 * vertex shader, 18460 * fragment shader when not flat double is used 18461 */ 18462 if ((Utils::Shader::VERTEX != stage) && 18463 ((Utils::Shader::FRAGMENT != stage) || (true == is_comb_accepted_as_fs_in))) 18464 { 18465 m_test_cases.push_back(test_case_in); 18466 } 18467 18468 /* Skip outputs in fragment shader */ 18469 if (Utils::Shader::FRAGMENT != stage) 18470 { 18471 m_test_cases.push_back(test_case_out); 18472 } 18473 } 18474 } 18475 } 18476 } 18477 } 18478 } 18479 18480 /** Get interpolation qualifier 18481 * 18482 * @param interpolation Enumeration 18483 * 18484 * @return GLSL qualifier 18485 **/ 18486 const GLchar* VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation) 18487 { 18488 const GLchar* result = 0; 18489 18490 switch (interpolation) 18491 { 18492 case SMOOTH: 18493 result = "smooth"; 18494 break; 18495 case FLAT: 18496 result = "flat"; 18497 break; 18498 case NO_PERSPECTIVE: 18499 result = "noperspective"; 18500 break; 18501 default: 18502 TCU_FAIL("Invalid enum"); 18503 } 18504 18505 return result; 18506 } 18507 18508 /** Check if given type is float 18509 * 18510 * @param type Type in question 18511 * 18512 * @return true if tpye is float, false otherwise 18513 **/ 18514 bool VaryingLocationAliasingWithMixedInterpolationTest::isFloatType(const Utils::Type& type) 18515 { 18516 bool is_float = false; 18517 18518 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type)) 18519 { 18520 is_float = true; 18521 } 18522 18523 return is_float; 18524 } 18525 18526 /** Constructor 18527 * 18528 * @param context Test framework context 18529 **/ 18530 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest( 18531 deqp::Context& context) 18532 : NegativeTestBase( 18533 context, "varying_location_aliasing_with_mixed_auxiliary_storage", 18534 "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location") 18535 { 18536 } 18537 18538 /** Source for given test case and stage 18539 * 18540 * @param test_case_index Index of test case 18541 * @param stage Shader stage 18542 * 18543 * @return Shader source 18544 **/ 18545 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint test_case_index, 18546 Utils::Shader::STAGES stage) 18547 { 18548 static const GLchar* var_definition = 18549 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n" 18550 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n"; 18551 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX_GOHAN) &&\n" 18552 " (TYPE(1) == gotenINDEX_GOTEN) )\n" 18553 " {\n" 18554 " result += vec4(1, 0.5, 0.25, 0.125);\n" 18555 " }\n"; 18556 static const GLchar* output_use = " gohanINDEX_GOHAN = TYPE(0);\n" 18557 " gotenINDEX_GOTEN = TYPE(1);\n" 18558 " if (vec4(0) == result)\n" 18559 " {\n" 18560 " gohanINDEX_GOHAN = TYPE(1);\n" 18561 " gotenINDEX_GOTEN = TYPE(0);\n" 18562 " }\n"; 18563 static const GLchar* fs = "#version 430 core\n" 18564 "#extension GL_ARB_enhanced_layouts : require\n" 18565 "\n" 18566 "in vec4 gs_fs;\n" 18567 "out vec4 fs_out;\n" 18568 "\n" 18569 "void main()\n" 18570 "{\n" 18571 " fs_out = gs_fs;\n" 18572 "}\n" 18573 "\n"; 18574 static const GLchar* fs_tested = "#version 430 core\n" 18575 "#extension GL_ARB_enhanced_layouts : require\n" 18576 "\n" 18577 "VAR_DEFINITION" 18578 "\n" 18579 "in vec4 gs_fs;\n" 18580 "out vec4 fs_out;\n" 18581 "\n" 18582 "void main()\n" 18583 "{\n" 18584 " vec4 result = gs_fs;\n" 18585 "\n" 18586 "VARIABLE_USE" 18587 "\n" 18588 " fs_out = result;\n" 18589 "}\n" 18590 "\n"; 18591 static const GLchar* gs = "#version 430 core\n" 18592 "#extension GL_ARB_enhanced_layouts : require\n" 18593 "\n" 18594 "layout(points) in;\n" 18595 "layout(triangle_strip, max_vertices = 4) out;\n" 18596 "\n" 18597 "in vec4 tes_gs[];\n" 18598 "out vec4 gs_fs;\n" 18599 "\n" 18600 "void main()\n" 18601 "{\n" 18602 " gs_fs = tes_gs[0];\n" 18603 " gl_Position = vec4(-1, -1, 0, 1);\n" 18604 " EmitVertex();\n" 18605 " gs_fs = tes_gs[0];\n" 18606 " gl_Position = vec4(-1, 1, 0, 1);\n" 18607 " EmitVertex();\n" 18608 " gs_fs = tes_gs[0];\n" 18609 " gl_Position = vec4(1, -1, 0, 1);\n" 18610 " EmitVertex();\n" 18611 " gs_fs = tes_gs[0];\n" 18612 " gl_Position = vec4(1, 1, 0, 1);\n" 18613 " EmitVertex();\n" 18614 "}\n" 18615 "\n"; 18616 static const GLchar* gs_tested = "#version 430 core\n" 18617 "#extension GL_ARB_enhanced_layouts : require\n" 18618 "\n" 18619 "layout(points) in;\n" 18620 "layout(triangle_strip, max_vertices = 4) out;\n" 18621 "\n" 18622 "VAR_DEFINITION" 18623 "\n" 18624 "in vec4 tes_gs[];\n" 18625 "out vec4 gs_fs;\n" 18626 "\n" 18627 "void main()\n" 18628 "{\n" 18629 " vec4 result = tes_gs[0];\n" 18630 "\n" 18631 "VARIABLE_USE" 18632 "\n" 18633 " gs_fs = result;\n" 18634 " gl_Position = vec4(-1, -1, 0, 1);\n" 18635 " EmitVertex();\n" 18636 " gs_fs = result;\n" 18637 " gl_Position = vec4(-1, 1, 0, 1);\n" 18638 " EmitVertex();\n" 18639 " gs_fs = result;\n" 18640 " gl_Position = vec4(1, -1, 0, 1);\n" 18641 " EmitVertex();\n" 18642 " gs_fs = result;\n" 18643 " gl_Position = vec4(1, 1, 0, 1);\n" 18644 " EmitVertex();\n" 18645 "}\n" 18646 "\n"; 18647 static const GLchar* tcs = "#version 430 core\n" 18648 "#extension GL_ARB_enhanced_layouts : require\n" 18649 "\n" 18650 "layout(vertices = 1) out;\n" 18651 "\n" 18652 "in vec4 vs_tcs[];\n" 18653 "out vec4 tcs_tes[];\n" 18654 "\n" 18655 "void main()\n" 18656 "{\n" 18657 "\n" 18658 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 18659 "\n" 18660 " gl_TessLevelOuter[0] = 1.0;\n" 18661 " gl_TessLevelOuter[1] = 1.0;\n" 18662 " gl_TessLevelOuter[2] = 1.0;\n" 18663 " gl_TessLevelOuter[3] = 1.0;\n" 18664 " gl_TessLevelInner[0] = 1.0;\n" 18665 " gl_TessLevelInner[1] = 1.0;\n" 18666 "}\n" 18667 "\n"; 18668 static const GLchar* tcs_tested = "#version 430 core\n" 18669 "#extension GL_ARB_enhanced_layouts : require\n" 18670 "\n" 18671 "layout(vertices = 1) out;\n" 18672 "\n" 18673 "VAR_DEFINITION" 18674 "\n" 18675 "in vec4 vs_tcs[];\n" 18676 "out vec4 tcs_tes[];\n" 18677 "\n" 18678 "void main()\n" 18679 "{\n" 18680 " vec4 result = vs_tcs[gl_InvocationID];\n" 18681 "\n" 18682 "VARIABLE_USE" 18683 "\n" 18684 " tcs_tes[gl_InvocationID] = result;\n" 18685 "\n" 18686 " gl_TessLevelOuter[0] = 1.0;\n" 18687 " gl_TessLevelOuter[1] = 1.0;\n" 18688 " gl_TessLevelOuter[2] = 1.0;\n" 18689 " gl_TessLevelOuter[3] = 1.0;\n" 18690 " gl_TessLevelInner[0] = 1.0;\n" 18691 " gl_TessLevelInner[1] = 1.0;\n" 18692 "}\n" 18693 "\n"; 18694 static const GLchar* tes = "#version 430 core\n" 18695 "#extension GL_ARB_enhanced_layouts : require\n" 18696 "\n" 18697 "layout(isolines, point_mode) in;\n" 18698 "\n" 18699 "in vec4 tcs_tes[];\n" 18700 "out vec4 tes_gs;\n" 18701 "\n" 18702 "void main()\n" 18703 "{\n" 18704 " tes_gs = tcs_tes[0];\n" 18705 "}\n" 18706 "\n"; 18707 static const GLchar* tes_tested = "#version 430 core\n" 18708 "#extension GL_ARB_enhanced_layouts : require\n" 18709 "\n" 18710 "layout(isolines, point_mode) in;\n" 18711 "\n" 18712 "VAR_DEFINITION" 18713 "\n" 18714 "in vec4 tcs_tes[];\n" 18715 "out vec4 tes_gs;\n" 18716 "\n" 18717 "void main()\n" 18718 "{\n" 18719 " vec4 result = tcs_tes[0];\n" 18720 "\n" 18721 "VARIABLE_USE" 18722 "\n" 18723 " tes_gs += result;\n" 18724 "}\n" 18725 "\n"; 18726 static const GLchar* vs = "#version 430 core\n" 18727 "#extension GL_ARB_enhanced_layouts : require\n" 18728 "\n" 18729 "in vec4 in_vs;\n" 18730 "out vec4 vs_tcs;\n" 18731 "\n" 18732 "void main()\n" 18733 "{\n" 18734 " vs_tcs = in_vs;\n" 18735 "}\n" 18736 "\n"; 18737 static const GLchar* vs_tested = "#version 430 core\n" 18738 "#extension GL_ARB_enhanced_layouts : require\n" 18739 "\n" 18740 "VAR_DEFINITION" 18741 "\n" 18742 "in vec4 in_vs;\n" 18743 "out vec4 vs_tcs;\n" 18744 "\n" 18745 "void main()\n" 18746 "{\n" 18747 " vec4 result = in_vs;\n" 18748 "\n" 18749 "VARIABLE_USE" 18750 "\n" 18751 " vs_tcs += result;\n" 18752 "}\n" 18753 "\n"; 18754 18755 std::string source; 18756 testCase& test_case = m_test_cases[test_case_index]; 18757 18758 if (test_case.m_stage == stage) 18759 { 18760 const GLchar* array_gohan = ""; 18761 const GLchar* array_goten = ""; 18762 const GLchar* aux_gohan = getAuxiliaryQualifier(test_case.m_aux_gohan); 18763 const GLchar* aux_goten = getAuxiliaryQualifier(test_case.m_aux_goten); 18764 GLchar buffer_gohan[16]; 18765 GLchar buffer_goten[16]; 18766 const GLchar* direction = "in "; 18767 const GLchar* index_gohan = ""; 18768 const GLchar* index_goten = ""; 18769 const GLchar* int_gohan = test_case.m_int_gohan; 18770 const GLchar* int_goten = test_case.m_int_goten; 18771 size_t position = 0; 18772 size_t temp; 18773 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName(); 18774 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName(); 18775 const GLchar* var_use = input_use; 18776 18777 if (false == test_case.m_is_input) 18778 { 18779 direction = "out"; 18780 18781 var_use = output_use; 18782 } 18783 18784 sprintf(buffer_gohan, "%d", test_case.m_component_gohan); 18785 sprintf(buffer_goten, "%d", test_case.m_component_goten); 18786 18787 switch (stage) 18788 { 18789 case Utils::Shader::FRAGMENT: 18790 source = fs_tested; 18791 break; 18792 case Utils::Shader::GEOMETRY: 18793 source = gs_tested; 18794 array_gohan = "[]"; 18795 index_gohan = "[0]"; 18796 array_goten = "[]"; 18797 index_goten = "[0]"; 18798 break; 18799 case Utils::Shader::TESS_CTRL: 18800 source = tcs_tested; 18801 if (PATCH != test_case.m_aux_gohan) 18802 { 18803 array_gohan = "[]"; 18804 index_gohan = "[gl_InvocationID]"; 18805 } 18806 if (PATCH != test_case.m_aux_goten) 18807 { 18808 array_goten = "[]"; 18809 index_goten = "[gl_InvocationID]"; 18810 } 18811 break; 18812 case Utils::Shader::TESS_EVAL: 18813 source = tes_tested; 18814 array_gohan = "[]"; 18815 index_gohan = "[0]"; 18816 array_goten = "[]"; 18817 index_goten = "[0]"; 18818 break; 18819 case Utils::Shader::VERTEX: 18820 source = vs_tested; 18821 break; 18822 default: 18823 TCU_FAIL("Invalid enum"); 18824 } 18825 18826 temp = position; 18827 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 18828 position = temp; 18829 Utils::replaceToken("COMPONENT", position, buffer_gohan, source); 18830 Utils::replaceToken("AUX", position, aux_gohan, source); 18831 Utils::replaceToken("INTERPOLATION", position, int_gohan, source); 18832 Utils::replaceToken("DIRECTION", position, direction, source); 18833 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18834 Utils::replaceToken("ARRAY", position, array_gohan, source); 18835 Utils::replaceToken("COMPONENT", position, buffer_goten, source); 18836 Utils::replaceToken("AUX", position, aux_goten, source); 18837 Utils::replaceToken("INTERPOLATION", position, int_goten, source); 18838 Utils::replaceToken("DIRECTION", position, direction, source); 18839 Utils::replaceToken("TYPE", position, type_goten_name, source); 18840 Utils::replaceToken("ARRAY", position, array_goten, source); 18841 18842 temp = position; 18843 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 18844 position = temp; 18845 if (true == test_case.m_is_input) 18846 { 18847 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18848 Utils::replaceToken("TYPE", position, type_goten_name, source); 18849 } 18850 else 18851 { 18852 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18853 Utils::replaceToken("TYPE", position, type_goten_name, source); 18854 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18855 Utils::replaceToken("TYPE", position, type_goten_name, source); 18856 } 18857 18858 Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source); 18859 Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source); 18860 } 18861 else 18862 { 18863 switch (stage) 18864 { 18865 case Utils::Shader::FRAGMENT: 18866 source = fs; 18867 break; 18868 case Utils::Shader::GEOMETRY: 18869 source = gs; 18870 break; 18871 case Utils::Shader::TESS_CTRL: 18872 source = tcs; 18873 break; 18874 case Utils::Shader::TESS_EVAL: 18875 source = tes; 18876 break; 18877 case Utils::Shader::VERTEX: 18878 source = vs; 18879 break; 18880 default: 18881 TCU_FAIL("Invalid enum"); 18882 } 18883 } 18884 18885 return source; 18886 } 18887 18888 /** Get description of test case 18889 * 18890 * @param test_case_index Index of test case 18891 * 18892 * @return Test case description 18893 **/ 18894 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index) 18895 { 18896 std::stringstream stream; 18897 testCase& test_case = m_test_cases[test_case_index]; 18898 18899 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", " 18900 << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at " 18901 << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " " 18902 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: "; 18903 18904 if (true == test_case.m_is_input) 18905 { 18906 stream << "input"; 18907 } 18908 else 18909 { 18910 stream << "output"; 18911 } 18912 18913 return stream.str(); 18914 } 18915 18916 /** Get number of test cases 18917 * 18918 * @return Number of test cases 18919 **/ 18920 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber() 18921 { 18922 return static_cast<GLuint>(m_test_cases.size()); 18923 } 18924 18925 /** Selects if "compute" stage is relevant for test 18926 * 18927 * @param ignored 18928 * 18929 * @return false 18930 **/ 18931 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */) 18932 { 18933 return false; 18934 } 18935 18936 /** Prepare all test cases 18937 * 18938 **/ 18939 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit() 18940 { 18941 static const GLuint n_components_per_location = 4; 18942 const GLuint n_types = getTypesNumber(); 18943 18944 for (GLuint i = 0; i < n_types; ++i) 18945 { 18946 const Utils::Type& type_gohan = getType(i); 18947 const bool is_float_type_gohan = isFloatType(type_gohan); 18948 18949 /* Skip matrices */ 18950 if (1 != type_gohan.m_n_columns) 18951 { 18952 continue; 18953 } 18954 18955 for (GLuint j = 0; j < n_types; ++j) 18956 { 18957 const Utils::Type& type_goten = getType(j); 18958 const bool is_flat_req_gohan = (Utils::Type::Float == type_gohan.m_basic_type) ? false : true; 18959 const bool is_flat_req_goten = (Utils::Type::Float == type_goten.m_basic_type) ? false : true; 18960 const bool is_float_type_goten = isFloatType(type_goten); 18961 18962 /* Skip matrices */ 18963 if (1 != type_goten.m_n_columns) 18964 { 18965 continue; 18966 } 18967 18968 /* Skip invalid combinations */ 18969 if (is_float_type_gohan != is_float_type_goten) 18970 { 18971 continue; 18972 } 18973 18974 const GLuint n_req_components_gohan = type_gohan.m_n_rows; 18975 const GLuint n_req_components_goten = type_goten.m_n_rows; 18976 18977 /* Skip pairs that cannot fit into one location */ 18978 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten)) 18979 { 18980 continue; 18981 } 18982 18983 const GLuint gohan = 0; 18984 const GLuint goten = gohan + n_req_components_gohan; 18985 18986 const GLchar* fs_int_gohan = is_flat_req_gohan ? "flat" : ""; 18987 const GLchar* fs_int_goten = is_flat_req_goten ? "flat" : ""; 18988 18989 testCase test_case_tcs_np = { gohan, goten, NONE, PATCH, "", "", false, Utils::Shader::TESS_CTRL, 18990 type_gohan, type_goten }; 18991 18992 testCase test_case_tcs_pn = { gohan, goten, PATCH, NONE, "", "", false, Utils::Shader::TESS_CTRL, 18993 type_gohan, type_goten }; 18994 18995 testCase test_case_tes_np = { gohan, goten, NONE, PATCH, "", "", true, Utils::Shader::TESS_EVAL, 18996 type_gohan, type_goten }; 18997 18998 testCase test_case_tes_pn = { gohan, goten, PATCH, NONE, "", "", true, Utils::Shader::TESS_EVAL, 18999 type_gohan, type_goten }; 19000 19001 testCase test_case_fs_nc = { gohan, goten, NONE, CENTROID, 19002 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT, 19003 type_gohan, type_goten }; 19004 19005 testCase test_case_fs_cn = { gohan, goten, CENTROID, NONE, 19006 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT, 19007 type_gohan, type_goten }; 19008 19009 testCase test_case_fs_ns = { gohan, goten, NONE, SAMPLE, 19010 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT, 19011 type_gohan, type_goten }; 19012 19013 testCase test_case_fs_sn = { gohan, goten, SAMPLE, NONE, 19014 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT, 19015 type_gohan, type_goten }; 19016 19017 testCase test_case_fs_cs = { gohan, goten, CENTROID, SAMPLE, 19018 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT, 19019 type_gohan, type_goten }; 19020 19021 testCase test_case_fs_sc = { gohan, goten, SAMPLE, CENTROID, 19022 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT, 19023 type_gohan, type_goten }; 19024 19025 m_test_cases.push_back(test_case_tcs_np); 19026 m_test_cases.push_back(test_case_tcs_pn); 19027 m_test_cases.push_back(test_case_tes_np); 19028 m_test_cases.push_back(test_case_tes_pn); 19029 m_test_cases.push_back(test_case_fs_nc); 19030 m_test_cases.push_back(test_case_fs_cn); 19031 m_test_cases.push_back(test_case_fs_ns); 19032 m_test_cases.push_back(test_case_fs_sn); 19033 m_test_cases.push_back(test_case_fs_cs); 19034 m_test_cases.push_back(test_case_fs_sc); 19035 } 19036 } 19037 } 19038 19039 /** Get auxiliary storage qualifier 19040 * 19041 * @param aux Enumeration 19042 * 19043 * @return GLSL qualifier 19044 **/ 19045 const GLchar* VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux) 19046 { 19047 const GLchar* result = 0; 19048 19049 switch (aux) 19050 { 19051 case NONE: 19052 result = ""; 19053 break; 19054 case PATCH: 19055 result = "patch"; 19056 break; 19057 case CENTROID: 19058 result = "centroid"; 19059 break; 19060 case SAMPLE: 19061 result = "sample"; 19062 break; 19063 default: 19064 TCU_FAIL("Invalid enum"); 19065 } 19066 19067 return result; 19068 } 19069 19070 /** Check if given type is float 19071 * 19072 * @param type Type in question 19073 * 19074 * @return true if tpye is float, false otherwise 19075 **/ 19076 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isFloatType(const Utils::Type& type) 19077 { 19078 bool is_float = false; 19079 19080 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type)) 19081 { 19082 is_float = true; 19083 } 19084 19085 return is_float; 19086 } 19087 19088 /* Constants used by VertexAttribLocationAPITest */ 19089 const GLuint VertexAttribLocationAPITest::m_goten_location = 6; 19090 19091 /** Constructor 19092 * 19093 * @param context Test framework context 19094 **/ 19095 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context& context) 19096 : TextureTestBase(context, "vertex_attrib_location_api", 19097 "Test verifies that attribute locations API works as expected") 19098 { 19099 } 19100 19101 /** Does BindAttribLocation for "goten" and relink program 19102 * 19103 * @param program Program object 19104 * @param program_interface Interface of program 19105 **/ 19106 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program& program, 19107 Utils::ProgramInterface& program_interface) 19108 { 19109 const Functions& gl = m_context.getRenderContext().getFunctions(); 19110 19111 gl.bindAttribLocation(program.m_id, m_goten_location, "goten"); 19112 GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation"); 19113 19114 program.Link(gl, program.m_id); 19115 19116 /* We still need to get locations for gohan and chichi */ 19117 TextureTestBase::prepareAttribLocation(program, program_interface); 19118 } 19119 19120 /** Get interface of program 19121 * 19122 * @param ignored 19123 * @param program_interface Interface of program 19124 * @param ignored 19125 **/ 19126 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */, 19127 Utils::ProgramInterface& program_interface, 19128 Utils::VaryingPassthrough& /* varying_passthrough */) 19129 { 19130 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 19131 const Utils::Type& type = Utils::Type::vec4; 19132 const GLuint type_size = type.GetSize(); 19133 19134 /* Offsets */ 19135 const GLuint chichi_offset = 0; 19136 const GLuint goten_offset = chichi_offset + type_size; 19137 const GLuint gohan_offset = goten_offset + type_size; 19138 const GLuint goku_offset = gohan_offset + type_size; 19139 19140 /* Locations */ 19141 const GLuint goku_location = 2; 19142 const GLuint goten_location = m_goten_location; 19143 19144 /* Generate data */ 19145 m_goku_data = type.GenerateDataPacked(); 19146 m_gohan_data = type.GenerateDataPacked(); 19147 m_goten_data = type.GenerateDataPacked(); 19148 m_chichi_data = type.GenerateDataPacked(); 19149 19150 /* Globals */ 19151 si.m_globals = "const uint GOKU_LOCATION = 2;\n"; 19152 19153 /* Attributes */ 19154 si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */, 19155 goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19156 0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid*)&m_goku_data[0] /* data */, 19157 m_goku_data.size() /* data_size */); 19158 19159 si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */, 19160 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19161 0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */, 19162 (GLvoid*)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */); 19163 19164 si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */, 19165 goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19166 0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */, 19167 (GLvoid*)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */); 19168 19169 si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */, 19170 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19171 0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */, 19172 (GLvoid*)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */); 19173 } 19174 19175 /** Selects if "compute" stage is relevant for test 19176 * 19177 * @param ignored 19178 * 19179 * @return false 19180 **/ 19181 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */) 19182 { 19183 return false; 19184 } 19185 19186 /* Constants used by FragmentDataLocationAPITest */ 19187 const GLuint FragmentDataLocationAPITest::m_goten_location = 6; 19188 19189 /** Constructor 19190 * 19191 * @param context Test framework context 19192 **/ 19193 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context& context) 19194 : TextureTestBase(context, "fragment_data_location_api", 19195 "Test verifies that fragment data locations API works as expected") 19196 , m_goku(context) 19197 , m_gohan(context) 19198 , m_goten(context) 19199 , m_chichi(context) 19200 { 19201 } 19202 19203 /** Verifies contents of drawn images 19204 * 19205 * @param ignored 19206 * @param ignored 19207 * 19208 * @return true if images are filled with expected values, false otherwise 19209 **/ 19210 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& /* color_0 */) 19211 { 19212 static const GLuint size = m_width * m_height; 19213 static const GLuint expected_goku = 0xff000000; 19214 static const GLuint expected_gohan = 0xff0000ff; 19215 static const GLuint expected_goten = 0xff00ff00; 19216 static const GLuint expected_chichi = 0xffff0000; 19217 19218 std::vector<GLuint> data; 19219 data.resize(size); 19220 19221 m_goku.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 19222 19223 for (GLuint i = 0; i < size; ++i) 19224 { 19225 const GLuint color = data[i]; 19226 19227 if (expected_goku != color) 19228 { 19229 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color 19230 << tcu::TestLog::EndMessage; 19231 return false; 19232 } 19233 } 19234 19235 m_gohan.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 19236 19237 for (GLuint i = 0; i < size; ++i) 19238 { 19239 const GLuint color = data[i]; 19240 19241 if (expected_gohan != color) 19242 { 19243 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color 19244 << tcu::TestLog::EndMessage; 19245 return false; 19246 } 19247 } 19248 19249 m_goten.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 19250 19251 for (GLuint i = 0; i < size; ++i) 19252 { 19253 const GLuint color = data[i]; 19254 19255 if (expected_goten != color) 19256 { 19257 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color 19258 << tcu::TestLog::EndMessage; 19259 return false; 19260 } 19261 } 19262 19263 m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 19264 19265 for (GLuint i = 0; i < size; ++i) 19266 { 19267 const GLuint color = data[i]; 19268 19269 if (expected_chichi != color) 19270 { 19271 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color 19272 << tcu::TestLog::EndMessage; 19273 return false; 19274 } 19275 } 19276 19277 return true; 19278 } 19279 19280 /** Prepare code snippet that will set out variables 19281 * 19282 * @param ignored 19283 * @param ignored 19284 * @param stage Shader stage 19285 * 19286 * @return Code that pass in variables to next stage 19287 **/ 19288 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */, 19289 Utils::VaryingPassthrough& /* varying_passthrough */, 19290 Utils::Shader::STAGES stage) 19291 { 19292 std::string result; 19293 19294 /* Skip for compute shader */ 19295 if (Utils::Shader::FRAGMENT != stage) 19296 { 19297 result = ""; 19298 } 19299 else 19300 { 19301 result = "chichi = vec4(0, 0, 1, 1);\n" 19302 " goku = vec4(0, 0, 0, 1);\n" 19303 " goten = vec4(0, 1, 0, 1);\n" 19304 " gohan = vec4(1, 0, 0, 1);\n"; 19305 } 19306 19307 return result; 19308 } 19309 19310 /** Get interface of program 19311 * 19312 * @param ignored 19313 * @param program_interface Interface of program 19314 * @param ignored 19315 **/ 19316 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */, 19317 Utils::ProgramInterface& program_interface, 19318 Utils::VaryingPassthrough& /* varying_passthrough */) 19319 { 19320 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT); 19321 const Utils::Type& type = Utils::Type::vec4; 19322 19323 /* Locations */ 19324 m_goku_location = 2; 19325 19326 /* Globals */ 19327 si.m_globals = "const uint GOKU_LOCATION = 2;\n"; 19328 19329 /* Attributes */ 19330 si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */, 19331 m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19332 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */); 19333 19334 si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */, 19335 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19336 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */); 19337 19338 si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */, 19339 m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19340 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */); 19341 19342 si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */, 19343 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19344 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */); 19345 } 19346 19347 /** Selects if "compute" stage is relevant for test 19348 * 19349 * @param ignored 19350 * 19351 * @return false 19352 **/ 19353 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */) 19354 { 19355 return false; 19356 } 19357 19358 /** Get locations for all outputs with automatic_location 19359 * 19360 * @param program Program object 19361 * @param program_interface Interface of program 19362 **/ 19363 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program& program, 19364 Utils::ProgramInterface& program_interface) 19365 { 19366 /* Bind location of goten */ 19367 const Functions& gl = m_context.getRenderContext().getFunctions(); 19368 19369 gl.bindFragDataLocation(program.m_id, m_goten_location, "goten"); 19370 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation"); 19371 19372 program.Link(gl, program.m_id); 19373 19374 /* Prepare locations for gohan and chichi */ 19375 TextureTestBase::prepareFragmentDataLoc(program, program_interface); 19376 19377 /* Get all locations */ 19378 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT); 19379 19380 Utils::Variable::PtrVector& outputs = si.m_outputs; 19381 19382 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it) 19383 { 19384 const Utils::Variable::Descriptor& desc = (*it)->m_descriptor; 19385 19386 if (0 == desc.m_name.compare("gohan")) 19387 { 19388 m_gohan_location = desc.m_expected_location; 19389 } 19390 else if (0 == desc.m_name.compare("chichi")) 19391 { 19392 m_chichi_location = desc.m_expected_location; 19393 } 19394 19395 /* Locations of goku and goten are fixed */ 19396 } 19397 } 19398 19399 /** Prepare framebuffer with single texture as color attachment 19400 * 19401 * @param framebuffer Framebuffer 19402 * @param color_0_texture Texture that will used as color attachment 19403 **/ 19404 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture) 19405 { 19406 /* Let parent prepare its stuff */ 19407 TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture); 19408 19409 /* Prepare data */ 19410 std::vector<GLuint> texture_data; 19411 texture_data.resize(m_width * m_height); 19412 19413 for (GLuint i = 0; i < texture_data.size(); ++i) 19414 { 19415 texture_data[i] = 0x20406080; 19416 } 19417 19418 /* Prepare textures */ 19419 m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]); 19420 19421 m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]); 19422 19423 m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]); 19424 19425 m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]); 19426 19427 /* Attach textures to framebuffer */ 19428 framebuffer.Bind(); 19429 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height); 19430 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height); 19431 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height); 19432 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height); 19433 19434 /* Set up drawbuffers */ 19435 const Functions& gl = m_context.getRenderContext().getFunctions(); 19436 // The fragment shader can have more than 4 color outputs, but it only care about 4 (goku, gohan, goten, chichi). 19437 // We will first initialize all draw buffers to NONE and then set the real value for the 4 outputs we care about 19438 GLint maxDrawBuffers = 0; 19439 gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); 19440 19441 std::vector<GLenum> buffers(maxDrawBuffers, GL_NONE); 19442 buffers[m_chichi_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location); 19443 buffers[m_goten_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location); 19444 buffers[m_goku_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location); 19445 buffers[m_gohan_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location); 19446 19447 gl.drawBuffers(maxDrawBuffers, buffers.data()); 19448 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers"); 19449 } 19450 19451 /** Constructor 19452 * 19453 * @param context Test framework context 19454 **/ 19455 XFBInputTest::XFBInputTest(deqp::Context& context) 19456 : NegativeTestBase(context, "xfb_input", 19457 "Test verifies that compiler reports error when xfb qualifiers are used with input") 19458 { 19459 } 19460 19461 /** Source for given test case and stage 19462 * 19463 * @param test_case_index Index of test case 19464 * @param stage Shader stage 19465 * 19466 * @return Shader source 19467 **/ 19468 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 19469 { 19470 static const GLchar* buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n"; 19471 static const GLchar* offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n"; 19472 static const GLchar* stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n"; 19473 static const GLchar* input_use = " result += gohanINDEX;\n"; 19474 static const GLchar* fs = "#version 430 core\n" 19475 "#extension GL_ARB_enhanced_layouts : require\n" 19476 "\n" 19477 "in vec4 gs_fs;\n" 19478 "out vec4 fs_out;\n" 19479 "\n" 19480 "void main()\n" 19481 "{\n" 19482 " fs_out = gs_fs;\n" 19483 "}\n" 19484 "\n"; 19485 static const GLchar* fs_tested = "#version 430 core\n" 19486 "#extension GL_ARB_enhanced_layouts : require\n" 19487 "\n" 19488 "VAR_DEFINITION" 19489 "\n" 19490 "in vec4 gs_fs;\n" 19491 "out vec4 fs_out;\n" 19492 "\n" 19493 "void main()\n" 19494 "{\n" 19495 " vec4 result = gs_fs;\n" 19496 "\n" 19497 "VARIABLE_USE" 19498 "\n" 19499 " fs_out = result;\n" 19500 "}\n" 19501 "\n"; 19502 static const GLchar* gs = "#version 430 core\n" 19503 "#extension GL_ARB_enhanced_layouts : require\n" 19504 "\n" 19505 "layout(points) in;\n" 19506 "layout(triangle_strip, max_vertices = 4) out;\n" 19507 "\n" 19508 "in vec4 tes_gs[];\n" 19509 "out vec4 gs_fs;\n" 19510 "\n" 19511 "void main()\n" 19512 "{\n" 19513 " gs_fs = tes_gs[0];\n" 19514 " gl_Position = vec4(-1, -1, 0, 1);\n" 19515 " EmitVertex();\n" 19516 " gs_fs = tes_gs[0];\n" 19517 " gl_Position = vec4(-1, 1, 0, 1);\n" 19518 " EmitVertex();\n" 19519 " gs_fs = tes_gs[0];\n" 19520 " gl_Position = vec4(1, -1, 0, 1);\n" 19521 " EmitVertex();\n" 19522 " gs_fs = tes_gs[0];\n" 19523 " gl_Position = vec4(1, 1, 0, 1);\n" 19524 " EmitVertex();\n" 19525 "}\n" 19526 "\n"; 19527 static const GLchar* gs_tested = "#version 430 core\n" 19528 "#extension GL_ARB_enhanced_layouts : require\n" 19529 "\n" 19530 "layout(points) in;\n" 19531 "layout(triangle_strip, max_vertices = 4) out;\n" 19532 "\n" 19533 "VAR_DEFINITION" 19534 "\n" 19535 "in vec4 tes_gs[];\n" 19536 "out vec4 gs_fs;\n" 19537 "\n" 19538 "void main()\n" 19539 "{\n" 19540 " vec4 result = tes_gs[0];\n" 19541 "\n" 19542 "VARIABLE_USE" 19543 "\n" 19544 " gs_fs = result;\n" 19545 " gl_Position = vec4(-1, -1, 0, 1);\n" 19546 " EmitVertex();\n" 19547 " gs_fs = result;\n" 19548 " gl_Position = vec4(-1, 1, 0, 1);\n" 19549 " EmitVertex();\n" 19550 " gs_fs = result;\n" 19551 " gl_Position = vec4(1, -1, 0, 1);\n" 19552 " EmitVertex();\n" 19553 " gs_fs = result;\n" 19554 " gl_Position = vec4(1, 1, 0, 1);\n" 19555 " EmitVertex();\n" 19556 "}\n" 19557 "\n"; 19558 static const GLchar* tcs = "#version 430 core\n" 19559 "#extension GL_ARB_enhanced_layouts : require\n" 19560 "\n" 19561 "layout(vertices = 1) out;\n" 19562 "\n" 19563 "in vec4 vs_tcs[];\n" 19564 "out vec4 tcs_tes[];\n" 19565 "\n" 19566 "void main()\n" 19567 "{\n" 19568 "\n" 19569 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 19570 "\n" 19571 " gl_TessLevelOuter[0] = 1.0;\n" 19572 " gl_TessLevelOuter[1] = 1.0;\n" 19573 " gl_TessLevelOuter[2] = 1.0;\n" 19574 " gl_TessLevelOuter[3] = 1.0;\n" 19575 " gl_TessLevelInner[0] = 1.0;\n" 19576 " gl_TessLevelInner[1] = 1.0;\n" 19577 "}\n" 19578 "\n"; 19579 static const GLchar* tcs_tested = "#version 430 core\n" 19580 "#extension GL_ARB_enhanced_layouts : require\n" 19581 "\n" 19582 "layout(vertices = 1) out;\n" 19583 "\n" 19584 "VAR_DEFINITION" 19585 "\n" 19586 "in vec4 vs_tcs[];\n" 19587 "out vec4 tcs_tes[];\n" 19588 "\n" 19589 "void main()\n" 19590 "{\n" 19591 " vec4 result = vs_tcs[gl_InvocationID];\n" 19592 "\n" 19593 "VARIABLE_USE" 19594 "\n" 19595 " tcs_tes[gl_InvocationID] = result;\n" 19596 "\n" 19597 " gl_TessLevelOuter[0] = 1.0;\n" 19598 " gl_TessLevelOuter[1] = 1.0;\n" 19599 " gl_TessLevelOuter[2] = 1.0;\n" 19600 " gl_TessLevelOuter[3] = 1.0;\n" 19601 " gl_TessLevelInner[0] = 1.0;\n" 19602 " gl_TessLevelInner[1] = 1.0;\n" 19603 "}\n" 19604 "\n"; 19605 static const GLchar* tes = "#version 430 core\n" 19606 "#extension GL_ARB_enhanced_layouts : require\n" 19607 "\n" 19608 "layout(isolines, point_mode) in;\n" 19609 "\n" 19610 "in vec4 tcs_tes[];\n" 19611 "out vec4 tes_gs;\n" 19612 "\n" 19613 "void main()\n" 19614 "{\n" 19615 " tes_gs = tcs_tes[0];\n" 19616 "}\n" 19617 "\n"; 19618 static const GLchar* tes_tested = "#version 430 core\n" 19619 "#extension GL_ARB_enhanced_layouts : require\n" 19620 "\n" 19621 "layout(isolines, point_mode) in;\n" 19622 "\n" 19623 "VAR_DEFINITION" 19624 "\n" 19625 "in vec4 tcs_tes[];\n" 19626 "out vec4 tes_gs;\n" 19627 "\n" 19628 "void main()\n" 19629 "{\n" 19630 " vec4 result = tcs_tes[0];\n" 19631 "\n" 19632 "VARIABLE_USE" 19633 "\n" 19634 " tes_gs += result;\n" 19635 "}\n" 19636 "\n"; 19637 static const GLchar* vs = "#version 430 core\n" 19638 "#extension GL_ARB_enhanced_layouts : require\n" 19639 "\n" 19640 "in vec4 in_vs;\n" 19641 "out vec4 vs_tcs;\n" 19642 "\n" 19643 "void main()\n" 19644 "{\n" 19645 " vs_tcs = in_vs;\n" 19646 "}\n" 19647 "\n"; 19648 static const GLchar* vs_tested = "#version 430 core\n" 19649 "#extension GL_ARB_enhanced_layouts : require\n" 19650 "\n" 19651 "VAR_DEFINITION" 19652 "\n" 19653 "in vec4 in_vs;\n" 19654 "out vec4 vs_tcs;\n" 19655 "\n" 19656 "void main()\n" 19657 "{\n" 19658 " vec4 result = in_vs;\n" 19659 "\n" 19660 "VARIABLE_USE" 19661 "\n" 19662 " vs_tcs += result;\n" 19663 "}\n" 19664 "\n"; 19665 19666 std::string source; 19667 testCase& test_case = m_test_cases[test_case_index]; 19668 19669 if (test_case.m_stage == stage) 19670 { 19671 const GLchar* array = ""; 19672 const GLchar* index = ""; 19673 size_t position = 0; 19674 size_t temp; 19675 const GLchar* var_definition = 0; 19676 const GLchar* var_use = input_use; 19677 19678 switch (test_case.m_qualifier) 19679 { 19680 case BUFFER: 19681 var_definition = buffer_var_definition; 19682 break; 19683 case OFFSET: 19684 var_definition = offset_var_definition; 19685 break; 19686 case STRIDE: 19687 var_definition = stride_var_definition; 19688 break; 19689 default: 19690 TCU_FAIL("Invalid enum"); 19691 } 19692 19693 switch (stage) 19694 { 19695 case Utils::Shader::FRAGMENT: 19696 source = fs_tested; 19697 break; 19698 case Utils::Shader::GEOMETRY: 19699 source = gs_tested; 19700 array = "[]"; 19701 index = "[0]"; 19702 break; 19703 case Utils::Shader::TESS_CTRL: 19704 source = tcs_tested; 19705 array = "[]"; 19706 index = "[gl_InvocationID]"; 19707 break; 19708 case Utils::Shader::TESS_EVAL: 19709 source = tes_tested; 19710 array = "[]"; 19711 index = "[0]"; 19712 break; 19713 case Utils::Shader::VERTEX: 19714 source = vs_tested; 19715 break; 19716 default: 19717 TCU_FAIL("Invalid enum"); 19718 } 19719 19720 temp = position; 19721 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 19722 position = temp; 19723 Utils::replaceToken("ARRAY", position, array, source); 19724 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 19725 19726 Utils::replaceAllTokens("INDEX", index, source); 19727 } 19728 else 19729 { 19730 switch (stage) 19731 { 19732 case Utils::Shader::FRAGMENT: 19733 source = fs; 19734 break; 19735 case Utils::Shader::GEOMETRY: 19736 source = gs; 19737 break; 19738 case Utils::Shader::TESS_CTRL: 19739 source = tcs; 19740 break; 19741 case Utils::Shader::TESS_EVAL: 19742 source = tes; 19743 break; 19744 case Utils::Shader::VERTEX: 19745 source = vs; 19746 break; 19747 default: 19748 TCU_FAIL("Invalid enum"); 19749 } 19750 } 19751 19752 return source; 19753 } 19754 19755 /** Get description of test case 19756 * 19757 * @param test_case_index Index of test case 19758 * 19759 * @return Test case description 19760 **/ 19761 std::string XFBInputTest::getTestCaseName(GLuint test_case_index) 19762 { 19763 std::stringstream stream; 19764 testCase& test_case = m_test_cases[test_case_index]; 19765 19766 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: "; 19767 19768 switch (test_case.m_qualifier) 19769 { 19770 case BUFFER: 19771 stream << "xfb_buffer"; 19772 break; 19773 case OFFSET: 19774 stream << "xfb_offset"; 19775 break; 19776 case STRIDE: 19777 stream << "xfb_stride"; 19778 break; 19779 default: 19780 TCU_FAIL("Invalid enum"); 19781 } 19782 19783 return stream.str(); 19784 } 19785 19786 /** Get number of test cases 19787 * 19788 * @return Number of test cases 19789 **/ 19790 GLuint XFBInputTest::getTestCaseNumber() 19791 { 19792 return static_cast<GLuint>(m_test_cases.size()); 19793 } 19794 19795 /** Selects if "compute" stage is relevant for test 19796 * 19797 * @param ignored 19798 * 19799 * @return false 19800 **/ 19801 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */) 19802 { 19803 return false; 19804 } 19805 19806 /** Prepare all test cases 19807 * 19808 **/ 19809 void XFBInputTest::testInit() 19810 { 19811 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier) 19812 { 19813 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 19814 { 19815 if (Utils::Shader::COMPUTE == stage) 19816 { 19817 continue; 19818 } 19819 19820 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage }; 19821 19822 m_test_cases.push_back(test_case); 19823 } 19824 } 19825 } 19826 19827 /* Constants used by XFBAllStagesTest */ 19828 const GLuint XFBAllStagesTest::m_gs_index = 3; 19829 19830 /** Constructor 19831 * 19832 * @param context Test context 19833 **/ 19834 XFBAllStagesTest::XFBAllStagesTest(deqp::Context& context) 19835 : BufferTestBase(context, "xfb_all_stages", 19836 "Test verifies that only last stage in vertex processing can output to transform feedback") 19837 { 19838 /* Nothing to be done here */ 19839 } 19840 19841 /** Get descriptors of buffers necessary for test 19842 * 19843 * @param ignored 19844 * @param out_descriptors Descriptors of buffers used by test 19845 **/ 19846 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 19847 bufferDescriptor::Vector& out_descriptors) 19848 { 19849 static const GLuint n_stages = 4; 19850 const Utils::Type& vec4 = Utils::Type::vec4; 19851 19852 /* Data */ 19853 tcu::Vec4 sum; 19854 19855 /* Test uses single uniform and xfb per stage + uniform for fragment shader */ 19856 out_descriptors.resize(n_stages * 2 + 1); 19857 19858 /* */ 19859 for (GLuint i = 0; i < n_stages; ++i) 19860 { 19861 /* Get references */ 19862 bufferDescriptor& uniform = out_descriptors[i + 0]; 19863 bufferDescriptor& xfb = out_descriptors[i + n_stages]; 19864 19865 /* Index */ 19866 uniform.m_index = i; 19867 xfb.m_index = i; 19868 19869 /* Target */ 19870 uniform.m_target = Utils::Buffer::Uniform; 19871 xfb.m_target = Utils::Buffer::Transform_feedback; 19872 19873 /* Data */ 19874 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat()); 19875 19876 sum += var; 19877 19878 uniform.m_initial_data.resize(vec4.GetSize()); 19879 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize()); 19880 19881 xfb.m_initial_data = vec4.GenerateDataPacked(); 19882 19883 if (m_gs_index != i) 19884 { 19885 xfb.m_expected_data = xfb.m_initial_data; 19886 } 19887 else 19888 { 19889 xfb.m_expected_data.resize(vec4.GetSize()); 19890 memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize()); 19891 } 19892 } 19893 19894 /* FS */ 19895 { 19896 /* Get reference */ 19897 bufferDescriptor& uniform = out_descriptors[n_stages * 2]; 19898 19899 /* Index */ 19900 uniform.m_index = n_stages; 19901 19902 /* Target */ 19903 uniform.m_target = Utils::Buffer::Uniform; 19904 19905 /* Data */ 19906 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat()); 19907 19908 uniform.m_initial_data.resize(vec4.GetSize()); 19909 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize()); 19910 } 19911 } 19912 19913 /** Get body of main function for given shader stage 19914 * 19915 * @param ignored 19916 * @param stage Shader stage 19917 * @param out_assignments Set to empty 19918 * @param out_calculations Set to empty 19919 **/ 19920 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage, 19921 std::string& out_assignments, std::string& out_calculations) 19922 { 19923 out_calculations = ""; 19924 19925 static const GLchar* vs = " vs_tcs = uni_vs;\n"; 19926 static const GLchar* tcs = " tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n"; 19927 static const GLchar* tes = " tes_gs = uni_tes + tcs_tes[0];\n"; 19928 static const GLchar* gs = " gs_fs = uni_gs + tes_gs[0];\n"; 19929 static const GLchar* fs = " fs_out = uni_fs + gs_fs;\n"; 19930 19931 const GLchar* assignments = 0; 19932 switch (stage) 19933 { 19934 case Utils::Shader::FRAGMENT: 19935 assignments = fs; 19936 break; 19937 case Utils::Shader::GEOMETRY: 19938 assignments = gs; 19939 break; 19940 case Utils::Shader::TESS_CTRL: 19941 assignments = tcs; 19942 break; 19943 case Utils::Shader::TESS_EVAL: 19944 assignments = tes; 19945 break; 19946 case Utils::Shader::VERTEX: 19947 assignments = vs; 19948 break; 19949 default: 19950 TCU_FAIL("Invalid enum"); 19951 } 19952 19953 out_assignments = assignments; 19954 } 19955 19956 /** Get interface of shader 19957 * 19958 * @param ignored 19959 * @param stage Shader stage 19960 * @param out_interface Set to "" 19961 **/ 19962 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage, 19963 std::string& out_interface) 19964 { 19965 static const GLchar* vs = "layout(xfb_buffer = 0, xfb_offset = 0) out vec4 vs_tcs;\n" 19966 "layout(binding = 0) uniform vs_block {\n" 19967 " vec4 uni_vs;\n" 19968 "};\n"; 19969 static const GLchar* tcs = " in vec4 vs_tcs[];\n" 19970 "layout(xfb_buffer = 1, xfb_offset = 0) out vec4 tcs_tes[1];\n" 19971 "layout(binding = 1) uniform tcs_block {\n" 19972 " vec4 uni_tcs;\n" 19973 "};\n"; 19974 static const GLchar* tes = " in vec4 tcs_tes[];\n" 19975 "layout(xfb_buffer = 2, xfb_offset = 0) out vec4 tes_gs;\n" 19976 "layout(binding = 2) uniform tes_block {\n" 19977 " vec4 uni_tes;\n" 19978 "};\n"; 19979 static const GLchar* gs = " in vec4 tes_gs[];\n" 19980 "layout(xfb_buffer = 3, xfb_offset = 0) out vec4 gs_fs;\n" 19981 "layout(binding = 3) uniform gs_block {\n" 19982 " vec4 uni_gs;\n" 19983 "};\n"; 19984 static const GLchar* fs = " in vec4 gs_fs;\n" 19985 " out vec4 fs_out;\n" 19986 "layout(binding = 4) uniform fs_block {\n" 19987 " vec4 uni_fs;\n" 19988 "};\n"; 19989 19990 const GLchar* interface = 0; 19991 switch (stage) 19992 { 19993 case Utils::Shader::FRAGMENT: 19994 interface = fs; 19995 break; 19996 case Utils::Shader::GEOMETRY: 19997 interface = gs; 19998 break; 19999 case Utils::Shader::TESS_CTRL: 20000 interface = tcs; 20001 break; 20002 case Utils::Shader::TESS_EVAL: 20003 interface = tes; 20004 break; 20005 case Utils::Shader::VERTEX: 20006 interface = vs; 20007 break; 20008 default: 20009 TCU_FAIL("Invalid enum"); 20010 } 20011 20012 out_interface = interface; 20013 } 20014 20015 /* Constants used by XFBStrideOfEmptyListTest */ 20016 const GLuint XFBStrideOfEmptyListTest::m_stride = 64; 20017 20018 /** Constructor 20019 * 20020 * @param context Test context 20021 **/ 20022 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context& context) 20023 : BufferTestBase( 20024 context, "xfb_stride_of_empty_list", 20025 "Test verifies correct behavior when xfb_stride qualifier is specified but no xfb_offset is specified") 20026 { 20027 /* Nothing to be done here */ 20028 } 20029 20030 /** Execute drawArrays for single vertex 20031 * 20032 * @param test_case_index Index of test case 20033 * 20034 * @return true if proper error is reported 20035 **/ 20036 bool XFBStrideOfEmptyListTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 20037 { 20038 const Functions& gl = m_context.getRenderContext().getFunctions(); 20039 bool result = true; 20040 20041 /* Draw */ 20042 gl.disable(GL_RASTERIZER_DISCARD); 20043 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 20044 20045 gl.beginTransformFeedback(GL_POINTS); 20046 GLenum error = gl.getError(); 20047 switch (test_case_index) 20048 { 20049 case VALID: 20050 if (GL_NO_ERROR != error) 20051 { 20052 gl.endTransformFeedback(); 20053 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback"); 20054 } 20055 20056 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 20057 error = gl.getError(); 20058 20059 gl.endTransformFeedback(); 20060 GLU_EXPECT_NO_ERROR(error, "DrawArrays"); 20061 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 20062 20063 break; 20064 20065 case FIRST_MISSING: 20066 if (GL_NO_ERROR == error) 20067 { 20068 gl.endTransformFeedback(); 20069 } 20070 20071 if (GL_INVALID_OPERATION != error) 20072 { 20073 m_context.getTestContext().getLog() 20074 << tcu::TestLog::Message << "XFB at index 0, that is written by GS, is missing. It was expected that " 20075 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: " 20076 << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 20077 20078 result = false; 20079 } 20080 20081 break; 20082 20083 case SECOND_MISSING: 20084 if (GL_NO_ERROR != error) 20085 { 20086 gl.endTransformFeedback(); 20087 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback"); 20088 } 20089 20090 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 20091 error = gl.getError(); 20092 20093 gl.endTransformFeedback(); 20094 GLU_EXPECT_NO_ERROR(error, "DrawArrays"); 20095 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 20096 20097 break; 20098 } 20099 20100 /* Done */ 20101 return result; 20102 } 20103 20104 /** Get descriptors of buffers necessary for test 20105 * 20106 * @param test_case_index Index of test case 20107 * @param out_descriptors Descriptors of buffers used by test 20108 **/ 20109 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint test_case_index, 20110 bufferDescriptor::Vector& out_descriptors) 20111 { 20112 switch (test_case_index) 20113 { 20114 case VALID: 20115 { 20116 /* Test needs single uniform and two xfbs */ 20117 out_descriptors.resize(3); 20118 20119 /* Get references */ 20120 bufferDescriptor& uniform = out_descriptors[0]; 20121 bufferDescriptor& xfb_0 = out_descriptors[1]; 20122 bufferDescriptor& xfb_1 = out_descriptors[2]; 20123 20124 /* Index */ 20125 uniform.m_index = 0; 20126 xfb_0.m_index = 0; 20127 xfb_1.m_index = 1; 20128 20129 /* Target */ 20130 uniform.m_target = Utils::Buffer::Uniform; 20131 xfb_0.m_target = Utils::Buffer::Transform_feedback; 20132 xfb_1.m_target = Utils::Buffer::Transform_feedback; 20133 20134 /* Data */ 20135 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20136 20137 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20138 xfb_0.m_expected_data = uniform.m_initial_data; 20139 20140 /* Data, contents are the same as no modification is expected */ 20141 xfb_1.m_initial_data.resize(m_stride); 20142 xfb_1.m_expected_data.resize(m_stride); 20143 20144 for (GLuint i = 0; i < m_stride; ++i) 20145 { 20146 xfb_1.m_initial_data[0] = (glw::GLubyte)i; 20147 xfb_1.m_expected_data[0] = (glw::GLubyte)i; 20148 } 20149 } 20150 20151 break; 20152 20153 case FIRST_MISSING: 20154 { 20155 /* Test needs single uniform and two xfbs */ 20156 out_descriptors.resize(2); 20157 20158 /* Get references */ 20159 bufferDescriptor& uniform = out_descriptors[0]; 20160 bufferDescriptor& xfb_1 = out_descriptors[1]; 20161 20162 /* Index */ 20163 uniform.m_index = 0; 20164 xfb_1.m_index = 1; 20165 20166 /* Target */ 20167 uniform.m_target = Utils::Buffer::Uniform; 20168 xfb_1.m_target = Utils::Buffer::Transform_feedback; 20169 20170 /* Data */ 20171 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20172 20173 /* Draw call will not be executed, contents does not matter */ 20174 xfb_1.m_initial_data.resize(m_stride); 20175 } 20176 20177 break; 20178 20179 case SECOND_MISSING: 20180 { 20181 /* Test needs single uniform and two xfbs */ 20182 out_descriptors.resize(2); 20183 20184 /* Get references */ 20185 bufferDescriptor& uniform = out_descriptors[0]; 20186 bufferDescriptor& xfb_0 = out_descriptors[1]; 20187 20188 /* Index */ 20189 uniform.m_index = 0; 20190 xfb_0.m_index = 0; 20191 20192 /* Target */ 20193 uniform.m_target = Utils::Buffer::Uniform; 20194 xfb_0.m_target = Utils::Buffer::Transform_feedback; 20195 20196 /* Data */ 20197 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20198 20199 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20200 xfb_0.m_expected_data = uniform.m_initial_data; 20201 } 20202 20203 break; 20204 } 20205 } 20206 20207 /** Get body of main function for given shader stage 20208 * 20209 * @param ignored 20210 * @param stage Shader stage 20211 * @param out_assignments Set to empty 20212 * @param out_calculations Set to empty 20213 **/ 20214 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 20215 std::string& out_assignments, std::string& out_calculations) 20216 { 20217 out_calculations = ""; 20218 20219 static const GLchar* gs = " gs_fs = uni_gs;\n"; 20220 static const GLchar* fs = " fs_out = vec4(gs_fs);\n"; 20221 20222 const GLchar* assignments = ""; 20223 switch (stage) 20224 { 20225 case Utils::Shader::FRAGMENT: 20226 assignments = fs; 20227 break; 20228 case Utils::Shader::GEOMETRY: 20229 assignments = gs; 20230 break; 20231 default: 20232 break; 20233 } 20234 20235 out_assignments = assignments; 20236 } 20237 20238 /** Get interface of shader 20239 * 20240 * @param ignored 20241 * @param stage Shader stage 20242 * @param out_interface Set to "" 20243 **/ 20244 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 20245 std::string& out_interface) 20246 { 20247 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 gs_fs;\n" 20248 "layout (xfb_buffer = 1, xfb_stride = 64) out;\n" 20249 "\n" 20250 "layout (binding = 0) uniform gs_block {\n" 20251 " vec4 uni_gs;\n" 20252 "};\n"; 20253 static const GLchar* fs = "in vec4 gs_fs;\n" 20254 "out vec4 fs_out;\n"; 20255 20256 switch (stage) 20257 { 20258 case Utils::Shader::FRAGMENT: 20259 out_interface = fs; 20260 break; 20261 case Utils::Shader::GEOMETRY: 20262 out_interface = gs; 20263 break; 20264 default: 20265 out_interface = ""; 20266 return; 20267 } 20268 } 20269 20270 /** Returns buffer details in human readable form. 20271 * 20272 * @param test_case_index Index of test case 20273 * 20274 * @return Case description 20275 **/ 20276 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index) 20277 { 20278 std::string result; 20279 20280 switch (test_case_index) 20281 { 20282 case VALID: 20283 result = "Valid case"; 20284 break; 20285 case FIRST_MISSING: 20286 result = "Missing xfb at index 0"; 20287 break; 20288 case SECOND_MISSING: 20289 result = "Missing xfb at index 1"; 20290 break; 20291 default: 20292 TCU_FAIL("Invalid enum"); 20293 } 20294 20295 return result; 20296 } 20297 20298 /** Get number of test cases 20299 * 20300 * @return 3 20301 **/ 20302 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber() 20303 { 20304 return 3; 20305 } 20306 20307 /* Constants used by XFBStrideOfEmptyListTest */ 20308 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64; 20309 20310 /** Constructor 20311 * 20312 * @param context Test context 20313 **/ 20314 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context& context) 20315 : BufferTestBase(context, "xfb_stride_of_empty_list_and_api", 20316 "Test verifies that xfb_stride qualifier is not overriden by API") 20317 { 20318 /* Nothing to be done here */ 20319 } 20320 20321 /** Execute drawArrays for single vertex 20322 * 20323 * @param test_case_index Index of test case 20324 * 20325 * @return true if proper error is reported 20326 **/ 20327 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 20328 { 20329 const Functions& gl = m_context.getRenderContext().getFunctions(); 20330 bool result = true; 20331 20332 /* Draw */ 20333 gl.disable(GL_RASTERIZER_DISCARD); 20334 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 20335 20336 gl.beginTransformFeedback(GL_POINTS); 20337 GLenum error = gl.getError(); 20338 switch (test_case_index) 20339 { 20340 case VALID: 20341 if (GL_NO_ERROR != error) 20342 { 20343 gl.endTransformFeedback(); 20344 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback"); 20345 } 20346 20347 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 20348 error = gl.getError(); 20349 20350 gl.endTransformFeedback(); 20351 GLU_EXPECT_NO_ERROR(error, "DrawArrays"); 20352 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 20353 20354 break; 20355 20356 case FIRST_MISSING: 20357 if (GL_NO_ERROR != error) 20358 { 20359 gl.endTransformFeedback(); 20360 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback"); 20361 } 20362 20363 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 20364 error = gl.getError(); 20365 20366 gl.endTransformFeedback(); 20367 GLU_EXPECT_NO_ERROR(error, "DrawArrays"); 20368 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 20369 20370 break; 20371 20372 case SECOND_MISSING: 20373 if (GL_NO_ERROR == error) 20374 { 20375 gl.endTransformFeedback(); 20376 } 20377 20378 if (GL_INVALID_OPERATION != error) 20379 { 20380 m_context.getTestContext().getLog() 20381 << tcu::TestLog::Message << "XFB at index 1, that is declared as empty, is missing. It was expected " 20382 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: " 20383 << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 20384 20385 result = false; 20386 } 20387 20388 break; 20389 } 20390 20391 /* Done */ 20392 return result; 20393 } 20394 20395 /** Get descriptors of buffers necessary for test 20396 * 20397 * @param test_case_index Index of test case 20398 * @param out_descriptors Descriptors of buffers used by test 20399 **/ 20400 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint test_case_index, 20401 bufferDescriptor::Vector& out_descriptors) 20402 { 20403 switch (test_case_index) 20404 { 20405 case VALID: 20406 { 20407 /* Test needs single uniform and two xfbs */ 20408 out_descriptors.resize(3); 20409 20410 /* Get references */ 20411 bufferDescriptor& uniform = out_descriptors[0]; 20412 bufferDescriptor& xfb_0 = out_descriptors[1]; 20413 bufferDescriptor& xfb_1 = out_descriptors[2]; 20414 20415 /* Index */ 20416 uniform.m_index = 0; 20417 xfb_0.m_index = 0; 20418 xfb_1.m_index = 1; 20419 20420 /* Target */ 20421 uniform.m_target = Utils::Buffer::Uniform; 20422 xfb_0.m_target = Utils::Buffer::Transform_feedback; 20423 xfb_1.m_target = Utils::Buffer::Transform_feedback; 20424 20425 /* Data */ 20426 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20427 20428 /* Data, contents are the same as no modification is expected */ 20429 xfb_0.m_initial_data.resize(m_stride); 20430 xfb_0.m_expected_data.resize(m_stride); 20431 20432 for (GLuint i = 0; i < m_stride; ++i) 20433 { 20434 xfb_0.m_initial_data[0] = (glw::GLubyte)i; 20435 xfb_0.m_expected_data[0] = (glw::GLubyte)i; 20436 } 20437 20438 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20439 xfb_1.m_expected_data = uniform.m_initial_data; 20440 } 20441 20442 break; 20443 20444 case FIRST_MISSING: 20445 { 20446 /* Test needs single uniform and two xfbs */ 20447 out_descriptors.resize(2); 20448 20449 /* Get references */ 20450 bufferDescriptor& uniform = out_descriptors[0]; 20451 bufferDescriptor& xfb_1 = out_descriptors[1]; 20452 20453 /* Index */ 20454 uniform.m_index = 0; 20455 xfb_1.m_index = 1; 20456 20457 /* Target */ 20458 uniform.m_target = Utils::Buffer::Uniform; 20459 xfb_1.m_target = Utils::Buffer::Transform_feedback; 20460 20461 /* Data */ 20462 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20463 20464 /* Data, contents are the same as no modification is expected */ 20465 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20466 xfb_1.m_expected_data = uniform.m_initial_data; 20467 } 20468 20469 break; 20470 20471 case SECOND_MISSING: 20472 { 20473 /* Test needs single uniform and two xfbs */ 20474 out_descriptors.resize(2); 20475 20476 /* Get references */ 20477 bufferDescriptor& uniform = out_descriptors[0]; 20478 bufferDescriptor& xfb_0 = out_descriptors[1]; 20479 20480 /* Index */ 20481 uniform.m_index = 0; 20482 xfb_0.m_index = 0; 20483 20484 /* Target */ 20485 uniform.m_target = Utils::Buffer::Uniform; 20486 xfb_0.m_target = Utils::Buffer::Transform_feedback; 20487 20488 /* Data */ 20489 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20490 20491 /* Draw call will not be executed, contents does not matter */ 20492 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20493 } 20494 20495 break; 20496 } 20497 } 20498 20499 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings 20500 * 20501 * @param ignored 20502 * @param captured_varyings Vector of varying names to be captured 20503 **/ 20504 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */, 20505 Utils::Program::NameVector& captured_varyings, 20506 GLint* xfb_components) 20507 { 20508 captured_varyings.push_back("gs_fs1"); 20509 captured_varyings.push_back("gs_fs2"); 20510 *xfb_components = 4; 20511 } 20512 20513 /** Get body of main function for given shader stage 20514 * 20515 * @param ignored 20516 * @param stage Shader stage 20517 * @param out_assignments Set to empty 20518 * @param out_calculations Set to empty 20519 **/ 20520 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 20521 std::string& out_assignments, std::string& out_calculations) 20522 { 20523 out_calculations = ""; 20524 20525 static const GLchar* gs = " gs_fs1 = -uni_gs;\n" 20526 " gs_fs2 = uni_gs;\n"; 20527 static const GLchar* fs = " fs_out = vec4(gs_fs2);\n"; 20528 20529 const GLchar* assignments = ""; 20530 switch (stage) 20531 { 20532 case Utils::Shader::FRAGMENT: 20533 assignments = fs; 20534 break; 20535 case Utils::Shader::GEOMETRY: 20536 assignments = gs; 20537 break; 20538 default: 20539 break; 20540 } 20541 20542 out_assignments = assignments; 20543 } 20544 20545 /** Get interface of shader 20546 * 20547 * @param ignored 20548 * @param stage Shader stage 20549 * @param out_interface Set to "" 20550 **/ 20551 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 20552 std::string& out_interface) 20553 { 20554 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_stride = 64) out vec4 gs_fs1;\n" 20555 "layout (xfb_buffer = 1, xfb_offset = 0) out vec4 gs_fs2;\n" 20556 "\n" 20557 "layout(binding = 0) uniform gs_block {\n" 20558 " vec4 uni_gs;\n" 20559 "};\n"; 20560 static const GLchar* fs = "in vec4 gs_fs2;\n" 20561 "out vec4 fs_out;\n"; 20562 20563 switch (stage) 20564 { 20565 case Utils::Shader::FRAGMENT: 20566 out_interface = fs; 20567 break; 20568 case Utils::Shader::GEOMETRY: 20569 out_interface = gs; 20570 break; 20571 default: 20572 out_interface = ""; 20573 return; 20574 } 20575 } 20576 20577 /** Returns buffer details in human readable form. 20578 * 20579 * @param test_case_index Index of test case 20580 * 20581 * @return Case description 20582 **/ 20583 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index) 20584 { 20585 std::string result; 20586 20587 switch (test_case_index) 20588 { 20589 case VALID: 20590 result = "Valid case"; 20591 break; 20592 case FIRST_MISSING: 20593 result = "Missing xfb at index 0"; 20594 break; 20595 case SECOND_MISSING: 20596 result = "Missing xfb at index 1"; 20597 break; 20598 default: 20599 TCU_FAIL("Invalid enum"); 20600 } 20601 20602 return result; 20603 } 20604 20605 /** Get number of test cases 20606 * 20607 * @return 2 20608 **/ 20609 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber() 20610 { 20611 return 3; 20612 } 20613 20614 /** Constructor 20615 * 20616 * @param context Test framework context 20617 **/ 20618 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context& context) 20619 : NegativeTestBase(context, "xfb_too_small_stride", 20620 "Test verifies that compiler reports error when xfb_stride sets not enough space") 20621 { 20622 } 20623 20624 /** Source for given test case and stage 20625 * 20626 * @param test_case_index Index of test case 20627 * @param stage Shader stage 20628 * 20629 * @return Shader source 20630 **/ 20631 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 20632 { 20633 static const GLchar* array_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n" 20634 "\n" 20635 "layout (xfb_offset = 16) out vec4 gohanARRAY[4];\n"; 20636 static const GLchar* block_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n" 20637 "\n" 20638 "layout (xfb_offset = 0) out Goku {\n" 20639 " vec4 gohan;\n" 20640 " vec4 goten;\n" 20641 " vec4 chichi;\n" 20642 "} gokuARRAY;\n"; 20643 static const GLchar* offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n" 20644 "\n" 20645 "layout (xfb_offset = 32) out vec4 gohanARRAY;\n"; 20646 // The test considers gohan overflows the buffer 0, but according to spec, it is valid to declare the variable with qualifier "layout (xfb_offset = 16, xfb_stride = 32) out vec4 gohan;" 20647 // To make the shader failed to compile, change xfb_stride to a value that is smaller than 32 20648 static const GLchar* stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n" 20649 "\n" 20650 "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohanARRAY;\n"; 20651 static const GLchar* array_use = " gohanINDEX[0] = result / 2;\n" 20652 " gohanINDEX[1] = result / 4;\n" 20653 " gohanINDEX[2] = result / 6;\n" 20654 " gohanINDEX[3] = result / 8;\n"; 20655 static const GLchar* block_use = " gokuINDEX.gohan = result / 2;\n" 20656 " gokuINDEX.goten = result / 4;\n" 20657 " gokuINDEX.chichi = result / 6;\n"; 20658 static const GLchar* output_use = "gohanINDEX = result / 4;\n"; 20659 static const GLchar* fs = "#version 430 core\n" 20660 "#extension GL_ARB_enhanced_layouts : require\n" 20661 "\n" 20662 "in vec4 gs_fs;\n" 20663 "out vec4 fs_out;\n" 20664 "\n" 20665 "void main()\n" 20666 "{\n" 20667 " fs_out = gs_fs;\n" 20668 "}\n" 20669 "\n"; 20670 static const GLchar* gs_tested = "#version 430 core\n" 20671 "#extension GL_ARB_enhanced_layouts : require\n" 20672 "\n" 20673 "layout(points) in;\n" 20674 "layout(triangle_strip, max_vertices = 4) out;\n" 20675 "\n" 20676 "VAR_DEFINITION" 20677 "\n" 20678 "in vec4 tes_gs[];\n" 20679 "out vec4 gs_fs;\n" 20680 "\n" 20681 "void main()\n" 20682 "{\n" 20683 " vec4 result = tes_gs[0];\n" 20684 "\n" 20685 "VARIABLE_USE" 20686 "\n" 20687 " gs_fs = result;\n" 20688 " gl_Position = vec4(-1, -1, 0, 1);\n" 20689 " EmitVertex();\n" 20690 " gs_fs = result;\n" 20691 " gl_Position = vec4(-1, 1, 0, 1);\n" 20692 " EmitVertex();\n" 20693 " gs_fs = result;\n" 20694 " gl_Position = vec4(1, -1, 0, 1);\n" 20695 " EmitVertex();\n" 20696 " gs_fs = result;\n" 20697 " gl_Position = vec4(1, 1, 0, 1);\n" 20698 " EmitVertex();\n" 20699 "}\n" 20700 "\n"; 20701 static const GLchar* tcs = "#version 430 core\n" 20702 "#extension GL_ARB_enhanced_layouts : require\n" 20703 "\n" 20704 "layout(vertices = 1) out;\n" 20705 "\n" 20706 "in vec4 vs_tcs[];\n" 20707 "out vec4 tcs_tes[];\n" 20708 "\n" 20709 "void main()\n" 20710 "{\n" 20711 "\n" 20712 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 20713 "\n" 20714 " gl_TessLevelOuter[0] = 1.0;\n" 20715 " gl_TessLevelOuter[1] = 1.0;\n" 20716 " gl_TessLevelOuter[2] = 1.0;\n" 20717 " gl_TessLevelOuter[3] = 1.0;\n" 20718 " gl_TessLevelInner[0] = 1.0;\n" 20719 " gl_TessLevelInner[1] = 1.0;\n" 20720 "}\n" 20721 "\n"; 20722 static const GLchar* tcs_tested = "#version 430 core\n" 20723 "#extension GL_ARB_enhanced_layouts : require\n" 20724 "\n" 20725 "layout(vertices = 1) out;\n" 20726 "\n" 20727 "VAR_DEFINITION" 20728 "\n" 20729 "in vec4 vs_tcs[];\n" 20730 "out vec4 tcs_tes[];\n" 20731 "\n" 20732 "void main()\n" 20733 "{\n" 20734 " vec4 result = vs_tcs[gl_InvocationID];\n" 20735 "\n" 20736 "VARIABLE_USE" 20737 "\n" 20738 " tcs_tes[gl_InvocationID] = result;\n" 20739 "\n" 20740 " gl_TessLevelOuter[0] = 1.0;\n" 20741 " gl_TessLevelOuter[1] = 1.0;\n" 20742 " gl_TessLevelOuter[2] = 1.0;\n" 20743 " gl_TessLevelOuter[3] = 1.0;\n" 20744 " gl_TessLevelInner[0] = 1.0;\n" 20745 " gl_TessLevelInner[1] = 1.0;\n" 20746 "}\n" 20747 "\n"; 20748 static const GLchar* tes_tested = "#version 430 core\n" 20749 "#extension GL_ARB_enhanced_layouts : require\n" 20750 "\n" 20751 "layout(isolines, point_mode) in;\n" 20752 "\n" 20753 "VAR_DEFINITION" 20754 "\n" 20755 "in vec4 tcs_tes[];\n" 20756 "out vec4 tes_gs;\n" 20757 "\n" 20758 "void main()\n" 20759 "{\n" 20760 " vec4 result = tcs_tes[0];\n" 20761 "\n" 20762 "VARIABLE_USE" 20763 "\n" 20764 " tes_gs += result;\n" 20765 "}\n" 20766 "\n"; 20767 static const GLchar* vs = "#version 430 core\n" 20768 "#extension GL_ARB_enhanced_layouts : require\n" 20769 "\n" 20770 "in vec4 in_vs;\n" 20771 "out vec4 vs_tcs;\n" 20772 "\n" 20773 "void main()\n" 20774 "{\n" 20775 " vs_tcs = in_vs;\n" 20776 "}\n" 20777 "\n"; 20778 static const GLchar* vs_tested = "#version 430 core\n" 20779 "#extension GL_ARB_enhanced_layouts : require\n" 20780 "\n" 20781 "VAR_DEFINITION" 20782 "\n" 20783 "in vec4 in_vs;\n" 20784 "out vec4 vs_tcs;\n" 20785 "\n" 20786 "void main()\n" 20787 "{\n" 20788 " vec4 result = in_vs;\n" 20789 "\n" 20790 "VARIABLE_USE" 20791 "\n" 20792 " vs_tcs += result;\n" 20793 "}\n" 20794 "\n"; 20795 20796 std::string source; 20797 testCase& test_case = m_test_cases[test_case_index]; 20798 20799 if (test_case.m_stage == stage) 20800 { 20801 const GLchar* array = ""; 20802 const GLchar* index = ""; 20803 size_t position = 0; 20804 size_t temp; 20805 const GLchar* var_definition = 0; 20806 const GLchar* var_use = 0; 20807 20808 switch (test_case.m_case) 20809 { 20810 case OFFSET: 20811 var_definition = offset_var_definition; 20812 var_use = output_use; 20813 break; 20814 case STRIDE: 20815 var_definition = stride_var_definition; 20816 var_use = output_use; 20817 break; 20818 case BLOCK: 20819 var_definition = block_var_definition; 20820 var_use = block_use; 20821 break; 20822 case ARRAY: 20823 var_definition = array_var_definition; 20824 var_use = array_use; 20825 break; 20826 default: 20827 TCU_FAIL("Invalid enum"); 20828 } 20829 20830 switch (stage) 20831 { 20832 case Utils::Shader::GEOMETRY: 20833 source = gs_tested; 20834 array = "[]"; 20835 index = "[0]"; 20836 break; 20837 case Utils::Shader::TESS_CTRL: 20838 source = tcs_tested; 20839 array = "[]"; 20840 index = "[gl_InvocationID]"; 20841 break; 20842 case Utils::Shader::TESS_EVAL: 20843 source = tes_tested; 20844 array = "[]"; 20845 index = "[0]"; 20846 break; 20847 case Utils::Shader::VERTEX: 20848 source = vs_tested; 20849 break; 20850 default: 20851 TCU_FAIL("Invalid enum"); 20852 } 20853 20854 temp = position; 20855 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 20856 position = temp; 20857 Utils::replaceToken("ARRAY", position, array, source); 20858 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 20859 20860 Utils::replaceAllTokens("INDEX", index, source); 20861 } 20862 else 20863 { 20864 switch (test_case.m_stage) 20865 { 20866 case Utils::Shader::GEOMETRY: 20867 switch (stage) 20868 { 20869 case Utils::Shader::FRAGMENT: 20870 source = fs; 20871 break; 20872 case Utils::Shader::VERTEX: 20873 source = vs; 20874 break; 20875 default: 20876 source = ""; 20877 } 20878 break; 20879 case Utils::Shader::TESS_CTRL: 20880 switch (stage) 20881 { 20882 case Utils::Shader::FRAGMENT: 20883 source = fs; 20884 break; 20885 case Utils::Shader::VERTEX: 20886 source = vs; 20887 break; 20888 default: 20889 source = ""; 20890 } 20891 break; 20892 case Utils::Shader::TESS_EVAL: 20893 switch (stage) 20894 { 20895 case Utils::Shader::FRAGMENT: 20896 source = fs; 20897 break; 20898 case Utils::Shader::TESS_CTRL: 20899 source = tcs; 20900 break; 20901 case Utils::Shader::VERTEX: 20902 source = vs; 20903 break; 20904 default: 20905 source = ""; 20906 } 20907 break; 20908 case Utils::Shader::VERTEX: 20909 switch (stage) 20910 { 20911 case Utils::Shader::FRAGMENT: 20912 source = fs; 20913 break; 20914 default: 20915 source = ""; 20916 } 20917 break; 20918 default: 20919 TCU_FAIL("Invalid enum"); 20920 break; 20921 } 20922 } 20923 20924 return source; 20925 } 20926 20927 /** Get description of test case 20928 * 20929 * @param test_case_index Index of test case 20930 * 20931 * @return Test case description 20932 **/ 20933 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index) 20934 { 20935 std::stringstream stream; 20936 testCase& test_case = m_test_cases[test_case_index]; 20937 20938 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: "; 20939 20940 switch (test_case.m_case) 20941 { 20942 case OFFSET: 20943 stream << "buffer stride: 40, vec4 offset: 32"; 20944 break; 20945 case STRIDE: 20946 stream << "buffer stride: 32, vec4 off 16 stride: 32"; 20947 break; 20948 case BLOCK: 20949 stream << "buffer stride: 32, block 3xvec4 offset 0"; 20950 break; 20951 case ARRAY: 20952 stream << "buffer stride: 32, vec4[4] offset 16"; 20953 break; 20954 default: 20955 TCU_FAIL("Invalid enum"); 20956 } 20957 20958 return stream.str(); 20959 } 20960 20961 /** Get number of test cases 20962 * 20963 * @return Number of test cases 20964 **/ 20965 GLuint XFBTooSmallStrideTest::getTestCaseNumber() 20966 { 20967 return static_cast<GLuint>(m_test_cases.size()); 20968 } 20969 20970 /** Selects if "compute" stage is relevant for test 20971 * 20972 * @param ignored 20973 * 20974 * @return false 20975 **/ 20976 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */) 20977 { 20978 return false; 20979 } 20980 20981 /** Prepare all test cases 20982 * 20983 **/ 20984 void XFBTooSmallStrideTest::testInit() 20985 { 20986 for (GLuint c = 0; c < CASE_MAX; ++c) 20987 { 20988 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 20989 { 20990 /* 20991 It is invalid to define transform feedback output in TCS, according to spec: 20992 The data captured in transform feedback mode depends on the active programs on each of the shader stages. 20993 If a program is active for the geometry shader stage, transform feedback captures the vertices of each 20994 primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation 20995 shader stage, transform feedback captures each primitive produced by the tessellation primitive generator, 20996 whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures 20997 each primitive processed by the vertex shader. 20998 */ 20999 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 21000 (Utils::Shader::FRAGMENT == stage)) 21001 { 21002 continue; 21003 } 21004 21005 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage }; 21006 21007 m_test_cases.push_back(test_case); 21008 } 21009 } 21010 } 21011 21012 /** Constructor 21013 * 21014 * @param context Test framework context 21015 **/ 21016 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context& context) 21017 : NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected") 21018 { 21019 } 21020 21021 /** Source for given test case and stage 21022 * 21023 * @param test_case_index Index of test case 21024 * @param stage Shader stage 21025 * 21026 * @return Shader source 21027 **/ 21028 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 21029 { 21030 static const GLchar* invalid_var_definition = 21031 "const uint type_size = SIZE;\n" 21032 "\n" 21033 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n" 21034 "layout (xfb_offset = type_size) out TYPE vegetaARRAY;\n"; 21035 static const GLchar* valid_var_definition = 21036 "const uint type_size = SIZE;\n" 21037 "\n" 21038 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n"; 21039 static const GLchar* invalid_use = " gokuINDEX = TYPE(1);\n" 21040 " vegetaINDEX = TYPE(0);\n" 21041 " if (vec4(0) == result)\n" 21042 " {\n" 21043 " gokuINDEX = TYPE(0);\n" 21044 " vegetaINDEX = TYPE(1);\n" 21045 " }\n"; 21046 static const GLchar* valid_use = " gokuINDEX = TYPE(1);\n" 21047 " if (vec4(0) == result)\n" 21048 " {\n" 21049 " gokuINDEX = TYPE(0);\n" 21050 " }\n"; 21051 static const GLchar* fs = "#version 430 core\n" 21052 "#extension GL_ARB_enhanced_layouts : require\n" 21053 "\n" 21054 "in vec4 any_fs;\n" 21055 "out vec4 fs_out;\n" 21056 "\n" 21057 "void main()\n" 21058 "{\n" 21059 " fs_out = any_fs;\n" 21060 "}\n" 21061 "\n"; 21062 static const GLchar* gs_tested = "#version 430 core\n" 21063 "#extension GL_ARB_enhanced_layouts : require\n" 21064 "\n" 21065 "layout(points) in;\n" 21066 "layout(triangle_strip, max_vertices = 4) out;\n" 21067 "\n" 21068 "VAR_DEFINITION" 21069 "\n" 21070 "in vec4 vs_any[];\n" 21071 "out vec4 any_fs;\n" 21072 "\n" 21073 "void main()\n" 21074 "{\n" 21075 " vec4 result = vs_any[0];\n" 21076 "\n" 21077 "VARIABLE_USE" 21078 "\n" 21079 " any_fs = result;\n" 21080 " gl_Position = vec4(-1, -1, 0, 1);\n" 21081 " EmitVertex();\n" 21082 " any_fs = result;\n" 21083 " gl_Position = vec4(-1, 1, 0, 1);\n" 21084 " EmitVertex();\n" 21085 " any_fs = result;\n" 21086 " gl_Position = vec4(1, -1, 0, 1);\n" 21087 " EmitVertex();\n" 21088 " any_fs = result;\n" 21089 " gl_Position = vec4(1, 1, 0, 1);\n" 21090 " EmitVertex();\n" 21091 "}\n" 21092 "\n"; 21093 static const GLchar* tcs = "#version 430 core\n" 21094 "#extension GL_ARB_enhanced_layouts : require\n" 21095 "\n" 21096 "layout(vertices = 1) out;\n" 21097 "\n" 21098 "in vec4 vs_any[];\n" 21099 "out vec4 tcs_tes[];\n" 21100 "\n" 21101 "void main()\n" 21102 "{\n" 21103 "\n" 21104 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n" 21105 "\n" 21106 " gl_TessLevelOuter[0] = 1.0;\n" 21107 " gl_TessLevelOuter[1] = 1.0;\n" 21108 " gl_TessLevelOuter[2] = 1.0;\n" 21109 " gl_TessLevelOuter[3] = 1.0;\n" 21110 " gl_TessLevelInner[0] = 1.0;\n" 21111 " gl_TessLevelInner[1] = 1.0;\n" 21112 "}\n" 21113 "\n"; 21114 static const GLchar* tcs_tested = "#version 430 core\n" 21115 "#extension GL_ARB_enhanced_layouts : require\n" 21116 "\n" 21117 "layout(vertices = 1) out;\n" 21118 "\n" 21119 "VAR_DEFINITION" 21120 "\n" 21121 "in vec4 vs_any[];\n" 21122 "out vec4 any_fs[];\n" 21123 "\n" 21124 "void main()\n" 21125 "{\n" 21126 " vec4 result = vs_any[gl_InvocationID];\n" 21127 "\n" 21128 "VARIABLE_USE" 21129 "\n" 21130 " any_fs[gl_InvocationID] = result;\n" 21131 "\n" 21132 " gl_TessLevelOuter[0] = 1.0;\n" 21133 " gl_TessLevelOuter[1] = 1.0;\n" 21134 " gl_TessLevelOuter[2] = 1.0;\n" 21135 " gl_TessLevelOuter[3] = 1.0;\n" 21136 " gl_TessLevelInner[0] = 1.0;\n" 21137 " gl_TessLevelInner[1] = 1.0;\n" 21138 "}\n" 21139 "\n"; 21140 static const GLchar* tes_tested = "#version 430 core\n" 21141 "#extension GL_ARB_enhanced_layouts : require\n" 21142 "\n" 21143 "layout(isolines, point_mode) in;\n" 21144 "\n" 21145 "VAR_DEFINITION" 21146 "\n" 21147 "in vec4 tcs_tes[];\n" 21148 "out vec4 any_fs;\n" 21149 "\n" 21150 "void main()\n" 21151 "{\n" 21152 " vec4 result = tcs_tes[0];\n" 21153 "\n" 21154 "VARIABLE_USE" 21155 "\n" 21156 " any_fs = result;\n" 21157 "}\n" 21158 "\n"; 21159 static const GLchar* vs = "#version 430 core\n" 21160 "#extension GL_ARB_enhanced_layouts : require\n" 21161 "\n" 21162 "in vec4 in_vs;\n" 21163 "out vec4 vs_any;\n" 21164 "\n" 21165 "void main()\n" 21166 "{\n" 21167 " vs_any = in_vs;\n" 21168 "}\n" 21169 "\n"; 21170 static const GLchar* vs_tested = "#version 430 core\n" 21171 "#extension GL_ARB_enhanced_layouts : require\n" 21172 "\n" 21173 "VAR_DEFINITION" 21174 "\n" 21175 "in vec4 in_vs;\n" 21176 "out vec4 any_fs;\n" 21177 "\n" 21178 "void main()\n" 21179 "{\n" 21180 " vec4 result = in_vs;\n" 21181 "\n" 21182 "VARIABLE_USE" 21183 "\n" 21184 " any_fs = result;\n" 21185 "}\n" 21186 "\n"; 21187 21188 std::string source; 21189 testCase& test_case = m_test_cases[test_case_index]; 21190 21191 if (test_case.m_stage == stage) 21192 { 21193 const GLchar* array = ""; 21194 GLchar buffer[16]; 21195 const GLchar* index = ""; 21196 size_t position = 0; 21197 size_t temp; 21198 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 21199 const GLchar* var_definition = 0; 21200 const GLchar* var_use = 0; 21201 21202 sprintf(buffer, "%d", test_case.m_type.GetSize()); 21203 21204 switch (test_case.m_case) 21205 { 21206 case VALID: 21207 var_definition = valid_var_definition; 21208 var_use = valid_use; 21209 break; 21210 case INVALID: 21211 var_definition = invalid_var_definition; 21212 var_use = invalid_use; 21213 break; 21214 default: 21215 TCU_FAIL("Invalid enum"); 21216 } 21217 21218 switch (stage) 21219 { 21220 case Utils::Shader::GEOMETRY: 21221 source = gs_tested; 21222 array = "[1]"; 21223 index = "[0]"; 21224 break; 21225 case Utils::Shader::TESS_CTRL: 21226 source = tcs_tested; 21227 array = "[1]"; 21228 index = "[gl_InvocationID]"; 21229 break; 21230 case Utils::Shader::TESS_EVAL: 21231 source = tes_tested; 21232 array = "[1]"; 21233 index = "[0]"; 21234 break; 21235 case Utils::Shader::VERTEX: 21236 source = vs_tested; 21237 break; 21238 default: 21239 TCU_FAIL("Invalid enum"); 21240 } 21241 21242 temp = position; 21243 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 21244 position = temp; 21245 Utils::replaceToken("SIZE", position, buffer, source); 21246 Utils::replaceToken("ARRAY", position, array, source); 21247 if (INVALID == test_case.m_case) 21248 { 21249 Utils::replaceToken("ARRAY", position, array, source); 21250 } 21251 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 21252 21253 Utils::replaceAllTokens("TYPE", type_name, source); 21254 Utils::replaceAllTokens("INDEX", index, source); 21255 } 21256 else 21257 { 21258 switch (test_case.m_stage) 21259 { 21260 case Utils::Shader::GEOMETRY: 21261 switch (stage) 21262 { 21263 case Utils::Shader::FRAGMENT: 21264 source = fs; 21265 break; 21266 case Utils::Shader::VERTEX: 21267 source = vs; 21268 break; 21269 default: 21270 source = ""; 21271 } 21272 break; 21273 case Utils::Shader::TESS_CTRL: 21274 switch (stage) 21275 { 21276 case Utils::Shader::FRAGMENT: 21277 source = fs; 21278 break; 21279 case Utils::Shader::VERTEX: 21280 source = vs; 21281 break; 21282 default: 21283 source = ""; 21284 } 21285 break; 21286 case Utils::Shader::TESS_EVAL: 21287 switch (stage) 21288 { 21289 case Utils::Shader::FRAGMENT: 21290 source = fs; 21291 break; 21292 case Utils::Shader::TESS_CTRL: 21293 source = tcs; 21294 break; 21295 case Utils::Shader::VERTEX: 21296 source = vs; 21297 break; 21298 default: 21299 source = ""; 21300 } 21301 break; 21302 case Utils::Shader::VERTEX: 21303 switch (stage) 21304 { 21305 case Utils::Shader::FRAGMENT: 21306 source = fs; 21307 break; 21308 default: 21309 source = ""; 21310 } 21311 break; 21312 default: 21313 TCU_FAIL("Invalid enum"); 21314 break; 21315 } 21316 } 21317 21318 return source; 21319 } 21320 21321 /** Get description of test case 21322 * 21323 * @param test_case_index Index of test case 21324 * 21325 * @return Test case description 21326 **/ 21327 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index) 21328 { 21329 std::stringstream stream; 21330 testCase& test_case = m_test_cases[test_case_index]; 21331 21332 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 21333 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: "; 21334 21335 switch (test_case.m_case) 21336 { 21337 case VALID: 21338 stream << "valid"; 21339 break; 21340 case INVALID: 21341 stream << "invalid"; 21342 break; 21343 default: 21344 TCU_FAIL("Invalid enum"); 21345 } 21346 21347 return stream.str(); 21348 } 21349 21350 /** Get number of test cases 21351 * 21352 * @return Number of test cases 21353 **/ 21354 GLuint XFBVariableStrideTest::getTestCaseNumber() 21355 { 21356 return static_cast<GLuint>(m_test_cases.size()); 21357 } 21358 21359 /** Selects if "compute" stage is relevant for test 21360 * 21361 * @param ignored 21362 * 21363 * @return false 21364 **/ 21365 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */) 21366 { 21367 return false; 21368 } 21369 21370 /** Selects if compilation failure is expected result 21371 * 21372 * @param test_case_index Index of test case 21373 * 21374 * @return true 21375 **/ 21376 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index) 21377 { 21378 testCase& test_case = m_test_cases[test_case_index]; 21379 21380 return (INVALID == test_case.m_case); 21381 } 21382 21383 /** Prepare all test cases 21384 * 21385 **/ 21386 void XFBVariableStrideTest::testInit() 21387 { 21388 const GLuint n_types = getTypesNumber(); 21389 21390 for (GLuint i = 0; i < n_types; ++i) 21391 { 21392 const Utils::Type& type = getType(i); 21393 21394 /* 21395 Some of the cases are declared as following are considered as invalid, 21396 but accoring to spec, the following declaration is valid: shaders in the 21397 transform feedback capturing mode have an initial global default of layout(xfb_buffer=0) out, 21398 so for the first variable's declaration, the xfb_stride = 16 is applied on buffer 0, for the 21399 second variable, its buffer is also inherited from global buffer 0, and its offset does not overflows 21400 the stride. 21401 21402 The xfb_stride is the memory width of given buffer, not for variable even though xfb_stride 21403 is declared on the variable. It seems that the writter of this case misunderstand the concept of 21404 xfb_stride, because spec describes that xfb_stride can be declared multiple times for the same buffer, 21405 it is a compile or link-time error to have different values specified for the stride for the same buffer. 21406 21407 int type_size = 8; 21408 layout (xfb_offset = 0, xfb_stride = 2 * type_size) out double goku; 21409 layout (xfb_offset = type_size) out double vegeta; 21410 */ 21411 // all the shaders are valid, so remove the following loop(it contains CASE_MAX is enum of valid and invalid) 21412 // for (GLuint c = 0; c < CASE_MAX; ++c) 21413 { 21414 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 21415 { 21416 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 21417 (Utils::Shader::FRAGMENT == stage)) 21418 { 21419 continue; 21420 } 21421 21422 testCase test_case = { (CASES)VALID, (Utils::Shader::STAGES)stage, type }; 21423 21424 m_test_cases.push_back(test_case); 21425 } 21426 } 21427 } 21428 } 21429 21430 /** Constructor 21431 * 21432 * @param context Test framework context 21433 **/ 21434 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context& context) 21435 : TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks") 21436 { 21437 } 21438 21439 /** Source for given test case and stage 21440 * 21441 * @param test_case_index Index of test case 21442 * @param stage Shader stage 21443 * 21444 * @return Shader source 21445 **/ 21446 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 21447 { 21448 static const GLchar* var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n" 21449 " vec4 gohan;\n" 21450 " vec4 goten;\n" 21451 " vec4 chichi;\n" 21452 "} gokuARRAY;\n"; 21453 static const GLchar* var_use = " gokuINDEX.gohan = vec4(1, 0, 0, 0);\n" 21454 " gokuINDEX.goten = vec4(0, 0, 1, 0);\n" 21455 " gokuINDEX.chichi = vec4(0, 1, 0, 0);\n" 21456 " if (vec4(0) == result)\n" 21457 " {\n" 21458 " gokuINDEX.gohan = vec4(0, 1, 1, 1);\n" 21459 " gokuINDEX.goten = vec4(1, 1, 0, 1);\n" 21460 " gokuINDEX.chichi = vec4(1, 0, 1, 1);\n" 21461 " }\n"; 21462 static const GLchar* gs_tested = 21463 "#version 430 core\n" 21464 "#extension GL_ARB_enhanced_layouts : require\n" 21465 "\n" 21466 "layout(points) in;\n" 21467 "layout(triangle_strip, max_vertices = 4) out;\n" 21468 "\n" 21469 "VAR_DEFINITION" 21470 "\n" 21471 "out gl_PerVertex \n" 21472 "{ \n" 21473 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode 21474 "}; \n" 21475 "in vec4 tes_gs[];\n" 21476 "out vec4 gs_fs;\n" 21477 "\n" 21478 "void main()\n" 21479 "{\n" 21480 " vec4 result = tes_gs[0];\n" 21481 "\n" 21482 "VARIABLE_USE" 21483 "\n" 21484 " gs_fs = result;\n" 21485 " gl_Position = vec4(-1, -1, 0, 1);\n" 21486 " EmitVertex();\n" 21487 " gs_fs = result;\n" 21488 " gl_Position = vec4(-1, 1, 0, 1);\n" 21489 " EmitVertex();\n" 21490 " gs_fs = result;\n" 21491 " gl_Position = vec4(1, -1, 0, 1);\n" 21492 " EmitVertex();\n" 21493 " gs_fs = result;\n" 21494 " gl_Position = vec4(1, 1, 0, 1);\n" 21495 " EmitVertex();\n" 21496 "}\n" 21497 "\n"; 21498 static const GLchar* tcs = "#version 430 core\n" 21499 "#extension GL_ARB_enhanced_layouts : require\n" 21500 "\n" 21501 "layout(vertices = 1) out;\n" 21502 "\n" 21503 "in vec4 vs_tcs[];\n" 21504 "out vec4 tcs_tes[];\n" 21505 "\n" 21506 "void main()\n" 21507 "{\n" 21508 "\n" 21509 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 21510 "\n" 21511 " gl_TessLevelOuter[0] = 1.0;\n" 21512 " gl_TessLevelOuter[1] = 1.0;\n" 21513 " gl_TessLevelOuter[2] = 1.0;\n" 21514 " gl_TessLevelOuter[3] = 1.0;\n" 21515 " gl_TessLevelInner[0] = 1.0;\n" 21516 " gl_TessLevelInner[1] = 1.0;\n" 21517 "}\n" 21518 "\n"; 21519 #if 0 21520 static const GLchar* tcs_tested = 21521 "#version 430 core\n" 21522 "#extension GL_ARB_enhanced_layouts : require\n" 21523 "\n" 21524 "layout(vertices = 1) out;\n" 21525 "\n" 21526 "VAR_DEFINITION" 21527 "\n" 21528 "in vec4 vs_tcs[];\n" 21529 "out vec4 tcs_tes[];\n" 21530 "\n" 21531 "void main()\n" 21532 "{\n" 21533 " vec4 result = vs_tcs[gl_InvocationID];\n" 21534 "\n" 21535 "VARIABLE_USE" 21536 "\n" 21537 " tcs_tes[gl_InvocationID] = result;\n" 21538 "\n" 21539 " gl_TessLevelOuter[0] = 1.0;\n" 21540 " gl_TessLevelOuter[1] = 1.0;\n" 21541 " gl_TessLevelOuter[2] = 1.0;\n" 21542 " gl_TessLevelOuter[3] = 1.0;\n" 21543 " gl_TessLevelInner[0] = 1.0;\n" 21544 " gl_TessLevelInner[1] = 1.0;\n" 21545 "}\n" 21546 "\n"; 21547 #endif 21548 static const GLchar* tes_tested = "#version 430 core\n" 21549 "#extension GL_ARB_enhanced_layouts : require\n" 21550 "\n" 21551 "layout(isolines, point_mode) in;\n" 21552 "\n" 21553 "VAR_DEFINITION" 21554 "\n" 21555 "in vec4 tcs_tes[];\n" 21556 "out vec4 tes_gs;\n" 21557 "\n" 21558 "void main()\n" 21559 "{\n" 21560 " vec4 result = tcs_tes[0];\n" 21561 "\n" 21562 "VARIABLE_USE" 21563 "\n" 21564 " tes_gs += result;\n" 21565 "}\n" 21566 "\n"; 21567 static const GLchar* vs = "#version 430 core\n" 21568 "#extension GL_ARB_enhanced_layouts : require\n" 21569 "\n" 21570 "in vec4 in_vs;\n" 21571 "out vec4 vs_tcs;\n" 21572 "out vec4 tes_gs;\n" 21573 "\n" 21574 "void main()\n" 21575 "{\n" 21576 " vs_tcs = tes_gs = in_vs;\n" 21577 "}\n" 21578 "\n"; 21579 static const GLchar* vs_tested = "#version 430 core\n" 21580 "#extension GL_ARB_enhanced_layouts : require\n" 21581 "\n" 21582 "VAR_DEFINITION" 21583 "\n" 21584 "in vec4 in_vs;\n" 21585 "out vec4 vs_tcs;\n" 21586 "\n" 21587 "void main()\n" 21588 "{\n" 21589 " vec4 result = in_vs;\n" 21590 "\n" 21591 "VARIABLE_USE" 21592 "\n" 21593 " vs_tcs += result;\n" 21594 "}\n" 21595 "\n"; 21596 21597 std::string source; 21598 Utils::Shader::STAGES test_case = m_test_cases[test_case_index]; 21599 21600 if (test_case == stage) 21601 { 21602 const GLchar* array = ""; 21603 const GLchar* index = ""; 21604 size_t position = 0; 21605 size_t temp; 21606 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73) 21607 // change array = "[]" to "[1]" 21608 switch (stage) 21609 { 21610 case Utils::Shader::GEOMETRY: 21611 source = gs_tested; 21612 array = "[1]"; 21613 index = "[0]"; 21614 break; 21615 /* 21616 It is invalid to define transform feedback output in HS 21617 */ 21618 #if 0 21619 case Utils::Shader::TESS_CTRL: 21620 source = tcs_tested; 21621 array = "[]"; 21622 index = "[gl_InvocationID]"; 21623 break; 21624 #endif 21625 case Utils::Shader::TESS_EVAL: 21626 source = tes_tested; 21627 array = "[1]"; 21628 index = "[0]"; 21629 break; 21630 case Utils::Shader::VERTEX: 21631 source = vs_tested; 21632 break; 21633 default: 21634 TCU_FAIL("Invalid enum"); 21635 } 21636 21637 temp = position; 21638 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 21639 position = temp; 21640 Utils::replaceToken("ARRAY", position, array, source); 21641 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 21642 21643 Utils::replaceAllTokens("INDEX", index, source); 21644 } 21645 else 21646 { 21647 switch (test_case) 21648 { 21649 case Utils::Shader::GEOMETRY: 21650 switch (stage) 21651 { 21652 case Utils::Shader::VERTEX: 21653 source = vs; 21654 break; 21655 default: 21656 source = ""; 21657 } 21658 break; 21659 case Utils::Shader::TESS_CTRL: 21660 switch (stage) 21661 { 21662 case Utils::Shader::VERTEX: 21663 source = vs; 21664 break; 21665 default: 21666 source = ""; 21667 } 21668 break; 21669 case Utils::Shader::TESS_EVAL: 21670 switch (stage) 21671 { 21672 case Utils::Shader::TESS_CTRL: 21673 source = tcs; 21674 break; 21675 case Utils::Shader::VERTEX: 21676 source = vs; 21677 break; 21678 default: 21679 source = ""; 21680 } 21681 break; 21682 case Utils::Shader::VERTEX: 21683 source = ""; 21684 break; 21685 default: 21686 TCU_FAIL("Invalid enum"); 21687 break; 21688 } 21689 } 21690 21691 return source; 21692 } 21693 21694 /** Get description of test case 21695 * 21696 * @param test_case_index Index of test case 21697 * 21698 * @return Test case description 21699 **/ 21700 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index) 21701 { 21702 std::stringstream stream; 21703 21704 stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]); 21705 21706 return stream.str(); 21707 } 21708 21709 /** Get number of test cases 21710 * 21711 * @return Number of test cases 21712 **/ 21713 GLuint XFBBlockStrideTest::getTestCaseNumber() 21714 { 21715 return static_cast<GLuint>(m_test_cases.size()); 21716 } 21717 21718 /** Inspects program for xfb stride 21719 * 21720 * @param program Program to query 21721 * 21722 * @return true if query results match expected values, false otherwise 21723 **/ 21724 bool XFBBlockStrideTest::inspectProgram(Utils::Program& program) 21725 { 21726 GLint stride = 0; 21727 21728 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 21729 1 /* buf_size */, &stride); 21730 21731 return (128 == stride); 21732 } 21733 21734 /** Runs test case 21735 * 21736 * @param test_case_index Id of test case 21737 * 21738 * @return true if test case pass, false otherwise 21739 **/ 21740 bool XFBBlockStrideTest::testCase(GLuint test_case_index) 21741 { 21742 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY); 21743 Utils::Program program(m_context); 21744 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL); 21745 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL); 21746 bool test_case_result = true; 21747 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX); 21748 21749 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */); 21750 21751 test_case_result = inspectProgram(program); 21752 21753 return test_case_result; 21754 } 21755 21756 /** Prepare all test cases 21757 * 21758 **/ 21759 void XFBBlockStrideTest::testInit() 21760 { 21761 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 21762 { 21763 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 21764 (Utils::Shader::FRAGMENT == stage)) 21765 { 21766 continue; 21767 } 21768 21769 m_test_cases.push_back((Utils::Shader::STAGES)stage); 21770 } 21771 } 21772 21773 /** Constructor 21774 * 21775 * @param context Test context 21776 **/ 21777 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context& context) 21778 : BufferTestBase(context, "xfb_block_member_stride", 21779 "Test verifies that xfb_stride qualifier is respected for block member") 21780 { 21781 /* Nothing to be done here */ 21782 } 21783 21784 /** Get descriptors of buffers necessary for test 21785 * 21786 * @param ignored 21787 * @param out_descriptors Descriptors of buffers used by test 21788 **/ 21789 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 21790 bufferDescriptor::Vector& out_descriptors) 21791 { 21792 const Utils::Type& vec4 = Utils::Type::vec4; 21793 21794 /* Test needs single uniform and xfb */ 21795 out_descriptors.resize(2); 21796 21797 /* Get references */ 21798 bufferDescriptor& uniform = out_descriptors[0]; 21799 bufferDescriptor& xfb = out_descriptors[1]; 21800 21801 /* Index */ 21802 uniform.m_index = 0; 21803 xfb.m_index = 0; 21804 21805 /* Target */ 21806 uniform.m_target = Utils::Buffer::Uniform; 21807 xfb.m_target = Utils::Buffer::Transform_feedback; 21808 21809 /* Data */ 21810 static const GLuint vec4_size = 16; 21811 const std::vector<GLubyte>& gohan_data = vec4.GenerateDataPacked(); 21812 const std::vector<GLubyte>& goten_data = vec4.GenerateDataPacked(); 21813 const std::vector<GLubyte>& chichi_data = vec4.GenerateDataPacked(); 21814 21815 /* Uniform data */ 21816 uniform.m_initial_data.resize(3 * vec4_size); 21817 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size); 21818 memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size); 21819 memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size); 21820 21821 /* XFB data */ 21822 xfb.m_initial_data.resize(4 * vec4_size); 21823 xfb.m_expected_data.resize(4 * vec4_size); 21824 21825 for (GLuint i = 0; i < 4 * vec4_size; ++i) 21826 { 21827 xfb.m_initial_data[i] = (glw::GLubyte)i; 21828 xfb.m_expected_data[i] = (glw::GLubyte)i; 21829 } 21830 21831 // the xfb_offset of "chichi" should be 32 21832 memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size); 21833 memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size); 21834 memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size); 21835 } 21836 21837 /** Get body of main function for given shader stage 21838 * 21839 * @param ignored 21840 * @param stage Shader stage 21841 * @param out_assignments Set to empty 21842 * @param out_calculations Set to empty 21843 **/ 21844 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 21845 std::string& out_assignments, std::string& out_calculations) 21846 { 21847 out_calculations = ""; 21848 21849 static const GLchar* gs = " gohan = uni_gohan;\n" 21850 " goten = uni_goten;\n" 21851 " chichi = uni_chichi;\n"; 21852 static const GLchar* fs = " fs_out = gohan + goten + chichi;\n"; 21853 21854 const GLchar* assignments = ""; 21855 switch (stage) 21856 { 21857 case Utils::Shader::FRAGMENT: 21858 assignments = fs; 21859 break; 21860 case Utils::Shader::GEOMETRY: 21861 assignments = gs; 21862 break; 21863 default: 21864 break; 21865 } 21866 21867 out_assignments = assignments; 21868 } 21869 21870 /** Get interface of shader 21871 * 21872 * @param ignored 21873 * @param stage Shader stage 21874 * @param out_interface Set to "" 21875 **/ 21876 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 21877 std::string& out_interface) 21878 { 21879 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n" 21880 " vec4 gohan;\n" 21881 " layout (xfb_stride = 48) vec4 goten;\n" 21882 " vec4 chichi;\n" 21883 "};\n" 21884 "layout(binding = 0) uniform gs_block {\n" 21885 " vec4 uni_gohan;\n" 21886 " vec4 uni_goten;\n" 21887 " vec4 uni_chichi;\n" 21888 "};\n"; 21889 static const GLchar* fs = "in Goku {\n" 21890 " vec4 gohan;\n" 21891 " vec4 goten;\n" 21892 " vec4 chichi;\n" 21893 "};\n" 21894 "out vec4 fs_out;\n"; 21895 21896 switch (stage) 21897 { 21898 case Utils::Shader::FRAGMENT: 21899 out_interface = fs; 21900 break; 21901 case Utils::Shader::GEOMETRY: 21902 out_interface = gs; 21903 break; 21904 default: 21905 out_interface = ""; 21906 return; 21907 } 21908 } 21909 21910 /** Inspects program to check if all resources are as expected 21911 * 21912 * @param ignored 21913 * @param program Program instance 21914 * @param out_stream Error message 21915 * 21916 * @return true if everything is ok, false otherwise 21917 **/ 21918 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program& program, 21919 std::stringstream& out_stream) 21920 { 21921 const GLuint gohan_id = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING); 21922 const GLuint goten_id = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING); 21923 const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING); 21924 21925 GLint gohan_offset = 0; 21926 GLint goten_offset = 0; 21927 GLint chichi_offset = 0; 21928 21929 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset); 21930 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset); 21931 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset); 21932 21933 // the xfb_offset of "chichi" should be 32 21934 if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset)) 21935 { 21936 out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset 21937 << "] expected: [0, 16, 32]"; 21938 return false; 21939 } 21940 21941 return true; 21942 } 21943 21944 /** Constructor 21945 * 21946 * @param context Test framework context 21947 **/ 21948 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context& context) 21949 : NegativeTestBase(context, "xfb_duplicated_stride", 21950 "Test verifies that compiler reports error when conflicting stride qualifiers are used") 21951 { 21952 } 21953 21954 /** Source for given test case and stage 21955 * 21956 * @param test_case_index Index of test case 21957 * @param stage Shader stage 21958 * 21959 * @return Shader source 21960 **/ 21961 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 21962 { 21963 static const GLchar* invalid_var_definition = "const uint valid_stride = 64;\n" 21964 "const uint conflicting_stride = 128;\n" 21965 "\n" 21966 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n" 21967 "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n"; 21968 static const GLchar* valid_var_definition = "const uint valid_stride = 64;\n" 21969 "\n" 21970 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n" 21971 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"; 21972 static const GLchar* fs = "#version 430 core\n" 21973 "#extension GL_ARB_enhanced_layouts : require\n" 21974 "\n" 21975 "in vec4 any_fs;\n" 21976 "out vec4 fs_out;\n" 21977 "\n" 21978 "void main()\n" 21979 "{\n" 21980 " fs_out = any_fs;\n" 21981 "}\n" 21982 "\n"; 21983 static const GLchar* gs_tested = "#version 430 core\n" 21984 "#extension GL_ARB_enhanced_layouts : require\n" 21985 "\n" 21986 "layout(points) in;\n" 21987 "layout(triangle_strip, max_vertices = 4) out;\n" 21988 "\n" 21989 "VAR_DEFINITION" 21990 "\n" 21991 "in vec4 vs_any[];\n" 21992 "out vec4 any_fs;\n" 21993 "\n" 21994 "void main()\n" 21995 "{\n" 21996 " vec4 result = vs_any[0];\n" 21997 "\n" 21998 "VARIABLE_USE" 21999 "\n" 22000 " any_fs = result;\n" 22001 " gl_Position = vec4(-1, -1, 0, 1);\n" 22002 " EmitVertex();\n" 22003 " any_fs = result;\n" 22004 " gl_Position = vec4(-1, 1, 0, 1);\n" 22005 " EmitVertex();\n" 22006 " any_fs = result;\n" 22007 " gl_Position = vec4(1, -1, 0, 1);\n" 22008 " EmitVertex();\n" 22009 " any_fs = result;\n" 22010 " gl_Position = vec4(1, 1, 0, 1);\n" 22011 " EmitVertex();\n" 22012 "}\n" 22013 "\n"; 22014 static const GLchar* tcs = "#version 430 core\n" 22015 "#extension GL_ARB_enhanced_layouts : require\n" 22016 "\n" 22017 "layout(vertices = 1) out;\n" 22018 "\n" 22019 "in vec4 vs_any[];\n" 22020 "out vec4 tcs_tes[];\n" 22021 "\n" 22022 "void main()\n" 22023 "{\n" 22024 "\n" 22025 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n" 22026 "\n" 22027 " gl_TessLevelOuter[0] = 1.0;\n" 22028 " gl_TessLevelOuter[1] = 1.0;\n" 22029 " gl_TessLevelOuter[2] = 1.0;\n" 22030 " gl_TessLevelOuter[3] = 1.0;\n" 22031 " gl_TessLevelInner[0] = 1.0;\n" 22032 " gl_TessLevelInner[1] = 1.0;\n" 22033 "}\n" 22034 "\n"; 22035 static const GLchar* tcs_tested = "#version 430 core\n" 22036 "#extension GL_ARB_enhanced_layouts : require\n" 22037 "\n" 22038 "layout(vertices = 1) out;\n" 22039 "\n" 22040 "VAR_DEFINITION" 22041 "\n" 22042 "in vec4 vs_any[];\n" 22043 "out vec4 any_fs[];\n" 22044 "\n" 22045 "void main()\n" 22046 "{\n" 22047 " vec4 result = vs_any[gl_InvocationID];\n" 22048 "\n" 22049 "VARIABLE_USE" 22050 "\n" 22051 " any_fs[gl_InvocationID] = result;\n" 22052 "\n" 22053 " gl_TessLevelOuter[0] = 1.0;\n" 22054 " gl_TessLevelOuter[1] = 1.0;\n" 22055 " gl_TessLevelOuter[2] = 1.0;\n" 22056 " gl_TessLevelOuter[3] = 1.0;\n" 22057 " gl_TessLevelInner[0] = 1.0;\n" 22058 " gl_TessLevelInner[1] = 1.0;\n" 22059 "}\n" 22060 "\n"; 22061 static const GLchar* tes_tested = "#version 430 core\n" 22062 "#extension GL_ARB_enhanced_layouts : require\n" 22063 "\n" 22064 "layout(isolines, point_mode) in;\n" 22065 "\n" 22066 "VAR_DEFINITION" 22067 "\n" 22068 "in vec4 tcs_tes[];\n" 22069 "out vec4 any_fs;\n" 22070 "\n" 22071 "void main()\n" 22072 "{\n" 22073 " vec4 result = tcs_tes[0];\n" 22074 "\n" 22075 "VARIABLE_USE" 22076 "\n" 22077 " any_fs = result;\n" 22078 "}\n" 22079 "\n"; 22080 static const GLchar* vs = "#version 430 core\n" 22081 "#extension GL_ARB_enhanced_layouts : require\n" 22082 "\n" 22083 "in vec4 in_vs;\n" 22084 "out vec4 vs_any;\n" 22085 "\n" 22086 "void main()\n" 22087 "{\n" 22088 " vs_any = in_vs;\n" 22089 "}\n" 22090 "\n"; 22091 static const GLchar* vs_tested = "#version 430 core\n" 22092 "#extension GL_ARB_enhanced_layouts : require\n" 22093 "\n" 22094 "VAR_DEFINITION" 22095 "\n" 22096 "in vec4 in_vs;\n" 22097 "out vec4 any_fs;\n" 22098 "\n" 22099 "void main()\n" 22100 "{\n" 22101 " vec4 result = in_vs;\n" 22102 "\n" 22103 "VARIABLE_USE" 22104 "\n" 22105 " any_fs += result;\n" 22106 "}\n" 22107 "\n"; 22108 22109 std::string source; 22110 testCase& test_case = m_test_cases[test_case_index]; 22111 22112 if (test_case.m_stage == stage) 22113 { 22114 size_t position = 0; 22115 const GLchar* var_definition = 0; 22116 const GLchar* var_use = ""; 22117 22118 switch (test_case.m_case) 22119 { 22120 case VALID: 22121 var_definition = valid_var_definition; 22122 break; 22123 case INVALID: 22124 var_definition = invalid_var_definition; 22125 break; 22126 default: 22127 TCU_FAIL("Invalid enum"); 22128 } 22129 22130 switch (stage) 22131 { 22132 case Utils::Shader::GEOMETRY: 22133 source = gs_tested; 22134 break; 22135 case Utils::Shader::TESS_CTRL: 22136 source = tcs_tested; 22137 break; 22138 case Utils::Shader::TESS_EVAL: 22139 source = tes_tested; 22140 break; 22141 case Utils::Shader::VERTEX: 22142 source = vs_tested; 22143 break; 22144 default: 22145 TCU_FAIL("Invalid enum"); 22146 } 22147 22148 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 22149 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 22150 } 22151 else 22152 { 22153 switch (test_case.m_stage) 22154 { 22155 case Utils::Shader::GEOMETRY: 22156 switch (stage) 22157 { 22158 case Utils::Shader::FRAGMENT: 22159 source = fs; 22160 break; 22161 case Utils::Shader::VERTEX: 22162 source = vs; 22163 break; 22164 default: 22165 source = ""; 22166 } 22167 break; 22168 case Utils::Shader::TESS_CTRL: 22169 switch (stage) 22170 { 22171 case Utils::Shader::FRAGMENT: 22172 source = fs; 22173 break; 22174 case Utils::Shader::VERTEX: 22175 source = vs; 22176 break; 22177 default: 22178 source = ""; 22179 } 22180 break; 22181 case Utils::Shader::TESS_EVAL: 22182 switch (stage) 22183 { 22184 case Utils::Shader::FRAGMENT: 22185 source = fs; 22186 break; 22187 case Utils::Shader::TESS_CTRL: 22188 source = tcs; 22189 break; 22190 case Utils::Shader::VERTEX: 22191 source = vs; 22192 break; 22193 default: 22194 source = ""; 22195 } 22196 break; 22197 case Utils::Shader::VERTEX: 22198 switch (stage) 22199 { 22200 case Utils::Shader::FRAGMENT: 22201 source = fs; 22202 break; 22203 default: 22204 source = ""; 22205 } 22206 break; 22207 default: 22208 TCU_FAIL("Invalid enum"); 22209 break; 22210 } 22211 } 22212 22213 return source; 22214 } 22215 22216 /** Get description of test case 22217 * 22218 * @param test_case_index Index of test case 22219 * 22220 * @return Test case description 22221 **/ 22222 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index) 22223 { 22224 std::stringstream stream; 22225 testCase& test_case = m_test_cases[test_case_index]; 22226 22227 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: "; 22228 22229 switch (test_case.m_case) 22230 { 22231 case VALID: 22232 stream << "valid"; 22233 break; 22234 case INVALID: 22235 stream << "invalid"; 22236 break; 22237 default: 22238 TCU_FAIL("Invalid enum"); 22239 } 22240 22241 return stream.str(); 22242 } 22243 22244 /** Get number of test cases 22245 * 22246 * @return Number of test cases 22247 **/ 22248 GLuint XFBDuplicatedStrideTest::getTestCaseNumber() 22249 { 22250 return static_cast<GLuint>(m_test_cases.size()); 22251 } 22252 22253 /** Selects if "compute" stage is relevant for test 22254 * 22255 * @param ignored 22256 * 22257 * @return false 22258 **/ 22259 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */) 22260 { 22261 return false; 22262 } 22263 22264 /** Selects if compilation failure is expected result 22265 * 22266 * @param test_case_index Index of test case 22267 * 22268 * @return true 22269 **/ 22270 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index) 22271 { 22272 testCase& test_case = m_test_cases[test_case_index]; 22273 22274 return (INVALID == test_case.m_case); 22275 } 22276 22277 /** Prepare all test cases 22278 * 22279 **/ 22280 void XFBDuplicatedStrideTest::testInit() 22281 { 22282 for (GLuint c = 0; c < CASE_MAX; ++c) 22283 { 22284 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 22285 { 22286 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 22287 (Utils::Shader::FRAGMENT == stage)) 22288 { 22289 continue; 22290 } 22291 22292 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage }; 22293 22294 m_test_cases.push_back(test_case); 22295 } 22296 } 22297 } 22298 22299 /** Constructor 22300 * 22301 * @param context Test framework context 22302 **/ 22303 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context& context) 22304 : TestBase(context, "xfb_get_program_resource_api", 22305 "Test verifies that get program resource reports correct results for XFB") 22306 { 22307 } 22308 22309 /** Source for given test case and stage 22310 * 22311 * @param test_case_index Index of test case 22312 * @param stage Shader stage 22313 * 22314 * @return Shader source 22315 **/ 22316 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 22317 { 22318 static const GLchar* api_var_definition = "out TYPE b0_v1ARRAY;\n" 22319 "out TYPE b1_v1ARRAY;\n" 22320 "out TYPE b0_v3ARRAY;\n" 22321 "out TYPE b0_v0ARRAY;\n"; 22322 static const GLchar* xfb_var_definition = 22323 "const uint type_size = SIZE;\n" 22324 "\n" 22325 "layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n" 22326 "\n" 22327 "layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n" 22328 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n" 22329 "layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n" 22330 "layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n"; 22331 static const GLchar* var_use = " b0_v1INDEX = TYPE(0);\n" 22332 " b1_v1INDEX = TYPE(1);\n" 22333 " b0_v3INDEX = TYPE(0);\n" 22334 " b0_v0INDEX = TYPE(1);\n" 22335 " if (vec4(0) == result)\n" 22336 " {\n" 22337 " b0_v1INDEX = TYPE(1);\n" 22338 " b1_v1INDEX = TYPE(0);\n" 22339 " b0_v3INDEX = TYPE(1);\n" 22340 " b0_v0INDEX = TYPE(0);\n" 22341 " }\n"; 22342 static const GLchar* gs_tested = 22343 "#version 430 core\n" 22344 "#extension GL_ARB_enhanced_layouts : require\n" 22345 "\n" 22346 "layout(points) in;\n" 22347 "layout(triangle_strip, max_vertices = 4) out;\n" 22348 "\n" 22349 "VAR_DEFINITION" 22350 "\n" 22351 "out gl_PerVertex \n" 22352 "{ \n" 22353 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode 22354 "}; \n" 22355 "in vec4 tes_gs[];\n" 22356 "out vec4 gs_fs;\n" 22357 "\n" 22358 "void main()\n" 22359 "{\n" 22360 " vec4 result = tes_gs[0];\n" 22361 "\n" 22362 "VARIABLE_USE" 22363 "\n" 22364 " gs_fs = result;\n" 22365 " gl_Position = vec4(-1, -1, 0, 1);\n" 22366 " EmitVertex();\n" 22367 " gs_fs = result;\n" 22368 " gl_Position = vec4(-1, 1, 0, 1);\n" 22369 " EmitVertex();\n" 22370 " gs_fs = result;\n" 22371 " gl_Position = vec4(1, -1, 0, 1);\n" 22372 " EmitVertex();\n" 22373 " gs_fs = result;\n" 22374 " gl_Position = vec4(1, 1, 0, 1);\n" 22375 " EmitVertex();\n" 22376 "}\n" 22377 "\n"; 22378 #if 0 22379 static const GLchar* tcs_tested = 22380 "#version 430 core\n" 22381 "#extension GL_ARB_enhanced_layouts : require\n" 22382 "\n" 22383 "layout(vertices = 1) out;\n" 22384 "\n" 22385 "VAR_DEFINITION" 22386 "\n" 22387 "in vec4 vs_tcs[];\n" 22388 "out vec4 tcs_tes[];\n" 22389 "\n" 22390 "void main()\n" 22391 "{\n" 22392 " vec4 result = vs_tcs[gl_InvocationID];\n" 22393 "\n" 22394 "VARIABLE_USE" 22395 "\n" 22396 " tcs_tes[gl_InvocationID] = result;\n" 22397 "\n" 22398 " gl_TessLevelOuter[0] = 1.0;\n" 22399 " gl_TessLevelOuter[1] = 1.0;\n" 22400 " gl_TessLevelOuter[2] = 1.0;\n" 22401 " gl_TessLevelOuter[3] = 1.0;\n" 22402 " gl_TessLevelInner[0] = 1.0;\n" 22403 " gl_TessLevelInner[1] = 1.0;\n" 22404 "}\n" 22405 "\n"; 22406 #endif 22407 static const GLchar* tes_tested = "#version 430 core\n" 22408 "#extension GL_ARB_enhanced_layouts : require\n" 22409 "\n" 22410 "layout(isolines, point_mode) in;\n" 22411 "\n" 22412 "VAR_DEFINITION" 22413 "\n" 22414 "in vec4 tcs_tes[];\n" 22415 "out vec4 tes_gs;\n" 22416 "\n" 22417 "void main()\n" 22418 "{\n" 22419 " vec4 result = tcs_tes[0];\n" 22420 "\n" 22421 "VARIABLE_USE" 22422 "\n" 22423 " tes_gs = result;\n" 22424 "}\n" 22425 "\n"; 22426 static const GLchar* vs_tested = "#version 430 core\n" 22427 "#extension GL_ARB_enhanced_layouts : require\n" 22428 "\n" 22429 "VAR_DEFINITION" 22430 "\n" 22431 "in vec4 in_vs;\n" 22432 "out vec4 vs_tcs;\n" 22433 "\n" 22434 "void main()\n" 22435 "{\n" 22436 " vec4 result = in_vs;\n" 22437 "\n" 22438 "VARIABLE_USE" 22439 "\n" 22440 " vs_tcs = result;\n" 22441 "}\n" 22442 "\n"; 22443 22444 std::string source; 22445 const test_Case& test_case = m_test_cases[test_case_index]; 22446 22447 if (test_case.m_stage == stage) 22448 { 22449 const GLchar* array = ""; 22450 GLchar buffer[16]; 22451 const GLchar* index = ""; 22452 size_t position = 0; 22453 size_t temp; 22454 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 22455 const GLchar* var_definition = 0; 22456 22457 sprintf(buffer, "%d", test_case.m_type.GetSize()); 22458 22459 if (XFB == test_case.m_case) 22460 { 22461 var_definition = xfb_var_definition; 22462 } 22463 else 22464 { 22465 var_definition = api_var_definition; 22466 } 22467 22468 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73) 22469 // change array = "[]" to "[1]" 22470 switch (stage) 22471 { 22472 case Utils::Shader::GEOMETRY: 22473 source = gs_tested; 22474 array = "[1]"; 22475 index = "[0]"; 22476 break; 22477 // It is invalid to output transform feedback varyings in tessellation control shader 22478 #if 0 22479 case Utils::Shader::TESS_CTRL: 22480 source = tcs_tested; 22481 array = "[]"; 22482 index = "[gl_InvocationID]"; 22483 break; 22484 #endif 22485 case Utils::Shader::TESS_EVAL: 22486 source = tes_tested; 22487 array = "[1]"; 22488 index = "[0]"; 22489 break; 22490 case Utils::Shader::VERTEX: 22491 source = vs_tested; 22492 break; 22493 default: 22494 TCU_FAIL("Invalid enum"); 22495 } 22496 22497 temp = position; 22498 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 22499 if (XFB == test_case.m_case) 22500 { 22501 position = temp; 22502 Utils::replaceToken("SIZE", position, buffer, source); 22503 } 22504 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 22505 22506 Utils::replaceAllTokens("ARRAY", array, source); 22507 Utils::replaceAllTokens("INDEX", index, source); 22508 Utils::replaceAllTokens("TYPE", type_name, source); 22509 } 22510 else 22511 { 22512 source = ""; 22513 } 22514 22515 return source; 22516 } 22517 22518 /** Get description of test case 22519 * 22520 * @param test_case_index Index of test case 22521 * 22522 * @return Test case description 22523 **/ 22524 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index) 22525 { 22526 std::stringstream stream; 22527 const test_Case& test_case = m_test_cases[test_case_index]; 22528 22529 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 22530 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: "; 22531 22532 switch (test_case.m_case) 22533 { 22534 case INTERLEAVED: 22535 stream << "interleaved"; 22536 break; 22537 case SEPARATED: 22538 stream << "separated"; 22539 break; 22540 case XFB: 22541 stream << "xfb"; 22542 break; 22543 default: 22544 TCU_FAIL("Invalid enum"); 22545 } 22546 22547 return stream.str(); 22548 } 22549 22550 /** Get number of test cases 22551 * 22552 * @return Number of test cases 22553 **/ 22554 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber() 22555 { 22556 return static_cast<GLuint>(m_test_cases.size()); 22557 } 22558 22559 /** Inspects program for offset, buffer index, buffer stride and type 22560 * 22561 * @param test_case_index Index of test case 22562 * @param program Program to query 22563 * 22564 * @return true if query results match expected values, false otherwise 22565 **/ 22566 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program& program) 22567 { 22568 GLint b0_stride = 0; 22569 GLint b1_stride = 0; 22570 GLint b0_v0_buf = 0; 22571 GLint b0_v0_offset = 0; 22572 GLint b0_v0_type = 0; 22573 GLint b0_v1_buf = 0; 22574 GLint b0_v1_offset = 0; 22575 GLint b0_v1_type = 0; 22576 GLint b0_v3_buf = 0; 22577 GLint b0_v3_offset = 0; 22578 GLint b0_v3_type = 0; 22579 GLint b1_v1_buf = 0; 22580 GLint b1_v1_offset = 0; 22581 GLint b1_v1_type = 0; 22582 const test_Case& test_case = m_test_cases[test_case_index]; 22583 const GLenum type_enum = test_case.m_type.GetTypeGLenum(); 22584 const GLint type_size = test_case.m_type.GetSize(); 22585 22586 GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING); 22587 GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING); 22588 GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING); 22589 GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING); 22590 22591 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset); 22592 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset); 22593 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset); 22594 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset); 22595 22596 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type); 22597 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type); 22598 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type); 22599 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type); 22600 22601 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX, 22602 1 /* buf_size */, &b0_v0_buf); 22603 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX, 22604 1 /* buf_size */, &b0_v1_buf); 22605 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX, 22606 1 /* buf_size */, &b0_v3_buf); 22607 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX, 22608 1 /* buf_size */, &b1_v1_buf); 22609 22610 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */, 22611 &b0_stride); 22612 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */, 22613 &b1_stride); 22614 22615 if (SEPARATED != test_case.m_case) 22616 { 22617 return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) && 22618 ((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) && 22619 ((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) && 22620 ((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) && 22621 ((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) && 22622 ((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) && 22623 ((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type)); 22624 } 22625 else 22626 { 22627 return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) && 22628 ((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) && 22629 ((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) && 22630 ((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) && 22631 ((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type)); 22632 } 22633 } 22634 22635 /** Insert gl_SkipComponents 22636 * 22637 * @param num_components How many gl_SkipComponents1 need to be inserted 22638 * @param varyings The transform feedback varyings string vector 22639 * 22640 **/ 22641 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector& varyings) 22642 { 22643 int num_component_4 = num_components / 4; 22644 int num_component_1 = num_components % 4; 22645 for (int i = 0; i < num_component_4; i++) 22646 { 22647 varyings.push_back("gl_SkipComponents4"); 22648 } 22649 switch (num_component_1) 22650 { 22651 case 1: 22652 varyings.push_back("gl_SkipComponents1"); 22653 break; 22654 case 2: 22655 varyings.push_back("gl_SkipComponents2"); 22656 break; 22657 case 3: 22658 varyings.push_back("gl_SkipComponents3"); 22659 break; 22660 default: 22661 break; 22662 } 22663 } 22664 22665 /** Runs test case 22666 * 22667 * @param test_case_index Id of test case 22668 * 22669 * @return true if test case pass, false otherwise 22670 **/ 22671 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index) 22672 { 22673 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY); 22674 Utils::Program program(m_context); 22675 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL); 22676 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL); 22677 const test_Case& test_case = m_test_cases[test_case_index]; 22678 bool test_case_result = true; 22679 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX); 22680 22681 // According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values. 22682 // No data will be recorded for such strings, but the offset assigned to the next variable in varyings and the stride of the assigned bingding point will be affected. 22683 22684 if (INTERLEAVED == test_case.m_case) 22685 { 22686 /* 22687 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1; 22688 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1; 22689 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3; 22690 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0; 22691 22692 Note: the type can be float, double, mat2, mat3x2, dmat2, dmat3x2..., so to make the each variable of "captured_varyings" has the same xfb_offset with the above shaders, 22693 we need to calculate how many "gl_SkipComponents" need to be inserted. 22694 */ 22695 Utils::Program::NameVector captured_varyings; 22696 captured_varyings.push_back("b0_v0"); 22697 captured_varyings.push_back("b0_v1"); 22698 // Compute how many gl_SkipComponents to be inserted 22699 int numComponents = test_case.m_type.GetSize() / 4; 22700 insertSkipComponents(numComponents, captured_varyings); 22701 captured_varyings.push_back("b0_v3"); 22702 captured_varyings.push_back("gl_NextBuffer"); 22703 insertSkipComponents(numComponents, captured_varyings); 22704 captured_varyings.push_back("b1_v1"); 22705 insertSkipComponents(numComponents * 2, captured_varyings); 22706 22707 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true, 22708 true /* separable */); 22709 } 22710 else if (SEPARATED == test_case.m_case) 22711 { 22712 Utils::Program::NameVector captured_varyings; 22713 22714 captured_varyings.push_back("b0_v0"); 22715 captured_varyings.push_back("b0_v1"); 22716 captured_varyings.push_back("b0_v3"); 22717 captured_varyings.push_back("b1_v1"); 22718 22719 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false, 22720 true /* separable */); 22721 } 22722 else 22723 { 22724 22725 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */); 22726 } 22727 22728 test_case_result = inspectProgram(test_case_index, program); 22729 22730 return test_case_result; 22731 } 22732 22733 /** Prepare all test cases 22734 * 22735 **/ 22736 void XFBGetProgramResourceAPITest::testInit() 22737 { 22738 const Functions& gl = m_context.getRenderContext().getFunctions(); 22739 const GLuint n_types = getTypesNumber(); 22740 GLint max_xfb_int; 22741 GLint max_xfb_sep; 22742 22743 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int); 22744 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 22745 22746 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep); 22747 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 22748 22749 GLint max_varyings; 22750 gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings); 22751 22752 for (GLuint i = 0; i < n_types; ++i) 22753 { 22754 // When i == 7, the type is dmat4, i == 9 the type is dmat4x3, the number of output components exceeds the maximum value that AMD's driver supported, 22755 // the MAX_VARYING_COMPONENTS is 32 in our driver, but when the variable type is dmat4 or dmat4x3, the number of output component is 33, to make the 22756 // shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader 22757 // to guarantee the number of varying not exceeded. 22758 /* 22759 layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out; 22760 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1; 22761 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1; 22762 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3; 22763 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0; 22764 in vec4 in_vs; 22765 out vec4 vs_tcs; 22766 */ 22767 if (i == 7 || i == 9) 22768 continue; 22769 const Utils::Type& type = getType(i); 22770 if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings) 22771 { 22772 continue; 22773 } 22774 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 22775 { 22776 /* 22777 It is invalid to define transform feedback output in HS 22778 */ 22779 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 22780 (Utils::Shader::FRAGMENT == stage)) 22781 { 22782 continue; 22783 } 22784 22785 test_Case test_case_int = { INTERLEAVED, (Utils::Shader::STAGES)stage, type }; 22786 test_Case test_case_sep = { SEPARATED, (Utils::Shader::STAGES)stage, type }; 22787 test_Case test_case_xfb = { XFB, (Utils::Shader::STAGES)stage, type }; 22788 22789 if ((int)type.GetSize() <= max_xfb_int) 22790 { 22791 m_test_cases.push_back(test_case_xfb); 22792 m_test_cases.push_back(test_case_int); 22793 } 22794 22795 if ((int)type.GetSize() <= max_xfb_sep) 22796 { 22797 m_test_cases.push_back(test_case_sep); 22798 } 22799 } 22800 } 22801 } 22802 22803 /** Constructor 22804 * 22805 * @param context Test context 22806 **/ 22807 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context& context) 22808 : BufferTestBase(context, "xfb_override_qualifiers_with_api", 22809 "Test verifies that xfb_offset qualifier is not overriden with API") 22810 { 22811 /* Nothing to be done here */ 22812 } 22813 22814 /** Get descriptors of buffers necessary for test 22815 * 22816 * @param test_case_index Index of test case 22817 * @param out_descriptors Descriptors of buffers used by test 22818 **/ 22819 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint test_case_index, 22820 bufferDescriptor::Vector& out_descriptors) 22821 { 22822 const Utils::Type& type = getType(test_case_index); 22823 22824 /* Test needs single uniform and xfb */ 22825 out_descriptors.resize(2); 22826 22827 /* Get references */ 22828 bufferDescriptor& uniform = out_descriptors[0]; 22829 bufferDescriptor& xfb = out_descriptors[1]; 22830 22831 /* Index */ 22832 uniform.m_index = 0; 22833 xfb.m_index = 0; 22834 22835 /* Target */ 22836 uniform.m_target = Utils::Buffer::Uniform; 22837 xfb.m_target = Utils::Buffer::Transform_feedback; 22838 22839 /* Data */ 22840 const GLuint gen_start = Utils::s_rand; 22841 const std::vector<GLubyte>& vegeta_data = type.GenerateData(); 22842 const std::vector<GLubyte>& trunks_data = type.GenerateData(); 22843 const std::vector<GLubyte>& goku_data = type.GenerateData(); 22844 22845 Utils::s_rand = gen_start; 22846 const std::vector<GLubyte>& vegeta_data_pck = type.GenerateDataPacked(); 22847 type.GenerateDataPacked(); // generate the data for trunks 22848 const std::vector<GLubyte>& goku_data_pck = type.GenerateDataPacked(); 22849 22850 const GLuint type_size = static_cast<GLuint>(vegeta_data.size()); 22851 const GLuint type_size_pck = static_cast<GLuint>(vegeta_data_pck.size()); 22852 22853 /* Uniform data */ 22854 uniform.m_initial_data.resize(3 * type_size); 22855 memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size); 22856 memcpy(&uniform.m_initial_data[0] + type_size, &trunks_data[0], type_size); 22857 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goku_data[0], type_size); 22858 22859 /* XFB data */ 22860 xfb.m_initial_data.resize(3 * type_size_pck); 22861 xfb.m_expected_data.resize(3 * type_size_pck); 22862 22863 for (GLuint i = 0; i < 3 * type_size_pck; ++i) 22864 { 22865 xfb.m_initial_data[i] = (glw::GLubyte)i; 22866 xfb.m_expected_data[i] = (glw::GLubyte)i; 22867 } 22868 22869 memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck); 22870 memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck); 22871 } 22872 22873 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings 22874 * 22875 * @param ignored 22876 * @param captured_varyings List of names 22877 **/ 22878 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint test_case_index, 22879 Utils::Program::NameVector& captured_varyings, 22880 GLint* xfb_components) 22881 { 22882 captured_varyings.resize(1); 22883 22884 captured_varyings[0] = "trunks"; 22885 22886 /* The test captures 3 varyings of type 'type' */ 22887 Utils::Type type = getType(test_case_index); 22888 GLint type_size = type.GetSize(false); 22889 *xfb_components = 3 * type_size / 4; 22890 } 22891 22892 /** Get body of main function for given shader stage 22893 * 22894 * @param test_case_index Index of test case 22895 * @param stage Shader stage 22896 * @param out_assignments Set to empty 22897 * @param out_calculations Set to empty 22898 **/ 22899 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, 22900 std::string& out_assignments, std::string& out_calculations) 22901 { 22902 out_calculations = ""; 22903 22904 static const GLchar* gs = " vegeta = uni_vegeta;\n" 22905 " trunks = uni_trunks;\n" 22906 " goku = uni_goku;\n"; 22907 static const GLchar* fs = " fs_out = vec4(0);\n" 22908 " if (TYPE(1) == goku + trunks + vegeta)\n" 22909 " {\n" 22910 " fs_out = vec4(1);\n" 22911 " }\n"; 22912 22913 const GLchar* assignments = ""; 22914 switch (stage) 22915 { 22916 case Utils::Shader::FRAGMENT: 22917 assignments = fs; 22918 break; 22919 case Utils::Shader::GEOMETRY: 22920 assignments = gs; 22921 break; 22922 default: 22923 break; 22924 } 22925 22926 out_assignments = assignments; 22927 22928 if (Utils::Shader::FRAGMENT == stage) 22929 { 22930 const Utils::Type& type = getType(test_case_index); 22931 22932 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments); 22933 } 22934 } 22935 22936 /** Get interface of shader 22937 * 22938 * @param test_case_index Index of test case 22939 * @param stage Shader stage 22940 * @param out_interface Set to "" 22941 **/ 22942 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, 22943 std::string& out_interface) 22944 { 22945 static const GLchar* gs = "const uint sizeof_type = SIZE;\n" 22946 "\n" 22947 "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n" 22948 " flat out TYPE trunks;\n" 22949 "layout (xfb_offset = 0) flat out TYPE goku;\n" 22950 "\n" 22951 /* 22952 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default, 22953 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will 22954 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API 22955 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the 22956 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed, 22957 we need to add the qualifier std140, and change the declaration as layout(binding=0, std140), which can make 22958 sure all the block members are packed and the application can upload the data by glBufferData() directly. 22959 */ 22960 "layout(binding = 0, std140) uniform gs_block {\n" 22961 " TYPE uni_vegeta;\n" 22962 " TYPE uni_trunks;\n" 22963 " TYPE uni_goku;\n" 22964 "};\n"; 22965 static const GLchar* fs = "flat in TYPE vegeta;\n" 22966 "flat in TYPE trunks;\n" 22967 "flat in TYPE goku;\n" 22968 "\n" 22969 "out vec4 fs_out;\n"; 22970 22971 const Utils::Type& type = getType(test_case_index); 22972 22973 switch (stage) 22974 { 22975 case Utils::Shader::FRAGMENT: 22976 out_interface = fs; 22977 break; 22978 case Utils::Shader::GEOMETRY: 22979 out_interface = gs; 22980 break; 22981 default: 22982 out_interface = ""; 22983 return; 22984 } 22985 22986 if (Utils::Shader::GEOMETRY == stage) 22987 { 22988 GLchar buffer[16]; 22989 size_t position = 0; 22990 const GLuint type_size = type.GetSize(); 22991 22992 sprintf(buffer, "%d", type_size); 22993 22994 Utils::replaceToken("SIZE", position, buffer, out_interface); 22995 } 22996 22997 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface); 22998 } 22999 23000 /** Get type name 23001 * 23002 * @param test_case_index Index of test case 23003 * 23004 * @return Name of type test in test_case_index 23005 **/ 23006 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index) 23007 { 23008 return getTypeName(test_case_index); 23009 } 23010 23011 /** Returns number of types to test 23012 * 23013 * @return Number of types, 34 23014 **/ 23015 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber() 23016 { 23017 return getTypesNumber(); 23018 } 23019 23020 /** Inspects program to check if all resources are as expected 23021 * 23022 * @param test_case_index Index of test case 23023 * @param program Program instance 23024 * @param out_stream Error message 23025 * 23026 * @return true if everything is ok, false otherwise 23027 **/ 23028 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program& program, 23029 std::stringstream& out_stream) 23030 { 23031 GLint stride = 0; 23032 const Utils::Type& type = getType(test_case_index); 23033 const GLuint type_size = type.GetSize(false); 23034 23035 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 23036 1 /* buf_size */, &stride); 23037 23038 if ((GLint)(3 * type_size) != stride) 23039 { 23040 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size); 23041 23042 return false; 23043 } 23044 23045 return true; 23046 } 23047 23048 /** Constructor 23049 * 23050 * @param context Test context 23051 **/ 23052 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context& context) 23053 : BufferTestBase(context, "xfb_vertex_streams", 23054 "Test verifies that xfb qualifier works with multiple output streams") 23055 { 23056 /* Nothing to be done here */ 23057 } 23058 23059 /** Get descriptors of buffers necessary for test 23060 * 23061 * @param ignored 23062 * @param out_descriptors Descriptors of buffers used by test 23063 **/ 23064 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 23065 bufferDescriptor::Vector& out_descriptors) 23066 { 23067 const Utils::Type& type = Utils::Type::vec4; 23068 23069 /* Test needs single uniform and three xfbs */ 23070 out_descriptors.resize(4); 23071 23072 /* Get references */ 23073 bufferDescriptor& uniform = out_descriptors[0]; 23074 bufferDescriptor& xfb_1 = out_descriptors[1]; 23075 bufferDescriptor& xfb_2 = out_descriptors[2]; 23076 bufferDescriptor& xfb_3 = out_descriptors[3]; 23077 23078 /* Index */ 23079 uniform.m_index = 0; 23080 xfb_1.m_index = 1; 23081 xfb_2.m_index = 2; 23082 xfb_3.m_index = 3; 23083 23084 /* Target */ 23085 uniform.m_target = Utils::Buffer::Uniform; 23086 xfb_1.m_target = Utils::Buffer::Transform_feedback; 23087 xfb_2.m_target = Utils::Buffer::Transform_feedback; 23088 xfb_3.m_target = Utils::Buffer::Transform_feedback; 23089 23090 /* Data */ 23091 const std::vector<GLubyte>& goku_data = type.GenerateData(); 23092 const std::vector<GLubyte>& gohan_data = type.GenerateData(); 23093 const std::vector<GLubyte>& goten_data = type.GenerateData(); 23094 const std::vector<GLubyte>& picolo_data = type.GenerateData(); 23095 const std::vector<GLubyte>& vegeta_data = type.GenerateData(); 23096 const std::vector<GLubyte>& bulma_data = type.GenerateData(); 23097 23098 const GLuint type_size = static_cast<GLuint>(vegeta_data.size()); 23099 23100 /* Uniform data */ 23101 uniform.m_initial_data.resize(6 * type_size); 23102 memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size); 23103 memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size); 23104 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size); 23105 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size); 23106 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size); 23107 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size); 23108 23109 /* XFB data */ 23110 static const GLuint xfb_stride = 64; 23111 xfb_1.m_initial_data.resize(xfb_stride); 23112 xfb_1.m_expected_data.resize(xfb_stride); 23113 xfb_2.m_initial_data.resize(xfb_stride); 23114 xfb_2.m_expected_data.resize(xfb_stride); 23115 xfb_3.m_initial_data.resize(xfb_stride); 23116 xfb_3.m_expected_data.resize(xfb_stride); 23117 23118 for (GLuint i = 0; i < xfb_stride; ++i) 23119 { 23120 xfb_1.m_initial_data[i] = (glw::GLubyte)i; 23121 xfb_1.m_expected_data[i] = (glw::GLubyte)i; 23122 xfb_2.m_initial_data[i] = (glw::GLubyte)i; 23123 xfb_2.m_expected_data[i] = (glw::GLubyte)i; 23124 xfb_3.m_initial_data[i] = (glw::GLubyte)i; 23125 xfb_3.m_expected_data[i] = (glw::GLubyte)i; 23126 } 23127 23128 memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size); 23129 memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size); 23130 memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size); 23131 memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size); 23132 memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size); 23133 memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size); 23134 } 23135 23136 /** Get body of main function for given shader stage 23137 * 23138 * @param ignored 23139 * @param stage Shader stage 23140 * @param out_assignments Set to empty 23141 * @param out_calculations Set to empty 23142 **/ 23143 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 23144 std::string& out_assignments, std::string& out_calculations) 23145 { 23146 out_calculations = ""; 23147 23148 // the shader declares the output variables with different "stream" qualifier, to make the data can export to 23149 // each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted 23150 // by the GS is assigned to specific stream. 23151 static const GLchar* gs = " goku = uni_goku;\n" 23152 " gohan = uni_gohan;\n" 23153 " goten = uni_goten;\n" 23154 " EmitStreamVertex(0);\n" 23155 " EndStreamPrimitive(0);\n" 23156 " picolo = uni_picolo;\n" 23157 " vegeta = uni_vegeta;\n" 23158 " EmitStreamVertex(1);\n" 23159 " EndStreamPrimitive(1);\n" 23160 " bulma = uni_bulma;\n" 23161 " EmitStreamVertex(2);\n" 23162 " EndStreamPrimitive(2);\n"; 23163 23164 static const GLchar* fs = " fs_out = gohan + goku + goten;\n"; 23165 23166 const GLchar* assignments = ""; 23167 switch (stage) 23168 { 23169 case Utils::Shader::FRAGMENT: 23170 assignments = fs; 23171 break; 23172 case Utils::Shader::GEOMETRY: 23173 assignments = gs; 23174 break; 23175 default: 23176 break; 23177 } 23178 23179 out_assignments = assignments; 23180 } 23181 23182 /** Get interface of shader 23183 * 23184 * @param ignored 23185 * @param stage Shader stage 23186 * @param out_interface Set to "" 23187 **/ 23188 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 23189 std::string& out_interface) 23190 { 23191 static const GLchar* gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n" 23192 "layout (xfb_buffer = 2, xfb_stride = 64) out;\n" 23193 "layout (xfb_buffer = 3, xfb_stride = 64) out;\n" 23194 "\n" 23195 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n" 23196 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n" 23197 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n" 23198 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n" 23199 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n" 23200 "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n" 23201 "\n" 23202 "layout(binding = 0) uniform gs_block {\n" 23203 " vec4 uni_goku;\n" 23204 " vec4 uni_gohan;\n" 23205 " vec4 uni_goten;\n" 23206 " vec4 uni_picolo;\n" 23207 " vec4 uni_vegeta;\n" 23208 " vec4 uni_bulma;\n" 23209 "};\n"; 23210 /* 23211 Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader 23212 */ 23213 static const GLchar* fs = "in vec4 goku;\n" 23214 "in vec4 gohan;\n" 23215 "in vec4 goten;\n" 23216 "\n" 23217 "out vec4 fs_out;\n"; 23218 23219 switch (stage) 23220 { 23221 case Utils::Shader::FRAGMENT: 23222 out_interface = fs; 23223 break; 23224 case Utils::Shader::GEOMETRY: 23225 out_interface = gs; 23226 break; 23227 default: 23228 out_interface = ""; 23229 return; 23230 } 23231 } 23232 23233 /** Constructor 23234 * 23235 * @param context Test framework context 23236 **/ 23237 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context& context) 23238 : NegativeTestBase( 23239 context, "xfb_multiple_vertex_streams", 23240 "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer") 23241 { 23242 } 23243 23244 /** Source for given test case and stage 23245 * 23246 * @param ignored 23247 * @param stage Shader stage 23248 * 23249 * @return Shader source 23250 **/ 23251 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage) 23252 { 23253 static const GLchar* var_definition = "const uint valid_stride = 64;\n" 23254 "\n" 23255 "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n" 23256 "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n" 23257 "\n" 23258 "\n" 23259 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n" 23260 "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n" 23261 "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"; 23262 static const GLchar* var_use = " goku = result / 2;\n" 23263 " gohan = result / 4;\n" 23264 " goten = result / 6;\n"; 23265 static const GLchar* fs = "#version 430 core\n" 23266 "#extension GL_ARB_enhanced_layouts : require\n" 23267 "\n" 23268 "in vec4 gs_fs;\n" 23269 "in vec4 goku;\n" 23270 "out vec4 fs_out;\n" 23271 "\n" 23272 "void main()\n" 23273 "{\n" 23274 " fs_out = gs_fs + goku;\n" 23275 "}\n" 23276 "\n"; 23277 static const GLchar* gs = "#version 430 core\n" 23278 "#extension GL_ARB_enhanced_layouts : require\n" 23279 "\n" 23280 "layout(points) in;\n" 23281 "layout(triangle_strip, max_vertices = 4) out;\n" 23282 "\n" 23283 "VAR_DEFINITION" 23284 "\n" 23285 "in vec4 tes_gs[];\n" 23286 "out vec4 gs_fs;\n" 23287 "\n" 23288 "void main()\n" 23289 "{\n" 23290 " vec4 result = tes_gs[0];\n" 23291 "\n" 23292 "VARIABLE_USE" 23293 "\n" 23294 " gs_fs = result;\n" 23295 " gl_Position = vec4(-1, -1, 0, 1);\n" 23296 " EmitVertex();\n" 23297 " gs_fs = result;\n" 23298 " gl_Position = vec4(-1, 1, 0, 1);\n" 23299 " EmitVertex();\n" 23300 " gs_fs = result;\n" 23301 " gl_Position = vec4(1, -1, 0, 1);\n" 23302 " EmitVertex();\n" 23303 " gs_fs = result;\n" 23304 " gl_Position = vec4(1, 1, 0, 1);\n" 23305 " EmitVertex();\n" 23306 "}\n" 23307 "\n"; 23308 static const GLchar* vs = "#version 430 core\n" 23309 "#extension GL_ARB_enhanced_layouts : require\n" 23310 "\n" 23311 "in vec4 in_vs;\n" 23312 "out vec4 vs_tcs;\n" 23313 "\n" 23314 "void main()\n" 23315 "{\n" 23316 " vs_tcs = in_vs;\n" 23317 "}\n" 23318 "\n"; 23319 23320 std::string source; 23321 23322 if (Utils::Shader::GEOMETRY == stage) 23323 { 23324 size_t position = 0; 23325 23326 source = gs; 23327 23328 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 23329 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 23330 } 23331 else 23332 { 23333 switch (stage) 23334 { 23335 case Utils::Shader::FRAGMENT: 23336 source = fs; 23337 break; 23338 case Utils::Shader::VERTEX: 23339 source = vs; 23340 break; 23341 default: 23342 source = ""; 23343 } 23344 } 23345 23346 return source; 23347 } 23348 23349 /** Selects if "compute" stage is relevant for test 23350 * 23351 * @param ignored 23352 * 23353 * @return false 23354 **/ 23355 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */) 23356 { 23357 return false; 23358 } 23359 23360 /** Constructor 23361 * 23362 * @param context Test framework context 23363 **/ 23364 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context& context) 23365 : NegativeTestBase(context, "xfb_exceed_buffer_limit", 23366 "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit") 23367 { 23368 } 23369 23370 /** Source for given test case and stage 23371 * 23372 * @param test_case_index Index of test case 23373 * @param stage Shader stage 23374 * 23375 * @return Shader source 23376 **/ 23377 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 23378 { 23379 static const GLchar* block_var_definition = "const uint buffer_index = BUFFER;\n" 23380 "\n" 23381 "layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n" 23382 " vec4 member;\n" 23383 "} gokuARRAY;\n"; 23384 static const GLchar* global_var_definition = "const uint buffer_index = BUFFER;\n" 23385 "\n" 23386 "layout (xfb_buffer = buffer_index) out;\n"; 23387 static const GLchar* vector_var_definition = "const uint buffer_index = BUFFER;\n" 23388 "\n" 23389 "layout (xfb_buffer = buffer_index) out vec4 gokuARRAY;\n"; 23390 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n"; 23391 static const GLchar* global_use = ""; 23392 static const GLchar* vector_use = " gokuINDEX = result / 2;\n"; 23393 static const GLchar* fs = "#version 430 core\n" 23394 "#extension GL_ARB_enhanced_layouts : require\n" 23395 "\n" 23396 "in vec4 gs_fs;\n" 23397 "out vec4 fs_out;\n" 23398 "\n" 23399 "void main()\n" 23400 "{\n" 23401 " fs_out = gs_fs;\n" 23402 "}\n" 23403 "\n"; 23404 static const GLchar* gs_tested = "#version 430 core\n" 23405 "#extension GL_ARB_enhanced_layouts : require\n" 23406 "\n" 23407 "layout(points) in;\n" 23408 "layout(triangle_strip, max_vertices = 4) out;\n" 23409 "\n" 23410 "VAR_DEFINITION" 23411 "\n" 23412 "in vec4 tes_gs[];\n" 23413 "out vec4 gs_fs;\n" 23414 "\n" 23415 "void main()\n" 23416 "{\n" 23417 " vec4 result = tes_gs[0];\n" 23418 "\n" 23419 "VARIABLE_USE" 23420 "\n" 23421 " gs_fs = result;\n" 23422 " gl_Position = vec4(-1, -1, 0, 1);\n" 23423 " EmitVertex();\n" 23424 " gs_fs = result;\n" 23425 " gl_Position = vec4(-1, 1, 0, 1);\n" 23426 " EmitVertex();\n" 23427 " gs_fs = result;\n" 23428 " gl_Position = vec4(1, -1, 0, 1);\n" 23429 " EmitVertex();\n" 23430 " gs_fs = result;\n" 23431 " gl_Position = vec4(1, 1, 0, 1);\n" 23432 " EmitVertex();\n" 23433 "}\n" 23434 "\n"; 23435 static const GLchar* tcs = "#version 430 core\n" 23436 "#extension GL_ARB_enhanced_layouts : require\n" 23437 "\n" 23438 "layout(vertices = 1) out;\n" 23439 "\n" 23440 "in vec4 vs_tcs[];\n" 23441 "out vec4 tcs_tes[];\n" 23442 "\n" 23443 "void main()\n" 23444 "{\n" 23445 "\n" 23446 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 23447 "\n" 23448 " gl_TessLevelOuter[0] = 1.0;\n" 23449 " gl_TessLevelOuter[1] = 1.0;\n" 23450 " gl_TessLevelOuter[2] = 1.0;\n" 23451 " gl_TessLevelOuter[3] = 1.0;\n" 23452 " gl_TessLevelInner[0] = 1.0;\n" 23453 " gl_TessLevelInner[1] = 1.0;\n" 23454 "}\n" 23455 "\n"; 23456 static const GLchar* tcs_tested = "#version 430 core\n" 23457 "#extension GL_ARB_enhanced_layouts : require\n" 23458 "\n" 23459 "layout(vertices = 1) out;\n" 23460 "\n" 23461 "VAR_DEFINITION" 23462 "\n" 23463 "in vec4 vs_tcs[];\n" 23464 "out vec4 tcs_tes[];\n" 23465 "\n" 23466 "void main()\n" 23467 "{\n" 23468 " vec4 result = vs_tcs[gl_InvocationID];\n" 23469 "\n" 23470 "VARIABLE_USE" 23471 "\n" 23472 " tcs_tes[gl_InvocationID] = result;\n" 23473 "\n" 23474 " gl_TessLevelOuter[0] = 1.0;\n" 23475 " gl_TessLevelOuter[1] = 1.0;\n" 23476 " gl_TessLevelOuter[2] = 1.0;\n" 23477 " gl_TessLevelOuter[3] = 1.0;\n" 23478 " gl_TessLevelInner[0] = 1.0;\n" 23479 " gl_TessLevelInner[1] = 1.0;\n" 23480 "}\n" 23481 "\n"; 23482 static const GLchar* tes_tested = "#version 430 core\n" 23483 "#extension GL_ARB_enhanced_layouts : require\n" 23484 "\n" 23485 "layout(isolines, point_mode) in;\n" 23486 "\n" 23487 "VAR_DEFINITION" 23488 "\n" 23489 "in vec4 tcs_tes[];\n" 23490 "out vec4 tes_gs;\n" 23491 "\n" 23492 "void main()\n" 23493 "{\n" 23494 " vec4 result = tcs_tes[0];\n" 23495 "\n" 23496 "VARIABLE_USE" 23497 "\n" 23498 " tes_gs += result;\n" 23499 "}\n" 23500 "\n"; 23501 static const GLchar* vs = "#version 430 core\n" 23502 "#extension GL_ARB_enhanced_layouts : require\n" 23503 "\n" 23504 "in vec4 in_vs;\n" 23505 "out vec4 vs_tcs;\n" 23506 "\n" 23507 "void main()\n" 23508 "{\n" 23509 " vs_tcs = in_vs;\n" 23510 "}\n" 23511 "\n"; 23512 static const GLchar* vs_tested = "#version 430 core\n" 23513 "#extension GL_ARB_enhanced_layouts : require\n" 23514 "\n" 23515 "VAR_DEFINITION" 23516 "\n" 23517 "in vec4 in_vs;\n" 23518 "out vec4 vs_tcs;\n" 23519 "\n" 23520 "void main()\n" 23521 "{\n" 23522 " vec4 result = in_vs;\n" 23523 "\n" 23524 "VARIABLE_USE" 23525 "\n" 23526 " vs_tcs = result;\n" 23527 "}\n" 23528 "\n"; 23529 23530 std::string source; 23531 testCase& test_case = m_test_cases[test_case_index]; 23532 23533 if (test_case.m_stage == stage) 23534 { 23535 const GLchar* array = ""; 23536 GLchar buffer[16]; 23537 const Functions& gl = m_context.getRenderContext().getFunctions(); 23538 const GLchar* index = ""; 23539 GLint max_n_xfb = 0; 23540 size_t position = 0; 23541 size_t temp; 23542 const GLchar* var_definition = 0; 23543 const GLchar* var_use = 0; 23544 23545 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb); 23546 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 23547 23548 sprintf(buffer, "%d", max_n_xfb); 23549 23550 switch (test_case.m_case) 23551 { 23552 case BLOCK: 23553 var_definition = block_var_definition; 23554 var_use = block_use; 23555 break; 23556 case GLOBAL: 23557 var_definition = global_var_definition; 23558 var_use = global_use; 23559 break; 23560 case VECTOR: 23561 var_definition = vector_var_definition; 23562 var_use = vector_use; 23563 break; 23564 default: 23565 TCU_FAIL("Invalid enum"); 23566 } 23567 23568 switch (stage) 23569 { 23570 case Utils::Shader::GEOMETRY: 23571 source = gs_tested; 23572 array = "[]"; 23573 index = "[0]"; 23574 break; 23575 case Utils::Shader::TESS_CTRL: 23576 source = tcs_tested; 23577 array = "[]"; 23578 index = "[gl_InvocationID]"; 23579 break; 23580 case Utils::Shader::TESS_EVAL: 23581 source = tes_tested; 23582 array = "[]"; 23583 index = "[0]"; 23584 break; 23585 case Utils::Shader::VERTEX: 23586 source = vs_tested; 23587 break; 23588 default: 23589 TCU_FAIL("Invalid enum"); 23590 } 23591 23592 temp = position; 23593 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 23594 position = temp; 23595 Utils::replaceToken("BUFFER", position, buffer, source); 23596 if (GLOBAL != test_case.m_case) 23597 { 23598 Utils::replaceToken("ARRAY", position, array, source); 23599 } 23600 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 23601 23602 Utils::replaceAllTokens("INDEX", index, source); 23603 } 23604 else 23605 { 23606 switch (test_case.m_stage) 23607 { 23608 case Utils::Shader::GEOMETRY: 23609 switch (stage) 23610 { 23611 case Utils::Shader::FRAGMENT: 23612 source = fs; 23613 break; 23614 case Utils::Shader::VERTEX: 23615 source = vs; 23616 break; 23617 default: 23618 source = ""; 23619 } 23620 break; 23621 case Utils::Shader::TESS_CTRL: 23622 switch (stage) 23623 { 23624 case Utils::Shader::FRAGMENT: 23625 source = fs; 23626 break; 23627 case Utils::Shader::VERTEX: 23628 source = vs; 23629 break; 23630 default: 23631 source = ""; 23632 } 23633 break; 23634 case Utils::Shader::TESS_EVAL: 23635 switch (stage) 23636 { 23637 case Utils::Shader::FRAGMENT: 23638 source = fs; 23639 break; 23640 case Utils::Shader::TESS_CTRL: 23641 source = tcs; 23642 break; 23643 case Utils::Shader::VERTEX: 23644 source = vs; 23645 break; 23646 default: 23647 source = ""; 23648 } 23649 break; 23650 case Utils::Shader::VERTEX: 23651 switch (stage) 23652 { 23653 case Utils::Shader::FRAGMENT: 23654 source = fs; 23655 break; 23656 default: 23657 source = ""; 23658 } 23659 break; 23660 default: 23661 TCU_FAIL("Invalid enum"); 23662 break; 23663 } 23664 } 23665 23666 return source; 23667 } 23668 23669 /** Get description of test case 23670 * 23671 * @param test_case_index Index of test case 23672 * 23673 * @return Test case description 23674 **/ 23675 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index) 23676 { 23677 std::stringstream stream; 23678 testCase& test_case = m_test_cases[test_case_index]; 23679 23680 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: "; 23681 23682 switch (test_case.m_case) 23683 { 23684 case BLOCK: 23685 stream << "BLOCK"; 23686 break; 23687 case GLOBAL: 23688 stream << "GLOBAL"; 23689 break; 23690 case VECTOR: 23691 stream << "VECTOR"; 23692 break; 23693 default: 23694 TCU_FAIL("Invalid enum"); 23695 } 23696 23697 return stream.str(); 23698 } 23699 23700 /** Get number of test cases 23701 * 23702 * @return Number of test cases 23703 **/ 23704 GLuint XFBExceedBufferLimitTest::getTestCaseNumber() 23705 { 23706 return static_cast<GLuint>(m_test_cases.size()); 23707 } 23708 23709 /** Selects if "compute" stage is relevant for test 23710 * 23711 * @param ignored 23712 * 23713 * @return false 23714 **/ 23715 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */) 23716 { 23717 return false; 23718 } 23719 23720 /** Prepare all test cases 23721 * 23722 **/ 23723 void XFBExceedBufferLimitTest::testInit() 23724 { 23725 for (GLuint c = 0; c < CASE_MAX; ++c) 23726 { 23727 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 23728 { 23729 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 23730 (Utils::Shader::FRAGMENT == stage)) 23731 { 23732 continue; 23733 } 23734 23735 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage }; 23736 23737 m_test_cases.push_back(test_case); 23738 } 23739 } 23740 } 23741 23742 /** Constructor 23743 * 23744 * @param context Test framework context 23745 **/ 23746 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context& context) 23747 : NegativeTestBase(context, "xfb_exceed_offset_limit", 23748 "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit") 23749 { 23750 } 23751 23752 /** Source for given test case and stage 23753 * 23754 * @param test_case_index Index of test case 23755 * @param stage Shader stage 23756 * 23757 * @return Shader source 23758 **/ 23759 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 23760 { 23761 static const GLchar* block_var_definition = "const uint max_size = SIZE;\n" 23762 "\n" 23763 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out Goku {\n" 23764 " vec4 member;\n" 23765 "} gokuARRAY;\n"; 23766 static const GLchar* global_var_definition = "const uint max_size = SIZE;\n" 23767 "\n" 23768 "layout (xfb_buffer = 0, xfb_stride = max_size + 16) out;\n"; 23769 static const GLchar* vector_var_definition = 23770 "const uint max_size = SIZE;\n" 23771 "\n" 23772 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out vec4 gokuARRAY;\n"; 23773 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n"; 23774 static const GLchar* global_use = ""; 23775 static const GLchar* vector_use = " gokuINDEX = result / 2;\n"; 23776 static const GLchar* fs = "#version 430 core\n" 23777 "#extension GL_ARB_enhanced_layouts : require\n" 23778 "\n" 23779 "in vec4 gs_fs;\n" 23780 "out vec4 fs_out;\n" 23781 "\n" 23782 "void main()\n" 23783 "{\n" 23784 " fs_out = gs_fs;\n" 23785 "}\n" 23786 "\n"; 23787 static const GLchar* gs_tested = "#version 430 core\n" 23788 "#extension GL_ARB_enhanced_layouts : require\n" 23789 "\n" 23790 "layout(points) in;\n" 23791 "layout(triangle_strip, max_vertices = 4) out;\n" 23792 "\n" 23793 "VAR_DEFINITION" 23794 "\n" 23795 "in vec4 tes_gs[];\n" 23796 "out vec4 gs_fs;\n" 23797 "\n" 23798 "void main()\n" 23799 "{\n" 23800 " vec4 result = tes_gs[0];\n" 23801 "\n" 23802 "VARIABLE_USE" 23803 "\n" 23804 " gs_fs = result;\n" 23805 " gl_Position = vec4(-1, -1, 0, 1);\n" 23806 " EmitVertex();\n" 23807 " gs_fs = result;\n" 23808 " gl_Position = vec4(-1, 1, 0, 1);\n" 23809 " EmitVertex();\n" 23810 " gs_fs = result;\n" 23811 " gl_Position = vec4(1, -1, 0, 1);\n" 23812 " EmitVertex();\n" 23813 " gs_fs = result;\n" 23814 " gl_Position = vec4(1, 1, 0, 1);\n" 23815 " EmitVertex();\n" 23816 "}\n" 23817 "\n"; 23818 static const GLchar* tcs = "#version 430 core\n" 23819 "#extension GL_ARB_enhanced_layouts : require\n" 23820 "\n" 23821 "layout(vertices = 1) out;\n" 23822 "\n" 23823 "in vec4 vs_tcs[];\n" 23824 "out vec4 tcs_tes[];\n" 23825 "\n" 23826 "void main()\n" 23827 "{\n" 23828 "\n" 23829 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 23830 "\n" 23831 " gl_TessLevelOuter[0] = 1.0;\n" 23832 " gl_TessLevelOuter[1] = 1.0;\n" 23833 " gl_TessLevelOuter[2] = 1.0;\n" 23834 " gl_TessLevelOuter[3] = 1.0;\n" 23835 " gl_TessLevelInner[0] = 1.0;\n" 23836 " gl_TessLevelInner[1] = 1.0;\n" 23837 "}\n" 23838 "\n"; 23839 static const GLchar* tcs_tested = "#version 430 core\n" 23840 "#extension GL_ARB_enhanced_layouts : require\n" 23841 "\n" 23842 "layout(vertices = 1) out;\n" 23843 "\n" 23844 "VAR_DEFINITION" 23845 "\n" 23846 "in vec4 vs_tcs[];\n" 23847 "out vec4 tcs_tes[];\n" 23848 "\n" 23849 "void main()\n" 23850 "{\n" 23851 " vec4 result = vs_tcs[gl_InvocationID];\n" 23852 "\n" 23853 "VARIABLE_USE" 23854 "\n" 23855 " tcs_tes[gl_InvocationID] = result;\n" 23856 "\n" 23857 " gl_TessLevelOuter[0] = 1.0;\n" 23858 " gl_TessLevelOuter[1] = 1.0;\n" 23859 " gl_TessLevelOuter[2] = 1.0;\n" 23860 " gl_TessLevelOuter[3] = 1.0;\n" 23861 " gl_TessLevelInner[0] = 1.0;\n" 23862 " gl_TessLevelInner[1] = 1.0;\n" 23863 "}\n" 23864 "\n"; 23865 static const GLchar* tes_tested = "#version 430 core\n" 23866 "#extension GL_ARB_enhanced_layouts : require\n" 23867 "\n" 23868 "layout(isolines, point_mode) in;\n" 23869 "\n" 23870 "VAR_DEFINITION" 23871 "\n" 23872 "in vec4 tcs_tes[];\n" 23873 "out vec4 tes_gs;\n" 23874 "\n" 23875 "void main()\n" 23876 "{\n" 23877 " vec4 result = tcs_tes[0];\n" 23878 "\n" 23879 "VARIABLE_USE" 23880 "\n" 23881 " tes_gs += result;\n" 23882 "}\n" 23883 "\n"; 23884 static const GLchar* vs = "#version 430 core\n" 23885 "#extension GL_ARB_enhanced_layouts : require\n" 23886 "\n" 23887 "in vec4 in_vs;\n" 23888 "out vec4 vs_tcs;\n" 23889 "\n" 23890 "void main()\n" 23891 "{\n" 23892 " vs_tcs = in_vs;\n" 23893 "}\n" 23894 "\n"; 23895 static const GLchar* vs_tested = "#version 430 core\n" 23896 "#extension GL_ARB_enhanced_layouts : require\n" 23897 "\n" 23898 "VAR_DEFINITION" 23899 "\n" 23900 "in vec4 in_vs;\n" 23901 "out vec4 vs_tcs;\n" 23902 "\n" 23903 "void main()\n" 23904 "{\n" 23905 " vec4 result = in_vs;\n" 23906 "\n" 23907 "VARIABLE_USE" 23908 "\n" 23909 " vs_tcs = result;\n" 23910 "}\n" 23911 "\n"; 23912 23913 std::string source; 23914 testCase& test_case = m_test_cases[test_case_index]; 23915 23916 if (test_case.m_stage == stage) 23917 { 23918 const GLchar* array = ""; 23919 GLchar buffer[16]; 23920 const Functions& gl = m_context.getRenderContext().getFunctions(); 23921 const GLchar* index = ""; 23922 GLint max_n_xfb_comp = 0; 23923 GLint max_n_xfb_bytes = 0; 23924 size_t position = 0; 23925 size_t temp; 23926 const GLchar* var_definition = 0; 23927 const GLchar* var_use = 0; 23928 23929 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp); 23930 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 23931 23932 max_n_xfb_bytes = max_n_xfb_comp * 4; 23933 23934 sprintf(buffer, "%d", max_n_xfb_bytes); 23935 23936 switch (test_case.m_case) 23937 { 23938 case BLOCK: 23939 var_definition = block_var_definition; 23940 var_use = block_use; 23941 break; 23942 case GLOBAL: 23943 var_definition = global_var_definition; 23944 var_use = global_use; 23945 break; 23946 case VECTOR: 23947 var_definition = vector_var_definition; 23948 var_use = vector_use; 23949 break; 23950 default: 23951 TCU_FAIL("Invalid enum"); 23952 } 23953 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73) 23954 // change array = "[]" to "[1]" 23955 switch (stage) 23956 { 23957 case Utils::Shader::GEOMETRY: 23958 source = gs_tested; 23959 array = "[1]"; 23960 index = "[0]"; 23961 break; 23962 case Utils::Shader::TESS_CTRL: 23963 source = tcs_tested; 23964 array = "[1]"; 23965 index = "[gl_InvocationID]"; 23966 break; 23967 case Utils::Shader::TESS_EVAL: 23968 source = tes_tested; 23969 array = "[1]"; 23970 index = "[0]"; 23971 break; 23972 case Utils::Shader::VERTEX: 23973 source = vs_tested; 23974 break; 23975 default: 23976 TCU_FAIL("Invalid enum"); 23977 } 23978 23979 temp = position; 23980 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 23981 position = temp; 23982 Utils::replaceToken("SIZE", position, buffer, source); 23983 if (GLOBAL != test_case.m_case) 23984 { 23985 Utils::replaceToken("ARRAY", position, array, source); 23986 } 23987 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 23988 23989 Utils::replaceAllTokens("INDEX", index, source); 23990 } 23991 else 23992 { 23993 switch (test_case.m_stage) 23994 { 23995 case Utils::Shader::GEOMETRY: 23996 switch (stage) 23997 { 23998 case Utils::Shader::FRAGMENT: 23999 source = fs; 24000 break; 24001 case Utils::Shader::VERTEX: 24002 source = vs; 24003 break; 24004 default: 24005 source = ""; 24006 } 24007 break; 24008 case Utils::Shader::TESS_CTRL: 24009 switch (stage) 24010 { 24011 case Utils::Shader::FRAGMENT: 24012 source = fs; 24013 break; 24014 case Utils::Shader::VERTEX: 24015 source = vs; 24016 break; 24017 default: 24018 source = ""; 24019 } 24020 break; 24021 case Utils::Shader::TESS_EVAL: 24022 switch (stage) 24023 { 24024 case Utils::Shader::FRAGMENT: 24025 source = fs; 24026 break; 24027 case Utils::Shader::TESS_CTRL: 24028 source = tcs; 24029 break; 24030 case Utils::Shader::VERTEX: 24031 source = vs; 24032 break; 24033 default: 24034 source = ""; 24035 } 24036 break; 24037 case Utils::Shader::VERTEX: 24038 switch (stage) 24039 { 24040 case Utils::Shader::FRAGMENT: 24041 source = fs; 24042 break; 24043 default: 24044 source = ""; 24045 } 24046 break; 24047 default: 24048 TCU_FAIL("Invalid enum"); 24049 break; 24050 } 24051 } 24052 24053 return source; 24054 } 24055 24056 /** Get description of test case 24057 * 24058 * @param test_case_index Index of test case 24059 * 24060 * @return Test case description 24061 **/ 24062 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index) 24063 { 24064 std::stringstream stream; 24065 testCase& test_case = m_test_cases[test_case_index]; 24066 24067 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: "; 24068 24069 switch (test_case.m_case) 24070 { 24071 case BLOCK: 24072 stream << "BLOCK"; 24073 break; 24074 case GLOBAL: 24075 stream << "GLOBAL"; 24076 break; 24077 case VECTOR: 24078 stream << "VECTOR"; 24079 break; 24080 default: 24081 TCU_FAIL("Invalid enum"); 24082 } 24083 24084 return stream.str(); 24085 } 24086 24087 /** Get number of test cases 24088 * 24089 * @return Number of test cases 24090 **/ 24091 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber() 24092 { 24093 return static_cast<GLuint>(m_test_cases.size()); 24094 } 24095 24096 /** Selects if "compute" stage is relevant for test 24097 * 24098 * @param ignored 24099 * 24100 * @return false 24101 **/ 24102 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */) 24103 { 24104 return false; 24105 } 24106 24107 /** Prepare all test cases 24108 * 24109 **/ 24110 void XFBExceedOffsetLimitTest::testInit() 24111 { 24112 for (GLuint c = 0; c < CASE_MAX; ++c) 24113 { 24114 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 24115 { 24116 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 24117 (Utils::Shader::FRAGMENT == stage)) 24118 { 24119 continue; 24120 } 24121 24122 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage }; 24123 24124 m_test_cases.push_back(test_case); 24125 } 24126 } 24127 } 24128 24129 /** Constructor 24130 * 24131 * @param context Test context 24132 **/ 24133 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context& context) 24134 : BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected") 24135 { 24136 /* Nothing to be done here */ 24137 } 24138 24139 /** Get descriptors of buffers necessary for test 24140 * 24141 * @param test_case_index Index of test case 24142 * @param out_descriptors Descriptors of buffers used by test 24143 **/ 24144 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors) 24145 { 24146 // the function "getType(test_case_index)" can't return correct data type, so change code as following: 24147 const Utils::Type& type = m_test_cases[test_case_index].m_type; 24148 24149 /* Test needs single uniform and two xfbs */ 24150 out_descriptors.resize(3); 24151 24152 /* Get references */ 24153 bufferDescriptor& uniform = out_descriptors[0]; 24154 bufferDescriptor& xfb_1 = out_descriptors[1]; 24155 bufferDescriptor& xfb_3 = out_descriptors[2]; 24156 24157 /* Index */ 24158 uniform.m_index = 0; 24159 xfb_1.m_index = 1; 24160 xfb_3.m_index = 3; 24161 24162 /* Target */ 24163 uniform.m_target = Utils::Buffer::Uniform; 24164 xfb_1.m_target = Utils::Buffer::Transform_feedback; 24165 xfb_3.m_target = Utils::Buffer::Transform_feedback; 24166 24167 /* Data */ 24168 const GLuint gen_start = Utils::s_rand; 24169 const std::vector<GLubyte>& chichi_data = type.GenerateData(); 24170 const std::vector<GLubyte>& bulma_data = type.GenerateData(); 24171 const std::vector<GLubyte>& trunks_data = type.GenerateData(); 24172 const std::vector<GLubyte>& bra_data = type.GenerateData(); 24173 const std::vector<GLubyte>& gohan_data = type.GenerateData(); 24174 const std::vector<GLubyte>& goten_data = type.GenerateData(); 24175 24176 Utils::s_rand = gen_start; 24177 const std::vector<GLubyte>& chichi_data_pck = type.GenerateDataPacked(); 24178 const std::vector<GLubyte>& bulma_data_pck = type.GenerateDataPacked(); 24179 const std::vector<GLubyte>& trunks_data_pck = type.GenerateDataPacked(); 24180 const std::vector<GLubyte>& bra_data_pck = type.GenerateDataPacked(); 24181 const std::vector<GLubyte>& gohan_data_pck = type.GenerateDataPacked(); 24182 const std::vector<GLubyte>& goten_data_pck = type.GenerateDataPacked(); 24183 24184 const GLuint type_size = static_cast<GLuint>(chichi_data.size()); 24185 const GLuint type_size_pck = static_cast<GLuint>(chichi_data_pck.size()); 24186 24187 /* Uniform data */ 24188 uniform.m_initial_data.resize(6 * type_size); 24189 memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size); 24190 memcpy(&uniform.m_initial_data[0] + type_size, &bulma_data[0], type_size); 24191 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &trunks_data[0], type_size); 24192 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &bra_data[0], type_size); 24193 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &gohan_data[0], type_size); 24194 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &goten_data[0], type_size); 24195 24196 /* XFB data */ 24197 xfb_1.m_initial_data.resize(3 * type_size_pck); 24198 xfb_1.m_expected_data.resize(3 * type_size_pck); 24199 xfb_3.m_initial_data.resize(3 * type_size_pck); 24200 xfb_3.m_expected_data.resize(3 * type_size_pck); 24201 24202 for (GLuint i = 0; i < 3 * type_size_pck; ++i) 24203 { 24204 xfb_1.m_initial_data[i] = (glw::GLubyte)i; 24205 xfb_1.m_expected_data[i] = (glw::GLubyte)i; 24206 xfb_3.m_initial_data[i] = (glw::GLubyte)i; 24207 xfb_3.m_expected_data[i] = (glw::GLubyte)i; 24208 } 24209 24210 memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck); 24211 memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck); 24212 memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck); 24213 memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck); 24214 memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck); 24215 memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck); 24216 } 24217 24218 /** Source for given test case and stage 24219 * 24220 * @param test_case_index Index of test case 24221 * @param stage Shader stage 24222 * 24223 * @return Shader source 24224 **/ 24225 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 24226 { 24227 static const GLchar* fs = 24228 "#version 430 core\n" 24229 "#extension GL_ARB_enhanced_layouts : require\n" 24230 "\n" 24231 "flat in TYPE chichi;\n" 24232 "flat in TYPE bulma;\n" 24233 "in Vegeta {\n" 24234 " flat TYPE trunk;\n" 24235 " flat TYPE bra;\n" 24236 "} vegeta;\n" 24237 "in Goku {\n" 24238 " flat TYPE gohan;\n" 24239 " flat TYPE goten;\n" 24240 "} goku;\n" 24241 "\n" 24242 "out vec4 fs_out;\n" 24243 "\n" 24244 "void main()\n" 24245 "{\n" 24246 " fs_out = vec4(1);\n" 24247 " if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n" 24248 " {\n" 24249 " fs_out = vec4(0);\n" 24250 " }\n" 24251 "}\n" 24252 "\n"; 24253 24254 static const GLchar* gs = "#version 430 core\n" 24255 "#extension GL_ARB_enhanced_layouts : require\n" 24256 "\n" 24257 "layout(points) in;\n" 24258 "layout(points, max_vertices = 1) out;\n" 24259 "\n" 24260 "INTERFACE" 24261 "\n" 24262 "void main()\n" 24263 "{\n" 24264 "ASSIGNMENTS" 24265 " EmitVertex();\n" 24266 "}\n" 24267 "\n"; 24268 24269 static const GLchar* tcs = "#version 430 core\n" 24270 "#extension GL_ARB_enhanced_layouts : require\n" 24271 "\n" 24272 "layout(vertices = 1) out;\n" 24273 "\n" 24274 "\n" 24275 "void main()\n" 24276 "{\n" 24277 " gl_TessLevelOuter[0] = 1.0;\n" 24278 " gl_TessLevelOuter[1] = 1.0;\n" 24279 " gl_TessLevelOuter[2] = 1.0;\n" 24280 " gl_TessLevelOuter[3] = 1.0;\n" 24281 " gl_TessLevelInner[0] = 1.0;\n" 24282 " gl_TessLevelInner[1] = 1.0;\n" 24283 "}\n" 24284 "\n"; 24285 24286 static const GLchar* tes = "#version 430 core\n" 24287 "#extension GL_ARB_enhanced_layouts : require\n" 24288 "\n" 24289 "layout(isolines, point_mode) in;\n" 24290 "\n" 24291 "INTERFACE" 24292 "\n" 24293 "void main()\n" 24294 "{\n" 24295 "ASSIGNMENTS" 24296 "}\n" 24297 "\n"; 24298 24299 static const GLchar* vs = "#version 430 core\n" 24300 "#extension GL_ARB_enhanced_layouts : require\n" 24301 "\n" 24302 "void main()\n" 24303 "{\n" 24304 "}\n" 24305 "\n"; 24306 24307 static const GLchar* vs_tested = "#version 430 core\n" 24308 "#extension GL_ARB_enhanced_layouts : require\n" 24309 "\n" 24310 "INTERFACE" 24311 "\n" 24312 "void main()\n" 24313 "{\n" 24314 "ASSIGNMENTS" 24315 "}\n" 24316 "\n"; 24317 24318 std::string source; 24319 const _testCase& test_case = m_test_cases[test_case_index]; 24320 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 24321 24322 if (test_case.m_stage == stage) 24323 { 24324 std::string assignments = " chichi = uni_chichi;\n" 24325 " bulma = uni_bulma;\n" 24326 " vegeta.trunk = uni_trunk;\n" 24327 " vegeta.bra = uni_bra;\n" 24328 " goku.gohan = uni_gohan;\n" 24329 " goku.goten = uni_goten;\n"; 24330 24331 std::string interface = "layout (xfb_buffer = 3) out;\n" 24332 "\n" 24333 "const uint type_size = SIZE;\n" 24334 "\n" 24335 "layout ( xfb_offset = 2 * type_size) flat out TYPE chichi;\n" 24336 "layout (xfb_buffer = 1, xfb_offset = 0) flat out TYPE bulma;\n" 24337 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n" 24338 " flat TYPE trunk;\n" 24339 " flat TYPE bra;\n" 24340 "} vegeta;\n" 24341 "layout ( xfb_offset = 0) out Goku {\n" 24342 " flat TYPE gohan;\n" 24343 " flat TYPE goten;\n" 24344 "} goku;\n" 24345 "\n" 24346 // Uniform block must be declared with std140, otherwise each block member is not packed 24347 "layout(binding = 0, std140) uniform block {\n" 24348 " TYPE uni_chichi;\n" 24349 " TYPE uni_bulma;\n" 24350 " TYPE uni_trunk;\n" 24351 " TYPE uni_bra;\n" 24352 " TYPE uni_gohan;\n" 24353 " TYPE uni_goten;\n" 24354 "};\n"; 24355 24356 /* Prepare interface string */ 24357 { 24358 GLchar buffer[16]; 24359 size_t position = 0; 24360 const GLuint type_size = test_case.m_type.GetSize(); 24361 24362 sprintf(buffer, "%d", type_size); 24363 24364 Utils::replaceToken("SIZE", position, buffer, interface); 24365 Utils::replaceAllTokens("TYPE", type_name, interface); 24366 } 24367 24368 switch (stage) 24369 { 24370 case Utils::Shader::GEOMETRY: 24371 source = gs; 24372 break; 24373 case Utils::Shader::TESS_EVAL: 24374 source = tes; 24375 break; 24376 case Utils::Shader::VERTEX: 24377 source = vs_tested; 24378 break; 24379 default: 24380 TCU_FAIL("Invalid enum"); 24381 } 24382 24383 /* Replace tokens */ 24384 { 24385 size_t position = 0; 24386 24387 Utils::replaceToken("INTERFACE", position, interface.c_str(), source); 24388 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source); 24389 } 24390 } 24391 else 24392 { 24393 switch (test_case.m_stage) 24394 { 24395 case Utils::Shader::GEOMETRY: 24396 switch (stage) 24397 { 24398 case Utils::Shader::FRAGMENT: 24399 source = fs; 24400 Utils::replaceAllTokens("TYPE", type_name, source); 24401 break; 24402 case Utils::Shader::VERTEX: 24403 source = vs; 24404 break; 24405 default: 24406 source = ""; 24407 } 24408 break; 24409 case Utils::Shader::TESS_EVAL: 24410 switch (stage) 24411 { 24412 case Utils::Shader::FRAGMENT: 24413 source = fs; 24414 Utils::replaceAllTokens("TYPE", type_name, source); 24415 break; 24416 case Utils::Shader::TESS_CTRL: 24417 source = tcs; 24418 break; 24419 case Utils::Shader::VERTEX: 24420 source = vs; 24421 break; 24422 default: 24423 source = ""; 24424 } 24425 break; 24426 case Utils::Shader::VERTEX: 24427 switch (stage) 24428 { 24429 case Utils::Shader::FRAGMENT: 24430 source = fs; 24431 Utils::replaceAllTokens("TYPE", type_name, source); 24432 break; 24433 default: 24434 source = ""; 24435 } 24436 break; 24437 default: 24438 TCU_FAIL("Invalid enum"); 24439 break; 24440 } 24441 } 24442 24443 return source; 24444 } 24445 24446 /** Get name of test case 24447 * 24448 * @param test_case_index Index of test case 24449 * 24450 * @return Name of case 24451 **/ 24452 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index) 24453 { 24454 std::string name; 24455 const _testCase& test_case = m_test_cases[test_case_index]; 24456 24457 name = "Tested stage: "; 24458 name.append(Utils::Shader::GetStageName(test_case.m_stage)); 24459 name.append(". Tested type: "); 24460 name.append(test_case.m_type.GetGLSLTypeName()); 24461 24462 return name; 24463 } 24464 24465 /** Get number of cases 24466 * 24467 * @return Number of test cases 24468 **/ 24469 GLuint XFBGlobalBufferTest::getTestCaseNumber() 24470 { 24471 return static_cast<GLuint>(m_test_cases.size()); 24472 } 24473 24474 /** Prepare set of test cases 24475 * 24476 **/ 24477 void XFBGlobalBufferTest::testInit() 24478 { 24479 GLuint n_types = getTypesNumber(); 24480 24481 for (GLuint i = 0; i < n_types; ++i) 24482 { 24483 const Utils::Type& type = getType(i); 24484 /* 24485 When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will 24486 cause a link time error. 24487 */ 24488 if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 || 24489 strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0) 24490 { 24491 continue; 24492 } 24493 const _testCase test_cases[] = { { Utils::Shader::VERTEX, type }, 24494 { Utils::Shader::GEOMETRY, type }, 24495 { Utils::Shader::TESS_EVAL, type } }; 24496 24497 m_test_cases.push_back(test_cases[0]); 24498 m_test_cases.push_back(test_cases[1]); 24499 m_test_cases.push_back(test_cases[2]); 24500 } 24501 } 24502 24503 /** Constructor 24504 * 24505 * @param context Test context 24506 **/ 24507 XFBStrideTest::XFBStrideTest(deqp::Context& context) 24508 : BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types") 24509 { 24510 /* Nothing to be done here */ 24511 } 24512 24513 /** Execute drawArrays for single vertex 24514 * 24515 * @param test_case_index 24516 * 24517 * @return true 24518 **/ 24519 bool XFBStrideTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 24520 { 24521 const Functions& gl = m_context.getRenderContext().getFunctions(); 24522 GLenum primitive_type = GL_PATCHES; 24523 const testCase& test_case = m_test_cases[test_case_index]; 24524 24525 if (Utils::Shader::VERTEX == test_case.m_stage) 24526 { 24527 primitive_type = GL_POINTS; 24528 } 24529 24530 gl.disable(GL_RASTERIZER_DISCARD); 24531 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 24532 24533 gl.beginTransformFeedback(GL_POINTS); 24534 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 24535 24536 gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */); 24537 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 24538 24539 gl.endTransformFeedback(); 24540 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 24541 24542 return true; 24543 } 24544 24545 /** Get descriptors of buffers necessary for test 24546 * 24547 * @param test_case_index Index of test case 24548 * @param out_descriptors Descriptors of buffers used by test 24549 **/ 24550 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors) 24551 { 24552 const testCase& test_case = m_test_cases[test_case_index]; 24553 const Utils::Type& type = test_case.m_type; 24554 24555 /* Test needs single uniform and xfb */ 24556 out_descriptors.resize(2); 24557 24558 /* Get references */ 24559 bufferDescriptor& uniform = out_descriptors[0]; 24560 bufferDescriptor& xfb = out_descriptors[1]; 24561 24562 /* Index */ 24563 uniform.m_index = 0; 24564 xfb.m_index = 0; 24565 24566 /* Target */ 24567 uniform.m_target = Utils::Buffer::Uniform; 24568 xfb.m_target = Utils::Buffer::Transform_feedback; 24569 24570 /* Data */ 24571 const GLuint rand_start = Utils::s_rand; 24572 const std::vector<GLubyte>& uniform_data = type.GenerateData(); 24573 24574 Utils::s_rand = rand_start; 24575 const std::vector<GLubyte>& xfb_data = type.GenerateDataPacked(); 24576 24577 const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size()); 24578 const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size()); 24579 /* 24580 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer, 24581 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;", 24582 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader 24583 only one valid data should be initialized in xfb.m_expected_data 24584 */ 24585 const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2; 24586 /* Uniform data */ 24587 uniform.m_initial_data.resize(uni_type_size); 24588 memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size); 24589 24590 /* XFB data */ 24591 xfb.m_initial_data.resize(xfb_data_size); 24592 xfb.m_expected_data.resize(xfb_data_size); 24593 24594 for (GLuint i = 0; i < xfb_data_size; ++i) 24595 { 24596 xfb.m_initial_data[i] = (glw::GLubyte)i; 24597 xfb.m_expected_data[i] = (glw::GLubyte)i; 24598 } 24599 24600 if (test_case.m_stage == Utils::Shader::VERTEX) 24601 { 24602 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size); 24603 } 24604 else 24605 { 24606 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size); 24607 memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size); 24608 } 24609 } 24610 24611 /** Get body of main function for given shader stage 24612 * 24613 * @param test_case_index Index of test case 24614 * @param stage Shader stage 24615 * @param out_assignments Set to empty 24616 * @param out_calculations Set to empty 24617 **/ 24618 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments, 24619 std::string& out_calculations) 24620 { 24621 const testCase& test_case = m_test_cases[test_case_index]; 24622 24623 out_calculations = ""; 24624 24625 static const GLchar* vs_tes_gs = " goku = uni_goku;\n"; 24626 static const GLchar* fs = " fs_out = vec4(1, 0.25, 0.5, 0.75);\n" 24627 " if (TYPE(0) == goku)\n" 24628 " {\n" 24629 " fs_out = vec4(1, 0.75, 0.5, 0.5);\n" 24630 " }\n"; 24631 24632 const GLchar* assignments = ""; 24633 24634 if (test_case.m_stage == stage) 24635 { 24636 switch (stage) 24637 { 24638 case Utils::Shader::GEOMETRY: 24639 assignments = vs_tes_gs; 24640 break; 24641 case Utils::Shader::TESS_EVAL: 24642 assignments = vs_tes_gs; 24643 break; 24644 case Utils::Shader::VERTEX: 24645 assignments = vs_tes_gs; 24646 break; 24647 default: 24648 TCU_FAIL("Invalid enum"); 24649 } 24650 } 24651 else 24652 { 24653 switch (stage) 24654 { 24655 case Utils::Shader::FRAGMENT: 24656 assignments = fs; 24657 break; 24658 case Utils::Shader::GEOMETRY: 24659 case Utils::Shader::TESS_CTRL: 24660 case Utils::Shader::TESS_EVAL: 24661 case Utils::Shader::VERTEX: 24662 break; 24663 default: 24664 TCU_FAIL("Invalid enum"); 24665 } 24666 } 24667 24668 out_assignments = assignments; 24669 24670 if (Utils::Shader::FRAGMENT == stage) 24671 { 24672 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments); 24673 } 24674 } 24675 24676 /** Get interface of shader 24677 * 24678 * @param test_case_index Index of test case 24679 * @param stage Shader stage 24680 * @param out_interface Set to "" 24681 **/ 24682 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface) 24683 { 24684 static const GLchar* vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n" 24685 "\n" 24686 "layout(std140, binding = 0) uniform Goku {\n" 24687 " TYPE uni_goku;\n" 24688 "};\n"; 24689 static const GLchar* fs = "FLAT in TYPE goku;\n" 24690 "\n" 24691 "out vec4 fs_out;\n"; 24692 24693 const testCase& test_case = m_test_cases[test_case_index]; 24694 const GLchar* interface = ""; 24695 const GLchar* flat = ""; 24696 24697 if (test_case.m_stage == stage) 24698 { 24699 switch (stage) 24700 { 24701 case Utils::Shader::GEOMETRY: 24702 interface = vs_tes_gs; 24703 break; 24704 case Utils::Shader::TESS_EVAL: 24705 interface = vs_tes_gs; 24706 break; 24707 case Utils::Shader::VERTEX: 24708 interface = vs_tes_gs; 24709 break; 24710 default: 24711 TCU_FAIL("Invalid enum"); 24712 } 24713 } 24714 else 24715 { 24716 switch (stage) 24717 { 24718 case Utils::Shader::FRAGMENT: 24719 interface = fs; 24720 break; 24721 case Utils::Shader::GEOMETRY: 24722 case Utils::Shader::TESS_CTRL: 24723 case Utils::Shader::TESS_EVAL: 24724 case Utils::Shader::VERTEX: 24725 break; 24726 default: 24727 TCU_FAIL("Invalid enum"); 24728 } 24729 } 24730 24731 out_interface = interface; 24732 24733 if (Utils::Type::Float != test_case.m_type.m_basic_type) 24734 { 24735 flat = "flat"; 24736 } 24737 24738 Utils::replaceAllTokens("FLAT", flat, out_interface); 24739 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface); 24740 } 24741 24742 /** Get source code of shader 24743 * 24744 * @param test_case_index Index of test case 24745 * @param stage Shader stage 24746 * 24747 * @return Source 24748 **/ 24749 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 24750 { 24751 std::string source; 24752 const testCase& test_case = m_test_cases[test_case_index]; 24753 24754 switch (test_case.m_stage) 24755 { 24756 case Utils::Shader::VERTEX: 24757 switch (stage) 24758 { 24759 case Utils::Shader::FRAGMENT: 24760 case Utils::Shader::VERTEX: 24761 source = BufferTestBase::getShaderSource(test_case_index, stage); 24762 break; 24763 default: 24764 break; 24765 } 24766 break; 24767 24768 case Utils::Shader::TESS_EVAL: 24769 switch (stage) 24770 { 24771 case Utils::Shader::FRAGMENT: 24772 case Utils::Shader::TESS_CTRL: 24773 case Utils::Shader::TESS_EVAL: 24774 case Utils::Shader::VERTEX: 24775 source = BufferTestBase::getShaderSource(test_case_index, stage); 24776 break; 24777 default: 24778 break; 24779 } 24780 break; 24781 24782 case Utils::Shader::GEOMETRY: 24783 source = BufferTestBase::getShaderSource(test_case_index, stage); 24784 break; 24785 24786 default: 24787 TCU_FAIL("Invalid enum"); 24788 break; 24789 } 24790 24791 /* */ 24792 return source; 24793 } 24794 24795 /** Get name of test case 24796 * 24797 * @param test_case_index Index of test case 24798 * 24799 * @return Name of tested stage 24800 **/ 24801 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index) 24802 { 24803 std::stringstream stream; 24804 const testCase& test_case = m_test_cases[test_case_index]; 24805 24806 stream << "Type: " << test_case.m_type.GetGLSLTypeName() 24807 << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage); 24808 24809 return stream.str(); 24810 } 24811 24812 /** Returns number of test cases 24813 * 24814 * @return TEST_MAX 24815 **/ 24816 glw::GLuint XFBStrideTest::getTestCaseNumber() 24817 { 24818 return static_cast<GLuint>(m_test_cases.size()); 24819 } 24820 24821 /** Prepare all test cases 24822 * 24823 **/ 24824 void XFBStrideTest::testInit() 24825 { 24826 const GLuint n_types = getTypesNumber(); 24827 24828 for (GLuint i = 0; i < n_types; ++i) 24829 { 24830 const Utils::Type& type = getType(i); 24831 24832 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 24833 { 24834 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) || 24835 (Utils::Shader::TESS_CTRL == stage)) 24836 { 24837 continue; 24838 } 24839 24840 testCase test_case = { (Utils::Shader::STAGES)stage, type }; 24841 24842 m_test_cases.push_back(test_case); 24843 } 24844 } 24845 } 24846 24847 /** Constructor 24848 * 24849 * @param context Test framework context 24850 **/ 24851 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context& context) 24852 : NegativeTestBase( 24853 context, "xfb_block_member_buffer", 24854 "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer") 24855 { 24856 } 24857 24858 /** Source for given test case and stage 24859 * 24860 * @param test_case_index Index of test case 24861 * @param stage Shader stage 24862 * 24863 * @return Shader source 24864 **/ 24865 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 24866 { 24867 static const GLchar* var_definition = "layout (xfb_offset = 0) out Goku {\n" 24868 " vec4 gohan;\n" 24869 " layout (xfb_buffer = 1) vec4 goten;\n" 24870 "} gokuARRAY;\n"; 24871 static const GLchar* var_use = " gokuINDEX.gohan = result / 2;\n" 24872 " gokuINDEX.goten = result / 4;\n"; 24873 static const GLchar* fs = "#version 430 core\n" 24874 "#extension GL_ARB_enhanced_layouts : require\n" 24875 "\n" 24876 "in vec4 gs_fs;\n" 24877 "out vec4 fs_out;\n" 24878 "\n" 24879 "void main()\n" 24880 "{\n" 24881 " fs_out = gs_fs;\n" 24882 "}\n" 24883 "\n"; 24884 static const GLchar* gs_tested = "#version 430 core\n" 24885 "#extension GL_ARB_enhanced_layouts : require\n" 24886 "\n" 24887 "layout(points) in;\n" 24888 "layout(triangle_strip, max_vertices = 4) out;\n" 24889 "\n" 24890 "VAR_DEFINITION" 24891 "\n" 24892 "in vec4 tes_gs[];\n" 24893 "out vec4 gs_fs;\n" 24894 "\n" 24895 "void main()\n" 24896 "{\n" 24897 " vec4 result = tes_gs[0];\n" 24898 "\n" 24899 "VARIABLE_USE" 24900 "\n" 24901 " gs_fs = result;\n" 24902 " gl_Position = vec4(-1, -1, 0, 1);\n" 24903 " EmitVertex();\n" 24904 " gs_fs = result;\n" 24905 " gl_Position = vec4(-1, 1, 0, 1);\n" 24906 " EmitVertex();\n" 24907 " gs_fs = result;\n" 24908 " gl_Position = vec4(1, -1, 0, 1);\n" 24909 " EmitVertex();\n" 24910 " gs_fs = result;\n" 24911 " gl_Position = vec4(1, 1, 0, 1);\n" 24912 " EmitVertex();\n" 24913 "}\n" 24914 "\n"; 24915 static const GLchar* tcs = "#version 430 core\n" 24916 "#extension GL_ARB_enhanced_layouts : require\n" 24917 "\n" 24918 "layout(vertices = 1) out;\n" 24919 "\n" 24920 "in vec4 vs_tcs[];\n" 24921 "out vec4 tcs_tes[];\n" 24922 "\n" 24923 "void main()\n" 24924 "{\n" 24925 "\n" 24926 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 24927 "\n" 24928 " gl_TessLevelOuter[0] = 1.0;\n" 24929 " gl_TessLevelOuter[1] = 1.0;\n" 24930 " gl_TessLevelOuter[2] = 1.0;\n" 24931 " gl_TessLevelOuter[3] = 1.0;\n" 24932 " gl_TessLevelInner[0] = 1.0;\n" 24933 " gl_TessLevelInner[1] = 1.0;\n" 24934 "}\n" 24935 "\n"; 24936 static const GLchar* tcs_tested = "#version 430 core\n" 24937 "#extension GL_ARB_enhanced_layouts : require\n" 24938 "\n" 24939 "layout(vertices = 1) out;\n" 24940 "\n" 24941 "VAR_DEFINITION" 24942 "\n" 24943 "in vec4 vs_tcs[];\n" 24944 "out vec4 tcs_tes[];\n" 24945 "\n" 24946 "void main()\n" 24947 "{\n" 24948 " vec4 result = vs_tcs[gl_InvocationID];\n" 24949 "\n" 24950 "VARIABLE_USE" 24951 "\n" 24952 " tcs_tes[gl_InvocationID] = result;\n" 24953 "\n" 24954 " gl_TessLevelOuter[0] = 1.0;\n" 24955 " gl_TessLevelOuter[1] = 1.0;\n" 24956 " gl_TessLevelOuter[2] = 1.0;\n" 24957 " gl_TessLevelOuter[3] = 1.0;\n" 24958 " gl_TessLevelInner[0] = 1.0;\n" 24959 " gl_TessLevelInner[1] = 1.0;\n" 24960 "}\n" 24961 "\n"; 24962 static const GLchar* tes_tested = "#version 430 core\n" 24963 "#extension GL_ARB_enhanced_layouts : require\n" 24964 "\n" 24965 "layout(isolines, point_mode) in;\n" 24966 "\n" 24967 "VAR_DEFINITION" 24968 "\n" 24969 "in vec4 tcs_tes[];\n" 24970 "out vec4 tes_gs;\n" 24971 "\n" 24972 "void main()\n" 24973 "{\n" 24974 " vec4 result = tcs_tes[0];\n" 24975 "\n" 24976 "VARIABLE_USE" 24977 "\n" 24978 " tes_gs += result;\n" 24979 "}\n" 24980 "\n"; 24981 static const GLchar* vs = "#version 430 core\n" 24982 "#extension GL_ARB_enhanced_layouts : require\n" 24983 "\n" 24984 "in vec4 in_vs;\n" 24985 "out vec4 vs_tcs;\n" 24986 "\n" 24987 "void main()\n" 24988 "{\n" 24989 " vs_tcs = in_vs;\n" 24990 "}\n" 24991 "\n"; 24992 static const GLchar* vs_tested = "#version 430 core\n" 24993 "#extension GL_ARB_enhanced_layouts : require\n" 24994 "\n" 24995 "VAR_DEFINITION" 24996 "\n" 24997 "in vec4 in_vs;\n" 24998 "out vec4 vs_tcs;\n" 24999 "\n" 25000 "void main()\n" 25001 "{\n" 25002 " vec4 result = in_vs;\n" 25003 "\n" 25004 "VARIABLE_USE" 25005 "\n" 25006 " vs_tcs = result;\n" 25007 "}\n" 25008 "\n"; 25009 25010 std::string source; 25011 testCase& test_case = m_test_cases[test_case_index]; 25012 25013 if (test_case.m_stage == stage) 25014 { 25015 const GLchar* array = ""; 25016 const GLchar* index = ""; 25017 size_t position = 0; 25018 25019 switch (stage) 25020 { 25021 case Utils::Shader::GEOMETRY: 25022 source = gs_tested; 25023 array = "[]"; 25024 index = "[0]"; 25025 break; 25026 case Utils::Shader::TESS_CTRL: 25027 source = tcs_tested; 25028 array = "[]"; 25029 index = "[gl_InvocationID]"; 25030 break; 25031 case Utils::Shader::TESS_EVAL: 25032 source = tes_tested; 25033 array = "[]"; 25034 index = "[0]"; 25035 break; 25036 case Utils::Shader::VERTEX: 25037 source = vs_tested; 25038 break; 25039 default: 25040 TCU_FAIL("Invalid enum"); 25041 } 25042 25043 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 25044 position = 0; 25045 Utils::replaceToken("ARRAY", position, array, source); 25046 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 25047 25048 Utils::replaceAllTokens("INDEX", index, source); 25049 } 25050 else 25051 { 25052 switch (test_case.m_stage) 25053 { 25054 case Utils::Shader::GEOMETRY: 25055 switch (stage) 25056 { 25057 case Utils::Shader::FRAGMENT: 25058 source = fs; 25059 break; 25060 case Utils::Shader::VERTEX: 25061 source = vs; 25062 break; 25063 default: 25064 source = ""; 25065 } 25066 break; 25067 case Utils::Shader::TESS_CTRL: 25068 switch (stage) 25069 { 25070 case Utils::Shader::FRAGMENT: 25071 source = fs; 25072 break; 25073 case Utils::Shader::VERTEX: 25074 source = vs; 25075 break; 25076 default: 25077 source = ""; 25078 } 25079 break; 25080 case Utils::Shader::TESS_EVAL: 25081 switch (stage) 25082 { 25083 case Utils::Shader::FRAGMENT: 25084 source = fs; 25085 break; 25086 case Utils::Shader::TESS_CTRL: 25087 source = tcs; 25088 break; 25089 case Utils::Shader::VERTEX: 25090 source = vs; 25091 break; 25092 default: 25093 source = ""; 25094 } 25095 break; 25096 case Utils::Shader::VERTEX: 25097 switch (stage) 25098 { 25099 case Utils::Shader::FRAGMENT: 25100 source = fs; 25101 break; 25102 default: 25103 source = ""; 25104 } 25105 break; 25106 default: 25107 TCU_FAIL("Invalid enum"); 25108 break; 25109 } 25110 } 25111 25112 return source; 25113 } 25114 25115 /** Get description of test case 25116 * 25117 * @param test_case_index Index of test case 25118 * 25119 * @return Test case description 25120 **/ 25121 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index) 25122 { 25123 std::stringstream stream; 25124 testCase& test_case = m_test_cases[test_case_index]; 25125 25126 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage); 25127 25128 return stream.str(); 25129 } 25130 25131 /** Get number of test cases 25132 * 25133 * @return Number of test cases 25134 **/ 25135 GLuint XFBBlockMemberBufferTest::getTestCaseNumber() 25136 { 25137 return static_cast<GLuint>(m_test_cases.size()); 25138 } 25139 25140 /** Selects if "compute" stage is relevant for test 25141 * 25142 * @param ignored 25143 * 25144 * @return false 25145 **/ 25146 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */) 25147 { 25148 return false; 25149 } 25150 25151 /** Prepare all test cases 25152 * 25153 **/ 25154 void XFBBlockMemberBufferTest::testInit() 25155 { 25156 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 25157 { 25158 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 25159 (Utils::Shader::FRAGMENT == stage)) 25160 { 25161 continue; 25162 } 25163 25164 testCase test_case = { (Utils::Shader::STAGES)stage }; 25165 25166 m_test_cases.push_back(test_case); 25167 } 25168 } 25169 25170 /** Constructor 25171 * 25172 * @param context Test framework context 25173 **/ 25174 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context& context) 25175 : NegativeTestBase(context, "xfb_output_overlapping", 25176 "Test verifies that compiler reports error when two xfb qualified outputs overlap") 25177 { 25178 } 25179 25180 /** Source for given test case and stage 25181 * 25182 * @param test_case_index Index of test case 25183 * @param stage Shader stage 25184 * 25185 * @return Shader source 25186 **/ 25187 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 25188 { 25189 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n" 25190 "layout (xfb_offset = OFFSET) out TYPE gotenARRAY;\n"; 25191 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n" 25192 " gotenINDEX = TYPE(1);\n" 25193 " if (vec4(0) == result)\n" 25194 " {\n" 25195 " gohanINDEX = TYPE(1);\n" 25196 " gotenINDEX = TYPE(0);\n" 25197 " }\n"; 25198 static const GLchar* fs = "#version 430 core\n" 25199 "#extension GL_ARB_enhanced_layouts : require\n" 25200 "\n" 25201 "in vec4 gs_fs;\n" 25202 "out vec4 fs_out;\n" 25203 "\n" 25204 "void main()\n" 25205 "{\n" 25206 " fs_out = gs_fs;\n" 25207 "}\n" 25208 "\n"; 25209 static const GLchar* gs_tested = "#version 430 core\n" 25210 "#extension GL_ARB_enhanced_layouts : require\n" 25211 "\n" 25212 "layout(points) in;\n" 25213 "layout(triangle_strip, max_vertices = 4) out;\n" 25214 "\n" 25215 "VAR_DEFINITION" 25216 "\n" 25217 "in vec4 tes_gs[];\n" 25218 "out vec4 gs_fs;\n" 25219 "\n" 25220 "void main()\n" 25221 "{\n" 25222 " vec4 result = tes_gs[0];\n" 25223 "\n" 25224 "VARIABLE_USE" 25225 "\n" 25226 " gs_fs = result;\n" 25227 " gl_Position = vec4(-1, -1, 0, 1);\n" 25228 " EmitVertex();\n" 25229 " gs_fs = result;\n" 25230 " gl_Position = vec4(-1, 1, 0, 1);\n" 25231 " EmitVertex();\n" 25232 " gs_fs = result;\n" 25233 " gl_Position = vec4(1, -1, 0, 1);\n" 25234 " EmitVertex();\n" 25235 " gs_fs = result;\n" 25236 " gl_Position = vec4(1, 1, 0, 1);\n" 25237 " EmitVertex();\n" 25238 "}\n" 25239 "\n"; 25240 static const GLchar* tcs = "#version 430 core\n" 25241 "#extension GL_ARB_enhanced_layouts : require\n" 25242 "\n" 25243 "layout(vertices = 1) out;\n" 25244 "\n" 25245 "in vec4 vs_tcs[];\n" 25246 "out vec4 tcs_tes[];\n" 25247 "\n" 25248 "void main()\n" 25249 "{\n" 25250 "\n" 25251 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 25252 "\n" 25253 " gl_TessLevelOuter[0] = 1.0;\n" 25254 " gl_TessLevelOuter[1] = 1.0;\n" 25255 " gl_TessLevelOuter[2] = 1.0;\n" 25256 " gl_TessLevelOuter[3] = 1.0;\n" 25257 " gl_TessLevelInner[0] = 1.0;\n" 25258 " gl_TessLevelInner[1] = 1.0;\n" 25259 "}\n" 25260 "\n"; 25261 static const GLchar* tcs_tested = "#version 430 core\n" 25262 "#extension GL_ARB_enhanced_layouts : require\n" 25263 "\n" 25264 "layout(vertices = 1) out;\n" 25265 "\n" 25266 "VAR_DEFINITION" 25267 "\n" 25268 "in vec4 vs_tcs[];\n" 25269 "out vec4 tcs_tes[];\n" 25270 "\n" 25271 "void main()\n" 25272 "{\n" 25273 " vec4 result = vs_tcs[gl_InvocationID];\n" 25274 "\n" 25275 "VARIABLE_USE" 25276 "\n" 25277 " tcs_tes[gl_InvocationID] = result;\n" 25278 "\n" 25279 " gl_TessLevelOuter[0] = 1.0;\n" 25280 " gl_TessLevelOuter[1] = 1.0;\n" 25281 " gl_TessLevelOuter[2] = 1.0;\n" 25282 " gl_TessLevelOuter[3] = 1.0;\n" 25283 " gl_TessLevelInner[0] = 1.0;\n" 25284 " gl_TessLevelInner[1] = 1.0;\n" 25285 "}\n" 25286 "\n"; 25287 static const GLchar* tes_tested = "#version 430 core\n" 25288 "#extension GL_ARB_enhanced_layouts : require\n" 25289 "\n" 25290 "layout(isolines, point_mode) in;\n" 25291 "\n" 25292 "VAR_DEFINITION" 25293 "\n" 25294 "in vec4 tcs_tes[];\n" 25295 "out vec4 tes_gs;\n" 25296 "\n" 25297 "void main()\n" 25298 "{\n" 25299 " vec4 result = tcs_tes[0];\n" 25300 "\n" 25301 "VARIABLE_USE" 25302 "\n" 25303 " tes_gs += result;\n" 25304 "}\n" 25305 "\n"; 25306 static const GLchar* vs = "#version 430 core\n" 25307 "#extension GL_ARB_enhanced_layouts : require\n" 25308 "\n" 25309 "in vec4 in_vs;\n" 25310 "out vec4 vs_tcs;\n" 25311 "\n" 25312 "void main()\n" 25313 "{\n" 25314 " vs_tcs = in_vs;\n" 25315 "}\n" 25316 "\n"; 25317 static const GLchar* vs_tested = "#version 430 core\n" 25318 "#extension GL_ARB_enhanced_layouts : require\n" 25319 "\n" 25320 "VAR_DEFINITION" 25321 "\n" 25322 "in vec4 in_vs;\n" 25323 "out vec4 vs_tcs;\n" 25324 "\n" 25325 "void main()\n" 25326 "{\n" 25327 " vec4 result = in_vs;\n" 25328 "\n" 25329 "VARIABLE_USE" 25330 "\n" 25331 " vs_tcs = result;\n" 25332 "}\n" 25333 "\n"; 25334 25335 std::string source; 25336 testCase& test_case = m_test_cases[test_case_index]; 25337 25338 if (test_case.m_stage == stage) 25339 { 25340 const GLchar* array = ""; 25341 GLchar buffer_gohan[16]; 25342 GLchar buffer_goten[16]; 25343 const GLchar* index = ""; 25344 size_t position = 0; 25345 size_t position_start = 0; 25346 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 25347 25348 sprintf(buffer_gohan, "%d", test_case.m_offset_gohan); 25349 sprintf(buffer_goten, "%d", test_case.m_offset_goten); 25350 25351 switch (stage) 25352 { 25353 case Utils::Shader::GEOMETRY: 25354 source = gs_tested; 25355 array = "[]"; 25356 index = "[0]"; 25357 break; 25358 case Utils::Shader::TESS_CTRL: 25359 source = tcs_tested; 25360 array = "[]"; 25361 index = "[gl_InvocationID]"; 25362 break; 25363 case Utils::Shader::TESS_EVAL: 25364 source = tes_tested; 25365 array = "[]"; 25366 index = "[0]"; 25367 break; 25368 case Utils::Shader::VERTEX: 25369 source = vs_tested; 25370 break; 25371 default: 25372 TCU_FAIL("Invalid enum"); 25373 } 25374 25375 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 25376 position = 0; 25377 Utils::replaceToken("OFFSET", position, buffer_gohan, source); 25378 Utils::replaceToken("TYPE", position, type_name, source); 25379 Utils::replaceToken("ARRAY", position, array, source); 25380 Utils::replaceToken("OFFSET", position, buffer_goten, source); 25381 Utils::replaceToken("TYPE", position, type_name, source); 25382 Utils::replaceToken("ARRAY", position, array, source); 25383 position_start = position; 25384 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 25385 position = position_start; 25386 Utils::replaceToken("INDEX", position, index, source); 25387 Utils::replaceToken("TYPE", position, type_name, source); 25388 Utils::replaceToken("INDEX", position, index, source); 25389 Utils::replaceToken("TYPE", position, type_name, source); 25390 Utils::replaceToken("INDEX", position, index, source); 25391 Utils::replaceToken("TYPE", position, type_name, source); 25392 Utils::replaceToken("INDEX", position, index, source); 25393 Utils::replaceToken("TYPE", position, type_name, source); 25394 } 25395 else 25396 { 25397 switch (test_case.m_stage) 25398 { 25399 case Utils::Shader::GEOMETRY: 25400 switch (stage) 25401 { 25402 case Utils::Shader::FRAGMENT: 25403 source = fs; 25404 break; 25405 case Utils::Shader::VERTEX: 25406 source = vs; 25407 break; 25408 default: 25409 source = ""; 25410 } 25411 break; 25412 case Utils::Shader::TESS_CTRL: 25413 switch (stage) 25414 { 25415 case Utils::Shader::FRAGMENT: 25416 source = fs; 25417 break; 25418 case Utils::Shader::VERTEX: 25419 source = vs; 25420 break; 25421 default: 25422 source = ""; 25423 } 25424 break; 25425 case Utils::Shader::TESS_EVAL: 25426 switch (stage) 25427 { 25428 case Utils::Shader::FRAGMENT: 25429 source = fs; 25430 break; 25431 case Utils::Shader::TESS_CTRL: 25432 source = tcs; 25433 break; 25434 case Utils::Shader::VERTEX: 25435 source = vs; 25436 break; 25437 default: 25438 source = ""; 25439 } 25440 break; 25441 case Utils::Shader::VERTEX: 25442 switch (stage) 25443 { 25444 case Utils::Shader::FRAGMENT: 25445 source = fs; 25446 break; 25447 default: 25448 source = ""; 25449 } 25450 break; 25451 default: 25452 TCU_FAIL("Invalid enum"); 25453 break; 25454 } 25455 } 25456 25457 return source; 25458 } 25459 25460 /** Get description of test case 25461 * 25462 * @param test_case_index Index of test case 25463 * 25464 * @return Test case description 25465 **/ 25466 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index) 25467 { 25468 std::stringstream stream; 25469 testCase& test_case = m_test_cases[test_case_index]; 25470 25471 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 25472 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offsets: " << test_case.m_offset_gohan << " & " 25473 << test_case.m_offset_goten; 25474 25475 return stream.str(); 25476 } 25477 25478 /** Get number of test cases 25479 * 25480 * @return Number of test cases 25481 **/ 25482 GLuint XFBOutputOverlappingTest::getTestCaseNumber() 25483 { 25484 return static_cast<GLuint>(m_test_cases.size()); 25485 } 25486 25487 /** Selects if "compute" stage is relevant for test 25488 * 25489 * @param ignored 25490 * 25491 * @return false 25492 **/ 25493 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */) 25494 { 25495 return false; 25496 } 25497 25498 /** Prepare all test cases 25499 * 25500 **/ 25501 void XFBOutputOverlappingTest::testInit() 25502 { 25503 const GLuint n_types = getTypesNumber(); 25504 25505 for (GLuint i = 0; i < n_types; ++i) 25506 { 25507 const Utils::Type& type = getType(i); 25508 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type); 25509 25510 /* Skip scalars, not applicable as: 25511 * 25512 * The offset must be a multiple of the size of the first component of the first 25513 * qualified variable or block member, or a compile-time error results. 25514 */ 25515 if ((1 == type.m_n_columns) && (1 == type.m_n_rows)) 25516 { 25517 continue; 25518 } 25519 25520 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 25521 { 25522 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 25523 (Utils::Shader::FRAGMENT == stage)) 25524 { 25525 continue; 25526 } 25527 25528 testCase test_case = { 0 /* gohan offset */, base_alingment /* goten_offset */, 25529 (Utils::Shader::STAGES)stage, type }; 25530 25531 m_test_cases.push_back(test_case); 25532 } 25533 } 25534 } 25535 25536 /** Constructor 25537 * 25538 * @param context Test framework context 25539 **/ 25540 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context& context) 25541 : NegativeTestBase(context, "xfb_invalid_offset_alignment", 25542 "Test verifies that compiler reports error when xfb_offset has invalid alignment") 25543 { 25544 } 25545 25546 /** Source for given test case and stage 25547 * 25548 * @param test_case_index Index of test case 25549 * @param stage Shader stage 25550 * 25551 * @return Shader source 25552 **/ 25553 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 25554 { 25555 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n"; 25556 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n" 25557 " if (vec4(0) == result)\n" 25558 " {\n" 25559 " gohanINDEX = TYPE(1);\n" 25560 " }\n"; 25561 static const GLchar* fs = "#version 430 core\n" 25562 "#extension GL_ARB_enhanced_layouts : require\n" 25563 "\n" 25564 "in vec4 gs_fs;\n" 25565 "out vec4 fs_out;\n" 25566 "\n" 25567 "void main()\n" 25568 "{\n" 25569 " fs_out = gs_fs;\n" 25570 "}\n" 25571 "\n"; 25572 static const GLchar* gs_tested = "#version 430 core\n" 25573 "#extension GL_ARB_enhanced_layouts : require\n" 25574 "\n" 25575 "layout(points) in;\n" 25576 "layout(triangle_strip, max_vertices = 4) out;\n" 25577 "\n" 25578 "VAR_DEFINITION" 25579 "\n" 25580 "in vec4 tes_gs[];\n" 25581 "out vec4 gs_fs;\n" 25582 "\n" 25583 "void main()\n" 25584 "{\n" 25585 " vec4 result = tes_gs[0];\n" 25586 "\n" 25587 "VARIABLE_USE" 25588 "\n" 25589 " gs_fs = result;\n" 25590 " gl_Position = vec4(-1, -1, 0, 1);\n" 25591 " EmitVertex();\n" 25592 " gs_fs = result;\n" 25593 " gl_Position = vec4(-1, 1, 0, 1);\n" 25594 " EmitVertex();\n" 25595 " gs_fs = result;\n" 25596 " gl_Position = vec4(1, -1, 0, 1);\n" 25597 " EmitVertex();\n" 25598 " gs_fs = result;\n" 25599 " gl_Position = vec4(1, 1, 0, 1);\n" 25600 " EmitVertex();\n" 25601 "}\n" 25602 "\n"; 25603 static const GLchar* tcs = "#version 430 core\n" 25604 "#extension GL_ARB_enhanced_layouts : require\n" 25605 "\n" 25606 "layout(vertices = 1) out;\n" 25607 "\n" 25608 "in vec4 vs_tcs[];\n" 25609 "out vec4 tcs_tes[];\n" 25610 "\n" 25611 "void main()\n" 25612 "{\n" 25613 "\n" 25614 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 25615 "\n" 25616 " gl_TessLevelOuter[0] = 1.0;\n" 25617 " gl_TessLevelOuter[1] = 1.0;\n" 25618 " gl_TessLevelOuter[2] = 1.0;\n" 25619 " gl_TessLevelOuter[3] = 1.0;\n" 25620 " gl_TessLevelInner[0] = 1.0;\n" 25621 " gl_TessLevelInner[1] = 1.0;\n" 25622 "}\n" 25623 "\n"; 25624 static const GLchar* tcs_tested = "#version 430 core\n" 25625 "#extension GL_ARB_enhanced_layouts : require\n" 25626 "\n" 25627 "layout(vertices = 1) out;\n" 25628 "\n" 25629 "VAR_DEFINITION" 25630 "\n" 25631 "in vec4 vs_tcs[];\n" 25632 "out vec4 tcs_tes[];\n" 25633 "\n" 25634 "void main()\n" 25635 "{\n" 25636 " vec4 result = vs_tcs[gl_InvocationID];\n" 25637 "\n" 25638 "VARIABLE_USE" 25639 "\n" 25640 " tcs_tes[gl_InvocationID] = result;\n" 25641 "\n" 25642 " gl_TessLevelOuter[0] = 1.0;\n" 25643 " gl_TessLevelOuter[1] = 1.0;\n" 25644 " gl_TessLevelOuter[2] = 1.0;\n" 25645 " gl_TessLevelOuter[3] = 1.0;\n" 25646 " gl_TessLevelInner[0] = 1.0;\n" 25647 " gl_TessLevelInner[1] = 1.0;\n" 25648 "}\n" 25649 "\n"; 25650 static const GLchar* tes_tested = "#version 430 core\n" 25651 "#extension GL_ARB_enhanced_layouts : require\n" 25652 "\n" 25653 "layout(isolines, point_mode) in;\n" 25654 "\n" 25655 "VAR_DEFINITION" 25656 "\n" 25657 "in vec4 tcs_tes[];\n" 25658 "out vec4 tes_gs;\n" 25659 "\n" 25660 "void main()\n" 25661 "{\n" 25662 " vec4 result = tcs_tes[0];\n" 25663 "\n" 25664 "VARIABLE_USE" 25665 "\n" 25666 " tes_gs += result;\n" 25667 "}\n" 25668 "\n"; 25669 static const GLchar* vs = "#version 430 core\n" 25670 "#extension GL_ARB_enhanced_layouts : require\n" 25671 "\n" 25672 "in vec4 in_vs;\n" 25673 "out vec4 vs_tcs;\n" 25674 "\n" 25675 "void main()\n" 25676 "{\n" 25677 " vs_tcs = in_vs;\n" 25678 "}\n" 25679 "\n"; 25680 static const GLchar* vs_tested = "#version 430 core\n" 25681 "#extension GL_ARB_enhanced_layouts : require\n" 25682 "\n" 25683 "VAR_DEFINITION" 25684 "\n" 25685 "in vec4 in_vs;\n" 25686 "out vec4 vs_tcs;\n" 25687 "\n" 25688 "void main()\n" 25689 "{\n" 25690 " vec4 result = in_vs;\n" 25691 "\n" 25692 "VARIABLE_USE" 25693 "\n" 25694 " vs_tcs = result;\n" 25695 "}\n" 25696 "\n"; 25697 25698 std::string source; 25699 testCase& test_case = m_test_cases[test_case_index]; 25700 25701 if (test_case.m_stage == stage) 25702 { 25703 const GLchar* array = ""; 25704 GLchar buffer[16]; 25705 const GLchar* index = ""; 25706 size_t position = 0; 25707 size_t position_start = 0; 25708 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 25709 25710 sprintf(buffer, "%d", test_case.m_offset); 25711 25712 switch (stage) 25713 { 25714 case Utils::Shader::GEOMETRY: 25715 source = gs_tested; 25716 array = "[]"; 25717 index = "[0]"; 25718 break; 25719 case Utils::Shader::TESS_CTRL: 25720 source = tcs_tested; 25721 array = "[]"; 25722 index = "[gl_InvocationID]"; 25723 break; 25724 case Utils::Shader::TESS_EVAL: 25725 source = tes_tested; 25726 array = "[]"; 25727 index = "[0]"; 25728 break; 25729 case Utils::Shader::VERTEX: 25730 source = vs_tested; 25731 break; 25732 default: 25733 TCU_FAIL("Invalid enum"); 25734 } 25735 25736 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 25737 position = 0; 25738 Utils::replaceToken("OFFSET", position, buffer, source); 25739 Utils::replaceToken("TYPE", position, type_name, source); 25740 Utils::replaceToken("ARRAY", position, array, source); 25741 position_start = position; 25742 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 25743 position = position_start; 25744 Utils::replaceToken("INDEX", position, index, source); 25745 Utils::replaceToken("TYPE", position, type_name, source); 25746 Utils::replaceToken("INDEX", position, index, source); 25747 Utils::replaceToken("TYPE", position, type_name, source); 25748 } 25749 else 25750 { 25751 switch (test_case.m_stage) 25752 { 25753 case Utils::Shader::GEOMETRY: 25754 switch (stage) 25755 { 25756 case Utils::Shader::FRAGMENT: 25757 source = fs; 25758 break; 25759 case Utils::Shader::VERTEX: 25760 source = vs; 25761 break; 25762 default: 25763 source = ""; 25764 } 25765 break; 25766 case Utils::Shader::TESS_CTRL: 25767 switch (stage) 25768 { 25769 case Utils::Shader::FRAGMENT: 25770 source = fs; 25771 break; 25772 case Utils::Shader::VERTEX: 25773 source = vs; 25774 break; 25775 default: 25776 source = ""; 25777 } 25778 break; 25779 case Utils::Shader::TESS_EVAL: 25780 switch (stage) 25781 { 25782 case Utils::Shader::FRAGMENT: 25783 source = fs; 25784 break; 25785 case Utils::Shader::TESS_CTRL: 25786 source = tcs; 25787 break; 25788 case Utils::Shader::VERTEX: 25789 source = vs; 25790 break; 25791 default: 25792 source = ""; 25793 } 25794 break; 25795 case Utils::Shader::VERTEX: 25796 switch (stage) 25797 { 25798 case Utils::Shader::FRAGMENT: 25799 source = fs; 25800 break; 25801 default: 25802 source = ""; 25803 } 25804 break; 25805 default: 25806 TCU_FAIL("Invalid enum"); 25807 break; 25808 } 25809 } 25810 25811 return source; 25812 } 25813 25814 /** Get description of test case 25815 * 25816 * @param test_case_index Index of test case 25817 * 25818 * @return Test case description 25819 **/ 25820 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index) 25821 { 25822 std::stringstream stream; 25823 testCase& test_case = m_test_cases[test_case_index]; 25824 25825 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 25826 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset; 25827 25828 return stream.str(); 25829 } 25830 25831 /** Get number of test cases 25832 * 25833 * @return Number of test cases 25834 **/ 25835 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber() 25836 { 25837 return static_cast<GLuint>(m_test_cases.size()); 25838 } 25839 25840 /** Selects if "compute" stage is relevant for test 25841 * 25842 * @param ignored 25843 * 25844 * @return false 25845 **/ 25846 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */) 25847 { 25848 return false; 25849 } 25850 25851 /** Prepare all test cases 25852 * 25853 **/ 25854 void XFBInvalidOffsetAlignmentTest::testInit() 25855 { 25856 const GLuint n_types = getTypesNumber(); 25857 25858 for (GLuint i = 0; i < n_types; ++i) 25859 { 25860 const Utils::Type& type = getType(i); 25861 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type); 25862 25863 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 25864 { 25865 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 25866 (Utils::Shader::FRAGMENT == stage)) 25867 { 25868 continue; 25869 } 25870 25871 for (GLuint offset = base_alingment + 1; offset < 2 * base_alingment; ++offset) 25872 { 25873 testCase test_case = { offset, (Utils::Shader::STAGES)stage, type }; 25874 25875 m_test_cases.push_back(test_case); 25876 } 25877 } 25878 } 25879 } 25880 25881 /** Constructor 25882 * 25883 * @param context Test context 25884 **/ 25885 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context& context) 25886 : BufferTestBase(context, "xfb_capture_inactive_output_variable", 25887 "Test verifies that inactive variables are captured") 25888 { 25889 /* Nothing to be done here */ 25890 } 25891 25892 /** Execute drawArrays for single vertex 25893 * 25894 * @param test_case_index 25895 * 25896 * @return true 25897 **/ 25898 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 25899 { 25900 const Functions& gl = m_context.getRenderContext().getFunctions(); 25901 GLenum primitive_type = GL_PATCHES; 25902 25903 if (TEST_VS == test_case_index) 25904 { 25905 primitive_type = GL_POINTS; 25906 } 25907 25908 gl.disable(GL_RASTERIZER_DISCARD); 25909 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 25910 25911 gl.beginTransformFeedback(GL_POINTS); 25912 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 25913 25914 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */); 25915 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 25916 25917 gl.endTransformFeedback(); 25918 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 25919 25920 return true; 25921 } 25922 25923 /** Get descriptors of buffers necessary for test 25924 * 25925 * @param ignored 25926 * @param out_descriptors Descriptors of buffers used by test 25927 **/ 25928 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 25929 bufferDescriptor::Vector& out_descriptors) 25930 { 25931 const Utils::Type& type = Utils::Type::vec4; 25932 25933 /* Test needs single uniform and xfb */ 25934 out_descriptors.resize(2); 25935 25936 /* Get references */ 25937 bufferDescriptor& uniform = out_descriptors[0]; 25938 bufferDescriptor& xfb = out_descriptors[1]; 25939 25940 /* Index */ 25941 uniform.m_index = 0; 25942 xfb.m_index = 0; 25943 25944 /* Target */ 25945 uniform.m_target = Utils::Buffer::Uniform; 25946 xfb.m_target = Utils::Buffer::Transform_feedback; 25947 25948 /* Data */ 25949 const std::vector<GLubyte>& gohan_data = type.GenerateData(); 25950 const std::vector<GLubyte>& goten_data = type.GenerateData(); 25951 25952 const GLuint type_size = static_cast<GLuint>(gohan_data.size()); 25953 25954 /* Uniform data */ 25955 uniform.m_initial_data.resize(2 * type_size); 25956 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size); 25957 memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size); 25958 25959 /* XFB data */ 25960 xfb.m_initial_data.resize(3 * type_size); 25961 xfb.m_expected_data.resize(3 * type_size); 25962 25963 for (GLuint i = 0; i < 3 * type_size; ++i) 25964 { 25965 xfb.m_initial_data[i] = (glw::GLubyte)i; 25966 xfb.m_expected_data[i] = (glw::GLubyte)i; 25967 } 25968 25969 memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size); 25970 memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size); 25971 } 25972 25973 /** Get body of main function for given shader stage 25974 * 25975 * @param test_case_index Index of test case 25976 * @param stage Shader stage 25977 * @param out_assignments Set to empty 25978 * @param out_calculations Set to empty 25979 **/ 25980 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, 25981 std::string& out_assignments, std::string& out_calculations) 25982 { 25983 out_calculations = ""; 25984 25985 static const GLchar* vs_tes_gs = " goten = uni_goten;\n" 25986 " gohan = uni_gohan;\n"; 25987 static const GLchar* fs = " fs_out = goku + gohan + goten;\n"; 25988 25989 const GLchar* assignments = ""; 25990 25991 switch (stage) 25992 { 25993 case Utils::Shader::FRAGMENT: 25994 assignments = fs; 25995 break; 25996 25997 case Utils::Shader::GEOMETRY: 25998 if (TEST_GS == test_case_index) 25999 { 26000 assignments = vs_tes_gs; 26001 } 26002 break; 26003 26004 case Utils::Shader::TESS_CTRL: 26005 break; 26006 26007 case Utils::Shader::TESS_EVAL: 26008 if (TEST_TES == test_case_index) 26009 { 26010 assignments = vs_tes_gs; 26011 } 26012 break; 26013 26014 case Utils::Shader::VERTEX: 26015 if (TEST_VS == test_case_index) 26016 { 26017 assignments = vs_tes_gs; 26018 } 26019 break; 26020 26021 default: 26022 TCU_FAIL("Invalid enum"); 26023 } 26024 26025 out_assignments = assignments; 26026 } 26027 26028 /** Get interface of shader 26029 * 26030 * @param test_case_index Index of test case 26031 * @param stage Shader stage 26032 * @param out_interface Set to "" 26033 **/ 26034 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, 26035 std::string& out_interface) 26036 { 26037 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n" 26038 "\n" 26039 "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n" 26040 "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n" 26041 "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n" 26042 "\n" 26043 "layout(binding = 0) uniform block {\n" 26044 " vec4 uni_gohan;\n" 26045 " vec4 uni_goten;\n" 26046 "};\n"; 26047 static const GLchar* fs = "in vec4 goku;\n" 26048 "in vec4 gohan;\n" 26049 "in vec4 goten;\n" 26050 "out vec4 fs_out;\n"; 26051 26052 const GLchar* interface = ""; 26053 26054 switch (stage) 26055 { 26056 case Utils::Shader::FRAGMENT: 26057 interface = fs; 26058 break; 26059 26060 case Utils::Shader::GEOMETRY: 26061 if (TEST_GS == test_case_index) 26062 { 26063 interface = vs_tes_gs; 26064 } 26065 break; 26066 26067 case Utils::Shader::TESS_CTRL: 26068 break; 26069 26070 case Utils::Shader::TESS_EVAL: 26071 if (TEST_TES == test_case_index) 26072 { 26073 interface = vs_tes_gs; 26074 } 26075 break; 26076 26077 case Utils::Shader::VERTEX: 26078 if (TEST_VS == test_case_index) 26079 { 26080 interface = vs_tes_gs; 26081 } 26082 break; 26083 26084 default: 26085 TCU_FAIL("Invalid enum"); 26086 } 26087 26088 out_interface = interface; 26089 } 26090 26091 /** Get source code of shader 26092 * 26093 * @param test_case_index Index of test case 26094 * @param stage Shader stage 26095 * 26096 * @return Source 26097 **/ 26098 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 26099 { 26100 std::string source; 26101 26102 switch (test_case_index) 26103 { 26104 case TEST_VS: 26105 switch (stage) 26106 { 26107 case Utils::Shader::FRAGMENT: 26108 case Utils::Shader::VERTEX: 26109 source = BufferTestBase::getShaderSource(test_case_index, stage); 26110 break; 26111 default: 26112 break; 26113 } 26114 break; 26115 26116 case TEST_TES: 26117 switch (stage) 26118 { 26119 case Utils::Shader::FRAGMENT: 26120 case Utils::Shader::TESS_CTRL: 26121 case Utils::Shader::TESS_EVAL: 26122 case Utils::Shader::VERTEX: 26123 source = BufferTestBase::getShaderSource(test_case_index, stage); 26124 break; 26125 default: 26126 break; 26127 } 26128 break; 26129 26130 case TEST_GS: 26131 source = BufferTestBase::getShaderSource(test_case_index, stage); 26132 break; 26133 26134 default: 26135 TCU_FAIL("Invalid enum"); 26136 break; 26137 } 26138 26139 /* */ 26140 return source; 26141 } 26142 26143 /** Get name of test case 26144 * 26145 * @param test_case_index Index of test case 26146 * 26147 * @return Name of tested stage 26148 **/ 26149 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index) 26150 { 26151 const GLchar* name = 0; 26152 26153 switch (test_case_index) 26154 { 26155 case TEST_VS: 26156 name = "vertex"; 26157 break; 26158 case TEST_TES: 26159 name = "tessellation evaluation"; 26160 break; 26161 case TEST_GS: 26162 name = "geometry"; 26163 break; 26164 default: 26165 TCU_FAIL("Invalid enum"); 26166 } 26167 26168 return name; 26169 } 26170 26171 /** Returns number of test cases 26172 * 26173 * @return TEST_MAX 26174 **/ 26175 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber() 26176 { 26177 return TEST_MAX; 26178 } 26179 26180 /** Inspects program to check if all resources are as expected 26181 * 26182 * @param ignored 26183 * @param program Program instance 26184 * @param out_stream Error message 26185 * 26186 * @return true if everything is ok, false otherwise 26187 **/ 26188 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program& program, 26189 std::stringstream& out_stream) 26190 { 26191 GLint stride = 0; 26192 const Utils::Type& type = Utils::Type::vec4; 26193 const GLuint type_size = type.GetSize(); 26194 26195 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 26196 1 /* buf_size */, &stride); 26197 26198 if ((GLint)(3 * type_size) != stride) 26199 { 26200 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size); 26201 26202 return false; 26203 } 26204 26205 return true; 26206 } 26207 26208 /** Verify contents of buffers 26209 * 26210 * @param buffers Collection of buffers to be verified 26211 * 26212 * @return true if everything is as expected, false otherwise 26213 **/ 26214 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection& buffers) 26215 { 26216 bool result = true; 26217 26218 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */; 26219 Utils::Buffer* buffer = pair.m_buffer; 26220 bufferDescriptor* descriptor = pair.m_descriptor; 26221 26222 /* Get pointer to contents of buffer */ 26223 buffer->Bind(); 26224 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly); 26225 26226 /* Get pointer to expected data */ 26227 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0]; 26228 26229 /* Compare */ 26230 static const GLuint vec4_size = 16; 26231 26232 int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size); 26233 int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size); 26234 26235 if ((0 != res_gohan) || (0 != res_goten)) 26236 { 26237 m_context.getTestContext().getLog() 26238 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target) 26239 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage; 26240 26241 result = false; 26242 } 26243 26244 /* Release buffer mapping */ 26245 buffer->UnMap(); 26246 26247 return result; 26248 } 26249 26250 /** Constructor 26251 * 26252 * @param context Test context 26253 **/ 26254 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context& context) 26255 : BufferTestBase(context, "xfb_capture_inactive_output_component", 26256 "Test verifies that inactive components are not modified") 26257 { 26258 /* Nothing to be done here */ 26259 } 26260 26261 /** Execute drawArrays for single vertex 26262 * 26263 * @param test_case_index 26264 * 26265 * @return true 26266 **/ 26267 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 26268 { 26269 const Functions& gl = m_context.getRenderContext().getFunctions(); 26270 GLenum primitive_type = GL_PATCHES; 26271 26272 if (TEST_VS == test_case_index) 26273 { 26274 primitive_type = GL_POINTS; 26275 } 26276 26277 gl.disable(GL_RASTERIZER_DISCARD); 26278 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 26279 26280 gl.beginTransformFeedback(GL_POINTS); 26281 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 26282 26283 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */); 26284 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 26285 26286 gl.endTransformFeedback(); 26287 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 26288 26289 return true; 26290 } 26291 26292 /** Get descriptors of buffers necessary for test 26293 * 26294 * @param ignored 26295 * @param out_descriptors Descriptors of buffers used by test 26296 **/ 26297 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 26298 bufferDescriptor::Vector& out_descriptors) 26299 { 26300 const Utils::Type& type = Utils::Type::vec4; 26301 26302 /* Test needs single uniform and xfb */ 26303 out_descriptors.resize(2); 26304 26305 /* Get references */ 26306 bufferDescriptor& uniform = out_descriptors[0]; 26307 bufferDescriptor& xfb = out_descriptors[1]; 26308 26309 /* Index */ 26310 uniform.m_index = 0; 26311 xfb.m_index = 0; 26312 26313 /* Target */ 26314 uniform.m_target = Utils::Buffer::Uniform; 26315 xfb.m_target = Utils::Buffer::Transform_feedback; 26316 26317 /* Data */ 26318 const std::vector<GLubyte>& goku_data = type.GenerateData(); 26319 const std::vector<GLubyte>& gohan_data = type.GenerateData(); 26320 const std::vector<GLubyte>& goten_data = type.GenerateData(); 26321 const std::vector<GLubyte>& chichi_data = type.GenerateData(); 26322 const std::vector<GLubyte>& vegeta_data = type.GenerateData(); 26323 const std::vector<GLubyte>& trunks_data = type.GenerateData(); 26324 const std::vector<GLubyte>& bra_data = type.GenerateData(); 26325 const std::vector<GLubyte>& bulma_data = type.GenerateData(); 26326 26327 const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type); 26328 const GLuint type_size = static_cast<GLuint>(gohan_data.size()); 26329 26330 /* Uniform data */ 26331 uniform.m_initial_data.resize(8 * type_size); 26332 memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size); 26333 memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size); 26334 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size); 26335 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size); 26336 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size); 26337 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size); 26338 memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size); 26339 memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size); 26340 26341 /* XFB data */ 26342 xfb.m_initial_data.resize(8 * type_size); 26343 xfb.m_expected_data.resize(8 * type_size); 26344 26345 for (GLuint i = 0; i < 8 * type_size; ++i) 26346 { 26347 xfb.m_initial_data[i] = (glw::GLubyte)i; 26348 xfb.m_expected_data[i] = (glw::GLubyte)i; 26349 } 26350 26351 /* goku - x, z - 32 */ 26352 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size); 26353 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size); 26354 26355 /* gohan - y, w - 0 */ 26356 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size); 26357 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size); 26358 26359 /* goten - x, y - 16 */ 26360 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size); 26361 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size); 26362 26363 /* chichi - z, w - 48 */ 26364 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size); 26365 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size); 26366 26367 /* vegeta - x - 112 */ 26368 memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size); 26369 26370 /* trunks - y - 96 */ 26371 memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size); 26372 26373 /* bra - z - 80 */ 26374 memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size); 26375 26376 /* bulma - w - 64 */ 26377 memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size); 26378 } 26379 26380 /** Get body of main function for given shader stage 26381 * 26382 * @param test_case_index Index of test case 26383 * @param stage Shader stage 26384 * @param out_assignments Set to empty 26385 * @param out_calculations Set to empty 26386 **/ 26387 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, 26388 std::string& out_assignments, std::string& out_calculations) 26389 { 26390 out_calculations = ""; 26391 26392 static const GLchar* vs_tes_gs = " goku.x = uni_goku.x ;\n" 26393 " goku.z = uni_goku.z ;\n" 26394 " gohan.y = uni_gohan.y ;\n" 26395 " gohan.w = uni_gohan.w ;\n" 26396 " goten.x = uni_goten.x ;\n" 26397 " goten.y = uni_goten.y ;\n" 26398 " chichi.z = uni_chichi.z ;\n" 26399 " chichi.w = uni_chichi.w ;\n" 26400 " vegeta.x = uni_vegeta.x ;\n" 26401 " trunks.y = uni_trunks.y ;\n" 26402 " bra.z = uni_bra.z ;\n" 26403 " bulma.w = uni_bulma.w ;\n"; 26404 static const GLchar* fs = " fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n"; 26405 26406 const GLchar* assignments = ""; 26407 26408 switch (stage) 26409 { 26410 case Utils::Shader::FRAGMENT: 26411 assignments = fs; 26412 break; 26413 26414 case Utils::Shader::GEOMETRY: 26415 if (TEST_GS == test_case_index) 26416 { 26417 assignments = vs_tes_gs; 26418 } 26419 break; 26420 26421 case Utils::Shader::TESS_CTRL: 26422 break; 26423 26424 case Utils::Shader::TESS_EVAL: 26425 if (TEST_TES == test_case_index) 26426 { 26427 assignments = vs_tes_gs; 26428 } 26429 break; 26430 26431 case Utils::Shader::VERTEX: 26432 if (TEST_VS == test_case_index) 26433 { 26434 assignments = vs_tes_gs; 26435 } 26436 break; 26437 26438 default: 26439 TCU_FAIL("Invalid enum"); 26440 } 26441 26442 out_assignments = assignments; 26443 } 26444 26445 /** Get interface of shader 26446 * 26447 * @param test_case_index Index of test case 26448 * @param stage Shader stage 26449 * @param out_interface Set to "" 26450 **/ 26451 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, 26452 std::string& out_interface) 26453 { 26454 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n" 26455 "\n" 26456 "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n" 26457 "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n" 26458 "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n" 26459 "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n" 26460 "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n" 26461 "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n" 26462 "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n" 26463 "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n" 26464 "\n" 26465 "layout(binding = 0) uniform block {\n" 26466 " vec4 uni_goku;\n" 26467 " vec4 uni_gohan;\n" 26468 " vec4 uni_goten;\n" 26469 " vec4 uni_chichi;\n" 26470 " vec4 uni_vegeta;\n" 26471 " vec4 uni_trunks;\n" 26472 " vec4 uni_bra;\n" 26473 " vec4 uni_bulma;\n" 26474 "};\n"; 26475 static const GLchar* fs = "in vec4 vegeta;\n" 26476 "in vec4 trunks;\n" 26477 "in vec4 bra;\n" 26478 "in vec4 bulma;\n" 26479 "in vec4 goku;\n" 26480 "in vec4 gohan;\n" 26481 "in vec4 goten;\n" 26482 "in vec4 chichi;\n" 26483 "\n" 26484 "out vec4 fs_out;\n"; 26485 26486 const GLchar* interface = ""; 26487 26488 switch (stage) 26489 { 26490 case Utils::Shader::FRAGMENT: 26491 interface = fs; 26492 break; 26493 26494 case Utils::Shader::GEOMETRY: 26495 if (TEST_GS == test_case_index) 26496 { 26497 interface = vs_tes_gs; 26498 } 26499 break; 26500 26501 case Utils::Shader::TESS_CTRL: 26502 break; 26503 26504 case Utils::Shader::TESS_EVAL: 26505 if (TEST_TES == test_case_index) 26506 { 26507 interface = vs_tes_gs; 26508 } 26509 break; 26510 26511 case Utils::Shader::VERTEX: 26512 if (TEST_VS == test_case_index) 26513 { 26514 interface = vs_tes_gs; 26515 } 26516 break; 26517 26518 default: 26519 TCU_FAIL("Invalid enum"); 26520 } 26521 26522 out_interface = interface; 26523 } 26524 26525 /** Get source code of shader 26526 * 26527 * @param test_case_index Index of test case 26528 * @param stage Shader stage 26529 * 26530 * @return Source 26531 **/ 26532 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 26533 { 26534 std::string source; 26535 26536 switch (test_case_index) 26537 { 26538 case TEST_VS: 26539 switch (stage) 26540 { 26541 case Utils::Shader::FRAGMENT: 26542 case Utils::Shader::VERTEX: 26543 source = BufferTestBase::getShaderSource(test_case_index, stage); 26544 break; 26545 default: 26546 break; 26547 } 26548 break; 26549 26550 case TEST_TES: 26551 switch (stage) 26552 { 26553 case Utils::Shader::FRAGMENT: 26554 case Utils::Shader::TESS_CTRL: 26555 case Utils::Shader::TESS_EVAL: 26556 case Utils::Shader::VERTEX: 26557 source = BufferTestBase::getShaderSource(test_case_index, stage); 26558 break; 26559 default: 26560 break; 26561 } 26562 break; 26563 26564 case TEST_GS: 26565 source = BufferTestBase::getShaderSource(test_case_index, stage); 26566 break; 26567 26568 default: 26569 TCU_FAIL("Invalid enum"); 26570 break; 26571 } 26572 26573 /* */ 26574 return source; 26575 } 26576 26577 /** Get name of test case 26578 * 26579 * @param test_case_index Index of test case 26580 * 26581 * @return Name of tested stage 26582 **/ 26583 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index) 26584 { 26585 const GLchar* name = 0; 26586 26587 switch (test_case_index) 26588 { 26589 case TEST_VS: 26590 name = "vertex"; 26591 break; 26592 case TEST_TES: 26593 name = "tessellation evaluation"; 26594 break; 26595 case TEST_GS: 26596 name = "geometry"; 26597 break; 26598 default: 26599 TCU_FAIL("Invalid enum"); 26600 } 26601 26602 return name; 26603 } 26604 26605 /** Returns number of test cases 26606 * 26607 * @return TEST_MAX 26608 **/ 26609 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber() 26610 { 26611 return TEST_MAX; 26612 } 26613 26614 /** Verify contents of buffers 26615 * 26616 * @param buffers Collection of buffers to be verified 26617 * 26618 * @return true if everything is as expected, false otherwise 26619 **/ 26620 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection& buffers) 26621 { 26622 bool result = true; 26623 26624 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */; 26625 Utils::Buffer* buffer = pair.m_buffer; 26626 bufferDescriptor* descriptor = pair.m_descriptor; 26627 26628 /* Get pointer to contents of buffer */ 26629 buffer->Bind(); 26630 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly); 26631 26632 /* Get pointer to expected data */ 26633 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0]; 26634 26635 /* Compare */ 26636 static const GLuint comp_size = 4; 26637 static const GLuint vec4_size = 16; 26638 26639 int res_goku_x = 26640 memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size); 26641 int res_goku_z = 26642 memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size); 26643 26644 int res_gohan_y = 26645 memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size); 26646 int res_gohan_w = 26647 memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size); 26648 26649 int res_goten_x = 26650 memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size); 26651 int res_goten_y = 26652 memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size); 26653 26654 int res_chichi_z = 26655 memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size); 26656 int res_chichi_w = 26657 memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size); 26658 26659 int res_vegeta_x = 26660 memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size); 26661 26662 int res_trunks_y = 26663 memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size); 26664 26665 int res_bra_z = 26666 memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size); 26667 26668 int res_bulma_w = 26669 memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size); 26670 26671 if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) || 26672 (0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) || 26673 (0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w)) 26674 { 26675 m_context.getTestContext().getLog() 26676 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target) 26677 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage; 26678 26679 result = false; 26680 } 26681 26682 /* Release buffer mapping */ 26683 buffer->UnMap(); 26684 26685 return result; 26686 } 26687 26688 /** Constructor 26689 * 26690 * @param context Test context 26691 **/ 26692 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context& context) 26693 : BufferTestBase(context, "xfb_capture_inactive_output_block_member", 26694 "Test verifies that inactive block members are captured") 26695 { 26696 /* Nothing to be done here */ 26697 } 26698 26699 /** Execute drawArrays for single vertex 26700 * 26701 * @param test_case_index 26702 * 26703 * @return true 26704 **/ 26705 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 26706 { 26707 const Functions& gl = m_context.getRenderContext().getFunctions(); 26708 GLenum primitive_type = GL_PATCHES; 26709 26710 if (TEST_VS == test_case_index) 26711 { 26712 primitive_type = GL_POINTS; 26713 } 26714 26715 gl.disable(GL_RASTERIZER_DISCARD); 26716 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 26717 26718 gl.beginTransformFeedback(GL_POINTS); 26719 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 26720 26721 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */); 26722 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 26723 26724 gl.endTransformFeedback(); 26725 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 26726 26727 return true; 26728 } 26729 26730 /** Get descriptors of buffers necessary for test 26731 * 26732 * @param ignored 26733 * @param out_descriptors Descriptors of buffers used by test 26734 **/ 26735 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 26736 bufferDescriptor::Vector& out_descriptors) 26737 { 26738 const Utils::Type& type = Utils::Type::vec4; 26739 26740 /* Test needs single uniform and xfb */ 26741 out_descriptors.resize(2); 26742 26743 /* Get references */ 26744 bufferDescriptor& uniform = out_descriptors[0]; 26745 bufferDescriptor& xfb = out_descriptors[1]; 26746 26747 /* Index */ 26748 uniform.m_index = 0; 26749 xfb.m_index = 0; 26750 26751 /* Target */ 26752 uniform.m_target = Utils::Buffer::Uniform; 26753 xfb.m_target = Utils::Buffer::Transform_feedback; 26754 26755 /* Data */ 26756 const std::vector<GLubyte>& gohan_data = type.GenerateData(); 26757 const std::vector<GLubyte>& chichi_data = type.GenerateData(); 26758 26759 const GLuint type_size = static_cast<GLuint>(gohan_data.size()); 26760 26761 /* Uniform data */ 26762 uniform.m_initial_data.resize(2 * type_size); 26763 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size); 26764 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size); 26765 26766 /* XFB data */ 26767 xfb.m_initial_data.resize(4 * type_size); 26768 xfb.m_expected_data.resize(4 * type_size); 26769 26770 for (GLuint i = 0; i < 4 * type_size; ++i) 26771 { 26772 xfb.m_initial_data[i] = (glw::GLubyte)i; 26773 xfb.m_expected_data[i] = (glw::GLubyte)i; 26774 } 26775 26776 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size); 26777 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size); 26778 } 26779 26780 /** Get body of main function for given shader stage 26781 * 26782 * @param test_case_index Index of test case 26783 * @param stage Shader stage 26784 * @param out_assignments Set to empty 26785 * @param out_calculations Set to empty 26786 **/ 26787 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, 26788 std::string& out_assignments, std::string& out_calculations) 26789 { 26790 out_calculations = ""; 26791 26792 static const GLchar* vs_tes_gs = " chichi = uni_chichi;\n" 26793 " gohan = uni_gohan;\n"; 26794 static const GLchar* fs = " fs_out = goten + gohan + chichi;\n"; 26795 26796 const GLchar* assignments = ""; 26797 26798 switch (stage) 26799 { 26800 case Utils::Shader::FRAGMENT: 26801 assignments = fs; 26802 break; 26803 26804 case Utils::Shader::GEOMETRY: 26805 if (TEST_GS == test_case_index) 26806 { 26807 assignments = vs_tes_gs; 26808 } 26809 break; 26810 26811 case Utils::Shader::TESS_CTRL: 26812 break; 26813 26814 case Utils::Shader::TESS_EVAL: 26815 if (TEST_TES == test_case_index) 26816 { 26817 assignments = vs_tes_gs; 26818 } 26819 break; 26820 26821 case Utils::Shader::VERTEX: 26822 if (TEST_VS == test_case_index) 26823 { 26824 assignments = vs_tes_gs; 26825 } 26826 break; 26827 26828 default: 26829 TCU_FAIL("Invalid enum"); 26830 } 26831 26832 out_assignments = assignments; 26833 } 26834 26835 /** Get interface of shader 26836 * 26837 * @param test_case_index Index of test case 26838 * @param stage Shader stage 26839 * @param out_interface Set to "" 26840 **/ 26841 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, 26842 std::string& out_interface) 26843 { 26844 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n" 26845 "\n" 26846 "layout (xfb_offset = 1 * sizeof_type) out Goku {\n" 26847 " vec4 gohan;\n" 26848 " vec4 goten;\n" 26849 " vec4 chichi;\n" 26850 "};\n" 26851 "\n" 26852 "layout(binding = 0) uniform block {\n" 26853 " vec4 uni_gohan;\n" 26854 " vec4 uni_chichi;\n" 26855 "};\n"; 26856 static const GLchar* fs = "in Goku {\n" 26857 " vec4 gohan;\n" 26858 " vec4 goten;\n" 26859 " vec4 chichi;\n" 26860 "};\n" 26861 "out vec4 fs_out;\n"; 26862 26863 const GLchar* interface = ""; 26864 26865 switch (stage) 26866 { 26867 case Utils::Shader::FRAGMENT: 26868 interface = fs; 26869 break; 26870 26871 case Utils::Shader::GEOMETRY: 26872 if (TEST_GS == test_case_index) 26873 { 26874 interface = vs_tes_gs; 26875 } 26876 break; 26877 26878 case Utils::Shader::TESS_CTRL: 26879 break; 26880 26881 case Utils::Shader::TESS_EVAL: 26882 if (TEST_TES == test_case_index) 26883 { 26884 interface = vs_tes_gs; 26885 } 26886 break; 26887 26888 case Utils::Shader::VERTEX: 26889 if (TEST_VS == test_case_index) 26890 { 26891 interface = vs_tes_gs; 26892 } 26893 break; 26894 26895 default: 26896 TCU_FAIL("Invalid enum"); 26897 } 26898 26899 out_interface = interface; 26900 } 26901 26902 /** Get source code of shader 26903 * 26904 * @param test_case_index Index of test case 26905 * @param stage Shader stage 26906 * 26907 * @return Source 26908 **/ 26909 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint test_case_index, 26910 Utils::Shader::STAGES stage) 26911 { 26912 std::string source; 26913 26914 switch (test_case_index) 26915 { 26916 case TEST_VS: 26917 switch (stage) 26918 { 26919 case Utils::Shader::FRAGMENT: 26920 case Utils::Shader::VERTEX: 26921 source = BufferTestBase::getShaderSource(test_case_index, stage); 26922 break; 26923 default: 26924 break; 26925 } 26926 break; 26927 26928 case TEST_TES: 26929 switch (stage) 26930 { 26931 case Utils::Shader::FRAGMENT: 26932 case Utils::Shader::TESS_CTRL: 26933 case Utils::Shader::TESS_EVAL: 26934 case Utils::Shader::VERTEX: 26935 source = BufferTestBase::getShaderSource(test_case_index, stage); 26936 break; 26937 default: 26938 break; 26939 } 26940 break; 26941 26942 case TEST_GS: 26943 source = BufferTestBase::getShaderSource(test_case_index, stage); 26944 break; 26945 26946 default: 26947 TCU_FAIL("Invalid enum"); 26948 break; 26949 } 26950 26951 /* */ 26952 return source; 26953 } 26954 26955 /** Get name of test case 26956 * 26957 * @param test_case_index Index of test case 26958 * 26959 * @return Name of tested stage 26960 **/ 26961 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index) 26962 { 26963 const GLchar* name = 0; 26964 26965 switch (test_case_index) 26966 { 26967 case TEST_VS: 26968 name = "vertex"; 26969 break; 26970 case TEST_TES: 26971 name = "tessellation evaluation"; 26972 break; 26973 case TEST_GS: 26974 name = "geometry"; 26975 break; 26976 default: 26977 TCU_FAIL("Invalid enum"); 26978 } 26979 26980 return name; 26981 } 26982 26983 /** Returns number of test cases 26984 * 26985 * @return TEST_MAX 26986 **/ 26987 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber() 26988 { 26989 return TEST_MAX; 26990 } 26991 26992 /** Verify contents of buffers 26993 * 26994 * @param buffers Collection of buffers to be verified 26995 * 26996 * @return true if everything is as expected, false otherwise 26997 **/ 26998 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection& buffers) 26999 { 27000 bool result = true; 27001 27002 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */; 27003 Utils::Buffer* buffer = pair.m_buffer; 27004 bufferDescriptor* descriptor = pair.m_descriptor; 27005 27006 /* Get pointer to contents of buffer */ 27007 buffer->Bind(); 27008 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly); 27009 27010 /* Get pointer to expected data */ 27011 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0]; 27012 27013 /* Compare */ 27014 static const GLuint vec4_size = 16; 27015 27016 int res_before = memcmp(buffer_data, expected_data, vec4_size); 27017 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size); 27018 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size); 27019 27020 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi)) 27021 { 27022 m_context.getTestContext().getLog() 27023 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target) 27024 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage; 27025 27026 result = false; 27027 } 27028 27029 /* Release buffer mapping */ 27030 buffer->UnMap(); 27031 27032 return result; 27033 } 27034 27035 /** Constructor 27036 * 27037 * @param context Test context 27038 **/ 27039 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context& context) 27040 : BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured") 27041 { 27042 /* Nothing to be done here */ 27043 } 27044 27045 /** Execute drawArrays for single vertex 27046 * 27047 * @param test_case_index 27048 * 27049 * @return true 27050 **/ 27051 bool XFBCaptureStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 27052 { 27053 const Functions& gl = m_context.getRenderContext().getFunctions(); 27054 GLenum primitive_type = GL_PATCHES; 27055 27056 if (TEST_VS == test_case_index) 27057 { 27058 primitive_type = GL_POINTS; 27059 } 27060 27061 gl.disable(GL_RASTERIZER_DISCARD); 27062 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 27063 27064 gl.beginTransformFeedback(GL_POINTS); 27065 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 27066 27067 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */); 27068 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 27069 27070 gl.endTransformFeedback(); 27071 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 27072 27073 return true; 27074 } 27075 27076 /** Get descriptors of buffers necessary for test 27077 * 27078 * @param ignored 27079 * @param out_descriptors Descriptors of buffers used by test 27080 **/ 27081 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 27082 bufferDescriptor::Vector& out_descriptors) 27083 { 27084 const Utils::Type& type = Utils::Type::vec4; 27085 27086 /* Test needs single uniform and xfb */ 27087 out_descriptors.resize(2); 27088 27089 /* Get references */ 27090 bufferDescriptor& uniform = out_descriptors[0]; 27091 bufferDescriptor& xfb = out_descriptors[1]; 27092 27093 /* Index */ 27094 uniform.m_index = 0; 27095 xfb.m_index = 0; 27096 27097 /* Target */ 27098 uniform.m_target = Utils::Buffer::Uniform; 27099 xfb.m_target = Utils::Buffer::Transform_feedback; 27100 27101 /* Data */ 27102 const std::vector<GLubyte>& gohan_data = type.GenerateData(); 27103 const std::vector<GLubyte>& chichi_data = type.GenerateData(); 27104 27105 const GLuint type_size = static_cast<GLuint>(gohan_data.size()); 27106 27107 /* Uniform data */ 27108 uniform.m_initial_data.resize(2 * type_size); 27109 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size); 27110 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size); 27111 27112 /* XFB data */ 27113 xfb.m_initial_data.resize(4 * type_size); 27114 xfb.m_expected_data.resize(4 * type_size); 27115 27116 for (GLuint i = 0; i < 4 * type_size; ++i) 27117 { 27118 xfb.m_initial_data[i] = (glw::GLubyte)i; 27119 xfb.m_expected_data[i] = (glw::GLubyte)i; 27120 } 27121 27122 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size); 27123 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size); 27124 } 27125 27126 /** Get body of main function for given shader stage 27127 * 27128 * @param test_case_index Index of test case 27129 * @param stage Shader stage 27130 * @param out_assignments Set to empty 27131 * @param out_calculations Set to empty 27132 **/ 27133 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, 27134 std::string& out_assignments, std::string& out_calculations) 27135 { 27136 out_calculations = ""; 27137 27138 static const GLchar* vs_tes_gs = " goku.chichi = uni_chichi;\n" 27139 " goku.gohan = uni_gohan;\n"; 27140 static const GLchar* fs = " fs_out = goku.goten + goku.gohan + goku.chichi;\n"; 27141 27142 const GLchar* assignments = ""; 27143 27144 switch (stage) 27145 { 27146 case Utils::Shader::FRAGMENT: 27147 assignments = fs; 27148 break; 27149 27150 case Utils::Shader::GEOMETRY: 27151 if (TEST_GS == test_case_index) 27152 { 27153 assignments = vs_tes_gs; 27154 } 27155 break; 27156 27157 case Utils::Shader::TESS_CTRL: 27158 break; 27159 27160 case Utils::Shader::TESS_EVAL: 27161 if (TEST_TES == test_case_index) 27162 { 27163 assignments = vs_tes_gs; 27164 } 27165 break; 27166 27167 case Utils::Shader::VERTEX: 27168 if (TEST_VS == test_case_index) 27169 { 27170 assignments = vs_tes_gs; 27171 } 27172 break; 27173 27174 default: 27175 TCU_FAIL("Invalid enum"); 27176 } 27177 27178 out_assignments = assignments; 27179 } 27180 27181 /** Get interface of shader 27182 * 27183 * @param test_case_index Index of test case 27184 * @param stage Shader stage 27185 * @param out_interface Set to "" 27186 **/ 27187 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, 27188 std::string& out_interface) 27189 { 27190 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n" 27191 "\n" 27192 "struct Goku {\n" 27193 " vec4 gohan;\n" 27194 " vec4 goten;\n" 27195 " vec4 chichi;\n" 27196 "};\n" 27197 "\n" 27198 "layout (xfb_offset = sizeof_type) out Goku goku;\n" 27199 "\n" 27200 "layout(binding = 0, std140) uniform block {\n" 27201 " vec4 uni_gohan;\n" 27202 " vec4 uni_chichi;\n" 27203 "};\n"; 27204 static const GLchar* fs = "struct Goku {\n" 27205 " vec4 gohan;\n" 27206 " vec4 goten;\n" 27207 " vec4 chichi;\n" 27208 "};\n" 27209 "\n" 27210 "in Goku goku;\n" 27211 "\n" 27212 "out vec4 fs_out;\n"; 27213 27214 const GLchar* interface = ""; 27215 27216 switch (stage) 27217 { 27218 case Utils::Shader::FRAGMENT: 27219 interface = fs; 27220 break; 27221 27222 case Utils::Shader::GEOMETRY: 27223 if (TEST_GS == test_case_index) 27224 { 27225 interface = vs_tes_gs; 27226 } 27227 break; 27228 27229 case Utils::Shader::TESS_CTRL: 27230 break; 27231 27232 case Utils::Shader::TESS_EVAL: 27233 if (TEST_TES == test_case_index) 27234 { 27235 interface = vs_tes_gs; 27236 } 27237 break; 27238 27239 case Utils::Shader::VERTEX: 27240 if (TEST_VS == test_case_index) 27241 { 27242 interface = vs_tes_gs; 27243 } 27244 break; 27245 27246 default: 27247 TCU_FAIL("Invalid enum"); 27248 } 27249 27250 out_interface = interface; 27251 } 27252 27253 /** Get source code of shader 27254 * 27255 * @param test_case_index Index of test case 27256 * @param stage Shader stage 27257 * 27258 * @return Source 27259 **/ 27260 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 27261 { 27262 std::string source; 27263 27264 switch (test_case_index) 27265 { 27266 case TEST_VS: 27267 switch (stage) 27268 { 27269 case Utils::Shader::FRAGMENT: 27270 case Utils::Shader::VERTEX: 27271 source = BufferTestBase::getShaderSource(test_case_index, stage); 27272 break; 27273 default: 27274 break; 27275 } 27276 break; 27277 27278 case TEST_TES: 27279 switch (stage) 27280 { 27281 case Utils::Shader::FRAGMENT: 27282 case Utils::Shader::TESS_CTRL: 27283 case Utils::Shader::TESS_EVAL: 27284 case Utils::Shader::VERTEX: 27285 source = BufferTestBase::getShaderSource(test_case_index, stage); 27286 break; 27287 default: 27288 break; 27289 } 27290 break; 27291 27292 case TEST_GS: 27293 source = BufferTestBase::getShaderSource(test_case_index, stage); 27294 break; 27295 27296 default: 27297 TCU_FAIL("Invalid enum"); 27298 break; 27299 } 27300 27301 /* */ 27302 return source; 27303 } 27304 27305 /** Get name of test case 27306 * 27307 * @param test_case_index Index of test case 27308 * 27309 * @return Name of tested stage 27310 **/ 27311 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index) 27312 { 27313 const GLchar* name = 0; 27314 27315 switch (test_case_index) 27316 { 27317 case TEST_VS: 27318 name = "vertex"; 27319 break; 27320 case TEST_TES: 27321 name = "tessellation evaluation"; 27322 break; 27323 case TEST_GS: 27324 name = "geometry"; 27325 break; 27326 default: 27327 TCU_FAIL("Invalid enum"); 27328 } 27329 27330 return name; 27331 } 27332 27333 /** Returns number of test cases 27334 * 27335 * @return TEST_MAX 27336 **/ 27337 glw::GLuint XFBCaptureStructTest::getTestCaseNumber() 27338 { 27339 return TEST_MAX; 27340 } 27341 27342 /** Verify contents of buffers 27343 * 27344 * @param buffers Collection of buffers to be verified 27345 * 27346 * @return true if everything is as expected, false otherwise 27347 **/ 27348 bool XFBCaptureStructTest::verifyBuffers(bufferCollection& buffers) 27349 { 27350 bool result = true; 27351 27352 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */; 27353 Utils::Buffer* buffer = pair.m_buffer; 27354 bufferDescriptor* descriptor = pair.m_descriptor; 27355 27356 /* Get pointer to contents of buffer */ 27357 buffer->Bind(); 27358 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly); 27359 27360 /* Get pointer to expected data */ 27361 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0]; 27362 27363 /* Compare */ 27364 static const GLuint vec4_size = 16; 27365 27366 int res_before = memcmp(buffer_data, expected_data, vec4_size); 27367 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size); 27368 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size); 27369 27370 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi)) 27371 { 27372 m_context.getTestContext().getLog() 27373 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target) 27374 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage; 27375 27376 result = false; 27377 } 27378 27379 /* Release buffer mapping */ 27380 buffer->UnMap(); 27381 27382 return result; 27383 } 27384 27385 /** Constructor 27386 * 27387 * @param context Test framework context 27388 **/ 27389 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context& context) 27390 : NegativeTestBase(context, "xfb_capture_unsized_array", 27391 "Test verifies that compiler reports error when unsized array is qualified with xfb_offset") 27392 { 27393 } 27394 27395 /** Source for given test case and stage 27396 * 27397 * @param test_case_index Index of test case 27398 * @param stage Shader stage 27399 * 27400 * @return Shader source 27401 **/ 27402 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 27403 { 27404 static const GLchar* var_definition = "layout (xfb_offset = 0) out vec4 gokuARRAY[];\n"; 27405 static const GLchar* var_use = " gokuINDEX[0] = result / 2;\n"; 27406 static const GLchar* fs = "#version 430 core\n" 27407 "#extension GL_ARB_enhanced_layouts : require\n" 27408 "\n" 27409 "in vec4 gs_fs;\n" 27410 "out vec4 fs_out;\n" 27411 "\n" 27412 "void main()\n" 27413 "{\n" 27414 " fs_out = gs_fs;\n" 27415 "}\n" 27416 "\n"; 27417 static const GLchar* gs_tested = "#version 430 core\n" 27418 "#extension GL_ARB_enhanced_layouts : require\n" 27419 "\n" 27420 "layout(points) in;\n" 27421 "layout(triangle_strip, max_vertices = 4) out;\n" 27422 "\n" 27423 "VAR_DEFINITION" 27424 "\n" 27425 "in vec4 tes_gs[];\n" 27426 "out vec4 gs_fs;\n" 27427 "\n" 27428 "void main()\n" 27429 "{\n" 27430 " vec4 result = tes_gs[0];\n" 27431 "\n" 27432 "VARIABLE_USE" 27433 "\n" 27434 " gs_fs = result;\n" 27435 " gl_Position = vec4(-1, -1, 0, 1);\n" 27436 " EmitVertex();\n" 27437 " gs_fs = result;\n" 27438 " gl_Position = vec4(-1, 1, 0, 1);\n" 27439 " EmitVertex();\n" 27440 " gs_fs = result;\n" 27441 " gl_Position = vec4(1, -1, 0, 1);\n" 27442 " EmitVertex();\n" 27443 " gs_fs = result;\n" 27444 " gl_Position = vec4(1, 1, 0, 1);\n" 27445 " EmitVertex();\n" 27446 "}\n" 27447 "\n"; 27448 static const GLchar* tcs = "#version 430 core\n" 27449 "#extension GL_ARB_enhanced_layouts : require\n" 27450 "\n" 27451 "layout(vertices = 1) out;\n" 27452 "\n" 27453 "in vec4 vs_tcs[];\n" 27454 "out vec4 tcs_tes[];\n" 27455 "\n" 27456 "void main()\n" 27457 "{\n" 27458 "\n" 27459 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 27460 "\n" 27461 " gl_TessLevelOuter[0] = 1.0;\n" 27462 " gl_TessLevelOuter[1] = 1.0;\n" 27463 " gl_TessLevelOuter[2] = 1.0;\n" 27464 " gl_TessLevelOuter[3] = 1.0;\n" 27465 " gl_TessLevelInner[0] = 1.0;\n" 27466 " gl_TessLevelInner[1] = 1.0;\n" 27467 "}\n" 27468 "\n"; 27469 static const GLchar* tcs_tested = "#version 430 core\n" 27470 "#extension GL_ARB_enhanced_layouts : require\n" 27471 "\n" 27472 "layout(vertices = 1) out;\n" 27473 "\n" 27474 "VAR_DEFINITION" 27475 "\n" 27476 "in vec4 vs_tcs[];\n" 27477 "out vec4 tcs_tes[];\n" 27478 "\n" 27479 "void main()\n" 27480 "{\n" 27481 " vec4 result = vs_tcs[gl_InvocationID];\n" 27482 "\n" 27483 "VARIABLE_USE" 27484 "\n" 27485 " tcs_tes[gl_InvocationID] = result;\n" 27486 "\n" 27487 " gl_TessLevelOuter[0] = 1.0;\n" 27488 " gl_TessLevelOuter[1] = 1.0;\n" 27489 " gl_TessLevelOuter[2] = 1.0;\n" 27490 " gl_TessLevelOuter[3] = 1.0;\n" 27491 " gl_TessLevelInner[0] = 1.0;\n" 27492 " gl_TessLevelInner[1] = 1.0;\n" 27493 "}\n" 27494 "\n"; 27495 static const GLchar* tes_tested = "#version 430 core\n" 27496 "#extension GL_ARB_enhanced_layouts : require\n" 27497 "\n" 27498 "layout(isolines, point_mode) in;\n" 27499 "\n" 27500 "VAR_DEFINITION" 27501 "\n" 27502 "in vec4 tcs_tes[];\n" 27503 "out vec4 tes_gs;\n" 27504 "\n" 27505 "void main()\n" 27506 "{\n" 27507 " vec4 result = tcs_tes[0];\n" 27508 "\n" 27509 "VARIABLE_USE" 27510 "\n" 27511 " tes_gs += result;\n" 27512 "}\n" 27513 "\n"; 27514 static const GLchar* vs = "#version 430 core\n" 27515 "#extension GL_ARB_enhanced_layouts : require\n" 27516 "\n" 27517 "in vec4 in_vs;\n" 27518 "out vec4 vs_tcs;\n" 27519 "\n" 27520 "void main()\n" 27521 "{\n" 27522 " vs_tcs = in_vs;\n" 27523 "}\n" 27524 "\n"; 27525 static const GLchar* vs_tested = "#version 430 core\n" 27526 "#extension GL_ARB_enhanced_layouts : require\n" 27527 "\n" 27528 "VAR_DEFINITION" 27529 "\n" 27530 "in vec4 in_vs;\n" 27531 "out vec4 vs_tcs;\n" 27532 "\n" 27533 "void main()\n" 27534 "{\n" 27535 " vec4 result = in_vs;\n" 27536 "\n" 27537 "VARIABLE_USE" 27538 "\n" 27539 " vs_tcs = result;\n" 27540 "}\n" 27541 "\n"; 27542 27543 std::string source; 27544 testCase& test_case = m_test_cases[test_case_index]; 27545 27546 if (test_case.m_stage == stage) 27547 { 27548 const GLchar* array = ""; 27549 const GLchar* index = ""; 27550 size_t position = 0; 27551 27552 switch (stage) 27553 { 27554 case Utils::Shader::GEOMETRY: 27555 source = gs_tested; 27556 array = "[]"; 27557 index = "[0]"; 27558 break; 27559 case Utils::Shader::TESS_CTRL: 27560 source = tcs_tested; 27561 array = "[]"; 27562 index = "[gl_InvocationID]"; 27563 break; 27564 case Utils::Shader::TESS_EVAL: 27565 source = tes_tested; 27566 array = "[]"; 27567 index = "[0]"; 27568 break; 27569 case Utils::Shader::VERTEX: 27570 source = vs_tested; 27571 break; 27572 default: 27573 TCU_FAIL("Invalid enum"); 27574 } 27575 27576 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 27577 position = 0; 27578 Utils::replaceToken("ARRAY", position, array, source); 27579 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 27580 27581 Utils::replaceAllTokens("INDEX", index, source); 27582 } 27583 else 27584 { 27585 switch (test_case.m_stage) 27586 { 27587 case Utils::Shader::GEOMETRY: 27588 switch (stage) 27589 { 27590 case Utils::Shader::FRAGMENT: 27591 source = fs; 27592 break; 27593 case Utils::Shader::VERTEX: 27594 source = vs; 27595 break; 27596 default: 27597 source = ""; 27598 } 27599 break; 27600 case Utils::Shader::TESS_CTRL: 27601 switch (stage) 27602 { 27603 case Utils::Shader::FRAGMENT: 27604 source = fs; 27605 break; 27606 case Utils::Shader::VERTEX: 27607 source = vs; 27608 break; 27609 default: 27610 source = ""; 27611 } 27612 break; 27613 case Utils::Shader::TESS_EVAL: 27614 switch (stage) 27615 { 27616 case Utils::Shader::FRAGMENT: 27617 source = fs; 27618 break; 27619 case Utils::Shader::TESS_CTRL: 27620 source = tcs; 27621 break; 27622 case Utils::Shader::VERTEX: 27623 source = vs; 27624 break; 27625 default: 27626 source = ""; 27627 } 27628 break; 27629 case Utils::Shader::VERTEX: 27630 switch (stage) 27631 { 27632 case Utils::Shader::FRAGMENT: 27633 source = fs; 27634 break; 27635 default: 27636 source = ""; 27637 } 27638 break; 27639 default: 27640 TCU_FAIL("Invalid enum"); 27641 break; 27642 } 27643 } 27644 27645 return source; 27646 } 27647 27648 /** Get description of test case 27649 * 27650 * @param test_case_index Index of test case 27651 * 27652 * @return Test case description 27653 **/ 27654 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index) 27655 { 27656 std::stringstream stream; 27657 testCase& test_case = m_test_cases[test_case_index]; 27658 27659 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage); 27660 27661 return stream.str(); 27662 } 27663 27664 /** Get number of test cases 27665 * 27666 * @return Number of test cases 27667 **/ 27668 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber() 27669 { 27670 return static_cast<GLuint>(m_test_cases.size()); 27671 } 27672 27673 /** Selects if "compute" stage is relevant for test 27674 * 27675 * @param ignored 27676 * 27677 * @return false 27678 **/ 27679 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */) 27680 { 27681 return false; 27682 } 27683 27684 /** Prepare all test cases 27685 * 27686 **/ 27687 void XFBCaptureUnsizedArrayTest::testInit() 27688 { 27689 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 27690 { 27691 /* Not aplicable for */ 27692 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) || 27693 (Utils::Shader::GEOMETRY == stage) || (Utils::Shader::TESS_EVAL == stage)) 27694 { 27695 continue; 27696 } 27697 27698 testCase test_case = { (Utils::Shader::STAGES)stage }; 27699 27700 m_test_cases.push_back(test_case); 27701 } 27702 } 27703 } /* EnhancedLayouts namespace */ 27704 27705 /** Constructor. 27706 * 27707 * @param context Rendering context. 27708 **/ 27709 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context& context) 27710 : TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality") 27711 { 27712 /* Left blank on purpose */ 27713 } 27714 27715 /** Initializes a texture_storage_multisample test group. 27716 * 27717 **/ 27718 void EnhancedLayoutsTests::init(void) 27719 { 27720 addChild(new EnhancedLayouts::APIConstantValuesTest(m_context)); 27721 addChild(new EnhancedLayouts::APIErrorsTest(m_context)); 27722 addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context)); 27723 addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context)); 27724 addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context)); 27725 addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context)); 27726 addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context)); 27727 addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context)); 27728 addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context)); 27729 addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context)); 27730 addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context)); 27731 addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context)); 27732 addChild(new EnhancedLayouts::XFBInputTest(m_context)); 27733 addChild(new EnhancedLayouts::XFBAllStagesTest(m_context)); 27734 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context)); 27735 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context)); 27736 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context)); 27737 addChild(new EnhancedLayouts::XFBStrideTest(m_context)); 27738 27739 addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context)); 27740 addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context)); 27741 addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context)); 27742 addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context)); 27743 addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context)); 27744 addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context)); 27745 addChild(new EnhancedLayouts::SSBAlignmentTest(m_context)); 27746 addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context)); 27747 addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context)); 27748 addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context)); 27749 addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context)); 27750 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context)); 27751 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context)); 27752 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context)); 27753 addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context)); 27754 addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context)); 27755 addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context)); 27756 addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context)); 27757 addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context)); 27758 addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context)); 27759 addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context)); 27760 addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context)); 27761 addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context)); 27762 addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context)); 27763 addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context)); 27764 addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context)); 27765 addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context)); 27766 addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context)); 27767 addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context)); 27768 addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context)); 27769 addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context)); 27770 addChild(new EnhancedLayouts::VaryingLocationsTest(m_context)); 27771 addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context)); 27772 addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context)); 27773 addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context)); 27774 addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context)); 27775 addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context)); 27776 addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context)); 27777 addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context)); 27778 addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context)); 27779 addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context)); 27780 addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context)); 27781 addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context)); 27782 addChild(new EnhancedLayouts::VaryingComponentsTest(m_context)); 27783 addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context)); 27784 } 27785 27786 } /* gl4cts namespace */ 27787