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, 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 // If struct variable is an array 1095 if (0 != variable.m_descriptor.m_n_array_elements) 1096 { 1097 for (GLuint i = 0; i < variable.m_descriptor.m_n_array_elements; i++) 1098 { 1099 GLchar buffer[16]; 1100 sprintf(buffer, "%d", i); 1101 structVariable.append("["); 1102 structVariable.append(buffer); 1103 structVariable.append("]"); 1104 for (size_t j = 0; j < n_members; ++j) 1105 { 1106 const Variable::Descriptor& member = interface->m_members[j]; 1107 bool member_result = verifyVarying(program, structVariable, member, stream, is_input); 1108 1109 if (false == member_result) 1110 { 1111 result = false; 1112 } 1113 } 1114 } 1115 } 1116 else 1117 { 1118 for (GLuint i = 0; i < n_members; ++i) 1119 { 1120 const Variable::Descriptor& member = interface->m_members[i]; 1121 bool member_result = verifyVarying(program, structVariable, member, stream, is_input); 1122 1123 if (false == member_result) 1124 { 1125 result = false; 1126 } 1127 } 1128 } 1129 } 1130 else 1131 { 1132 result = verifyVarying(program, "", variable.m_descriptor, stream, is_input); 1133 } 1134 return result; 1135 } 1136 1137 /** Query program resource for given variable and verify that everything is as expected 1138 * 1139 * @param program Program object 1140 * @param variable Variable object 1141 * @param stream Stream that will be used to log any error 1142 * 1143 * @return true if verification is positive, false otherwise 1144 **/ 1145 bool checkUniform(Program& program, const Utils::Variable& variable, std::stringstream& stream) 1146 { 1147 bool result = true; 1148 1149 if (false == variable.IsBlock()) 1150 { 1151 TCU_FAIL("Not implemented"); 1152 } 1153 else 1154 { 1155 Utils::Interface* interface = variable.m_descriptor.m_interface; 1156 1157 size_t size = interface->m_members.size(); 1158 1159 std::vector<GLuint> indices; 1160 std::vector<const char*> names; 1161 std::vector<std::string> names_str; 1162 std::vector<GLint> offsets; 1163 1164 indices.resize(size); 1165 names.resize(size); 1166 names_str.resize(size); 1167 offsets.resize(size); 1168 1169 for (size_t i = 0; i < size; ++i) 1170 { 1171 indices[i] = 0; 1172 offsets[i] = 0; 1173 1174 const std::string& name = 1175 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0); 1176 1177 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type) 1178 { 1179 const std::string& member_name = Utils::Variable::GetReference( 1180 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0); 1181 1182 names_str[i] = member_name; 1183 } 1184 else 1185 { 1186 names_str[i] = name; 1187 } 1188 1189 names[i] = names_str[i].c_str(); 1190 } 1191 1192 try 1193 { 1194 program.GetUniformIndices(static_cast<glw::GLsizei>(size), &names[0], &indices[0]); 1195 program.GetActiveUniformsiv(static_cast<glw::GLsizei>(size), &indices[0], GL_UNIFORM_OFFSET, &offsets[0]); 1196 } 1197 catch (std::exception& exc) 1198 { 1199 stream << "Failed to query program for uniforms in block: " << variable.m_descriptor.m_name 1200 << ". Reason: " << exc.what() << "\n"; 1201 1202 return false; 1203 } 1204 1205 for (size_t i = 0; i < size; ++i) 1206 { 1207 Utils::Variable::Descriptor& desc = interface->m_members[i]; 1208 1209 if (offsets[i] != (GLint)desc.m_offset) 1210 { 1211 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offsets[i] 1212 << " expected: " << desc.m_offset << std::endl; 1213 result = false; 1214 } 1215 } 1216 } 1217 1218 return result; 1219 } 1220 1221 /** Query program resource for given variable and verify that everything is as expected 1222 * 1223 * @param program Program object 1224 * @param variable Variable object 1225 * @param stream Stream that will be used to log any error 1226 * 1227 * @return true if verification is positive, false otherwise 1228 **/ 1229 bool checkSSB(Program& program, const Utils::Variable& variable, std::stringstream& stream) 1230 { 1231 bool result = true; 1232 1233 if (false == variable.IsBlock()) 1234 { 1235 TCU_FAIL("Not implemented"); 1236 } 1237 else 1238 { 1239 Utils::Interface* interface = variable.m_descriptor.m_interface; 1240 1241 size_t size = interface->m_members.size(); 1242 1243 for (size_t i = 0; i < size; ++i) 1244 { 1245 GLuint index = 0; 1246 std::string name_str = ""; 1247 GLint offset = 0; 1248 1249 const std::string& name = 1250 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0); 1251 1252 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type) 1253 { 1254 const std::string& member_name = Utils::Variable::GetReference( 1255 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0); 1256 1257 name_str = member_name; 1258 } 1259 else 1260 { 1261 name_str = name; 1262 } 1263 1264 try 1265 { 1266 index = program.GetResourceIndex(name_str, GL_BUFFER_VARIABLE); 1267 1268 program.GetResource(GL_BUFFER_VARIABLE, index, GL_OFFSET, 1, &offset); 1269 } 1270 catch (std::exception& exc) 1271 { 1272 stream << "Failed to query program for buffer variable: " << variable.m_descriptor.m_name 1273 << ". Reason: " << exc.what() << "\n"; 1274 1275 return false; 1276 } 1277 1278 Utils::Variable::Descriptor& desc = interface->m_members[i]; 1279 1280 if (offset != (GLint)desc.m_offset) 1281 { 1282 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offset 1283 << " expected: " << desc.m_offset << std::endl; 1284 result = false; 1285 } 1286 } 1287 } 1288 1289 return result; 1290 } 1291 1292 /** Query program resources at given stage and verifies results 1293 * 1294 * @param program Program object 1295 * @param program_interface Definition of program interface 1296 * @param stage Stage to be verified 1297 * @param check_inputs Select if inputs should be verified 1298 * @param check_outputs Select if output should be verified 1299 * @param check_uniforms Select if uniforms should be verified 1300 * @param check_ssbs Select if buffers should be verified 1301 * @param stream Stream that will be used to log any error 1302 * 1303 * @return true if verification is positive, false otherwise 1304 **/ 1305 bool checkProgramStage(Program& program, const ProgramInterface& program_interface, Utils::Shader::STAGES stage, 1306 bool check_inputs, bool check_outputs, bool check_uniforms, bool check_ssbs, 1307 std::stringstream& stream) 1308 { 1309 typedef Variable::PtrVector::const_iterator const_iterator; 1310 1311 const ShaderInterface& interface = program_interface.GetShaderInterface(stage); 1312 1313 bool result = true; 1314 1315 /* Inputs */ 1316 if (true == check_inputs) 1317 { 1318 const Variable::PtrVector& inputs = interface.m_inputs; 1319 1320 for (const_iterator it = inputs.begin(); it != inputs.end(); ++it) 1321 { 1322 if (false == checkVarying(program, **it, stream, true)) 1323 { 1324 result = false; 1325 } 1326 } 1327 } 1328 1329 /* Outputs */ 1330 if (true == check_outputs) 1331 { 1332 const Variable::PtrVector& outputs = interface.m_outputs; 1333 1334 for (const_iterator it = outputs.begin(); it != outputs.end(); ++it) 1335 { 1336 if (false == checkVarying(program, **it, stream, false)) 1337 { 1338 result = false; 1339 } 1340 } 1341 } 1342 1343 /* Uniforms */ 1344 if (true == check_uniforms) 1345 { 1346 const Variable::PtrVector& uniforms = interface.m_uniforms; 1347 1348 for (const_iterator it = uniforms.begin(); it != uniforms.end(); ++it) 1349 { 1350 if (false == checkUniform(program, **it, stream)) 1351 { 1352 result = false; 1353 } 1354 } 1355 } 1356 1357 /* SSBs */ 1358 if (true == check_ssbs) 1359 { 1360 const Variable::PtrVector& ssbs = interface.m_ssb_blocks; 1361 1362 for (const_iterator it = ssbs.begin(); it != ssbs.end(); ++it) 1363 { 1364 if (false == checkSSB(program, **it, stream)) 1365 { 1366 result = false; 1367 } 1368 } 1369 } 1370 1371 return result; 1372 } 1373 1374 /** Query resources of monolithic compute program and verifies results 1375 * 1376 * @param program Program object 1377 * @param program_interface Definition of program interface 1378 * @param stream Stream that will be used to log any error 1379 * 1380 * @return true if verification is positive, false otherwise 1381 **/ 1382 bool checkMonolithicComputeProgramInterface(Program& program, const ProgramInterface& program_interface, 1383 std::stringstream& stream) 1384 { 1385 bool result = true; 1386 1387 if (false == checkProgramStage(program, program_interface, Shader::COMPUTE, false, false, true, true, stream)) 1388 { 1389 result = false; 1390 } 1391 1392 /* Done */ 1393 return result; 1394 } 1395 1396 /** Query resources of monolithic draw program and verifies results 1397 * 1398 * @param program Program object 1399 * @param program_interface Definition of program interface 1400 * @param stream Stream that will be used to log any error 1401 * 1402 * @return true if verification is positive, false otherwise 1403 **/ 1404 bool checkMonolithicDrawProgramInterface(Program& program, const ProgramInterface& program_interface, 1405 std::stringstream& stream) 1406 { 1407 bool result = true; 1408 1409 if (false == checkProgramStage(program, program_interface, Shader::VERTEX, true, false, true, true, stream)) 1410 { 1411 result = false; 1412 } 1413 1414 /* Done */ 1415 return result; 1416 } 1417 1418 /** Query resources of separable draw program and verifies results 1419 * 1420 * @param program Program object 1421 * @param program_interface Definition of program interface 1422 * @param stream Stream that will be used to log any error 1423 * 1424 * @return true if verification is positive, false otherwise 1425 **/ 1426 bool checkSeparableDrawProgramInterface(Program& program, const ProgramInterface& program_interface, 1427 Utils::Shader::STAGES stage, std::stringstream& stream) 1428 { 1429 bool result = true; 1430 1431 if (false == checkProgramStage(program, program_interface, stage, true, true, true, true, stream)) 1432 { 1433 result = false; 1434 } 1435 1436 /* Done */ 1437 return result; 1438 } 1439 1440 /** Check if extension is supported 1441 * 1442 * @param context Test context 1443 * @param extension_name Name of extension 1444 * 1445 * @return true if extension is supported, false otherwise 1446 **/ 1447 bool isExtensionSupported(deqp::Context& context, const GLchar* extension_name) 1448 { 1449 const std::vector<std::string>& extensions = context.getContextInfo().getExtensions(); 1450 1451 if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end()) 1452 { 1453 return false; 1454 } 1455 1456 return true; 1457 } 1458 1459 /** Check if GL context meets version requirements 1460 * 1461 * @param gl Functions 1462 * @param required_major Minimum required MAJOR_VERSION 1463 * @param required_minor Minimum required MINOR_VERSION 1464 * 1465 * @return true if GL context version is at least as requested, false otherwise 1466 **/ 1467 bool isGLVersionAtLeast(const Functions& gl, GLint required_major, GLint required_minor) 1468 { 1469 glw::GLint major = 0; 1470 glw::GLint minor = 0; 1471 1472 gl.getIntegerv(GL_MAJOR_VERSION, &major); 1473 gl.getIntegerv(GL_MINOR_VERSION, &minor); 1474 1475 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 1476 1477 if (major > required_major) 1478 { 1479 /* Major is higher than required one */ 1480 return true; 1481 } 1482 else if (major == required_major) 1483 { 1484 if (minor >= required_minor) 1485 { 1486 /* Major is equal to required one */ 1487 /* Minor is higher than or equal to required one */ 1488 return true; 1489 } 1490 else 1491 { 1492 /* Major is equal to required one */ 1493 /* Minor is lower than required one */ 1494 return false; 1495 } 1496 } 1497 else 1498 { 1499 /* Major is lower than required one */ 1500 return false; 1501 } 1502 } 1503 1504 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion> 1505 * 1506 * @param token Token string 1507 * @param search_position Position at which find will start, it is updated to position at which replaced text ends 1508 * @param text String that will be used as replacement for <token> 1509 * @param string String to work on 1510 **/ 1511 void replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string) 1512 { 1513 const size_t text_length = strlen(text); 1514 const size_t token_length = strlen(token); 1515 const size_t token_position = string.find(token, search_position); 1516 1517 #if DEBUG_REPLACE_TOKEN 1518 if (std::string::npos == token_position) 1519 { 1520 string.append("\n\nInvalid token: "); 1521 string.append(token); 1522 1523 TCU_FAIL(string.c_str()); 1524 } 1525 #endif /* DEBUG_REPLACE_TOKEN */ 1526 1527 string.replace(token_position, token_length, text, text_length); 1528 1529 search_position = token_position + text_length; 1530 } 1531 1532 /** Replace all occurances of <token> with <text> in <string> 1533 * 1534 * @param token Token string 1535 * @param text String that will be used as replacement for <token> 1536 * @param string String to work on 1537 **/ 1538 void replaceAllTokens(const GLchar* token, const GLchar* text, std::string& string) 1539 { 1540 const size_t text_length = strlen(text); 1541 const size_t token_length = strlen(token); 1542 1543 size_t search_position = 0; 1544 1545 while (1) 1546 { 1547 const size_t token_position = string.find(token, search_position); 1548 1549 if (std::string::npos == token_position) 1550 { 1551 break; 1552 } 1553 1554 search_position = token_position + text_length; 1555 1556 string.replace(token_position, token_length, text, text_length); 1557 } 1558 } 1559 1560 /** Rounds up the value to the next power of 2. 1561 * This routine does not work for 0, see the url for explanations. 1562 * 1563 * @param value Starting point 1564 * 1565 * @return Calculated value 1566 **/ 1567 glw::GLuint roundUpToPowerOf2(glw::GLuint value) 1568 { 1569 /* Taken from: graphics.stanford.edu/~seander/bithacks.html */ 1570 --value; 1571 1572 value |= value >> 1; 1573 value |= value >> 2; 1574 value |= value >> 4; 1575 value |= value >> 8; 1576 value |= value >> 16; 1577 1578 ++value; 1579 1580 return value; 1581 } 1582 1583 /** Insert elements of list into string. 1584 * List in string is represented either by token "LIST" or "SEPARATORLIST". 1585 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>. 1586 * LIST is replaced with <element>SEPARATORLIST 1587 * 1588 * @param element Element to be inserted 1589 * @param separator Separator inserted between elements 1590 * @param search_position Position in string, where search for list should start 1591 * @param string String 1592 **/ 1593 void insertElementOfList(const GLchar* element, const GLchar* separator, size_t& search_position, std::string& string) 1594 { 1595 static const char* list = g_list; 1596 static const char* sep_list = "SEPARATORLIST"; 1597 1598 /* Try to get "list" positions */ 1599 const size_t list_position = string.find(list, search_position); 1600 const size_t sep_list_position = string.find(sep_list, search_position); 1601 1602 /* There is no list in string */ 1603 if (std::string::npos == list_position) 1604 { 1605 return; 1606 } 1607 1608 if (9 /* strlen(SEPARATOR) */ == list_position - sep_list_position) 1609 { 1610 replaceToken("SEPARATOR", search_position, separator, string); 1611 } 1612 1613 /* Save search_position */ 1614 const size_t start_position = search_position; 1615 1616 /* Prepare new element */ 1617 replaceToken("LIST", search_position, "ELEMENTSEPARATORLIST", string); 1618 1619 /* Restore search_position */ 1620 search_position = start_position; 1621 1622 /* Replace element and separator */ 1623 replaceToken("ELEMENT", search_position, element, string); 1624 } 1625 1626 /** Close list in string. 1627 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator> 1628 * LIST is replaced with "" 1629 * 1630 * @param separator Separator inserted between elements 1631 * @param search_position Position in string, where search for list should start 1632 * @param string String 1633 **/ 1634 void endList(const glw::GLchar* separator, size_t& search_position, std::string& string) 1635 { 1636 const size_t sep_position = string.find("SEPARATOR", search_position); 1637 if (std::string::npos != sep_position) 1638 { 1639 replaceToken("SEPARATOR", search_position, separator, string); 1640 } 1641 1642 replaceToken("LIST", search_position, "", string); 1643 } 1644 1645 /* Buffer constants */ 1646 const GLuint Buffer::m_invalid_id = -1; 1647 1648 /** Constructor. 1649 * 1650 * @param context CTS context. 1651 **/ 1652 Buffer::Buffer(deqp::Context& context) : m_id(m_invalid_id), m_buffer(Array), m_context(context) 1653 { 1654 } 1655 1656 /** Destructor 1657 * 1658 **/ 1659 Buffer::~Buffer() 1660 { 1661 Release(); 1662 } 1663 1664 /** Initialize buffer instance 1665 * 1666 * @param buffer Buffer type 1667 * @param usage Buffer usage enum 1668 * @param size <size> parameter 1669 * @param data <data> parameter 1670 **/ 1671 void Buffer::Init(BUFFERS buffer, USAGE usage, GLsizeiptr size, GLvoid* data) 1672 { 1673 /* Delete previous buffer instance */ 1674 Release(); 1675 1676 m_buffer = buffer; 1677 1678 const Functions& gl = m_context.getRenderContext().getFunctions(); 1679 1680 Generate(gl, m_id); 1681 Bind(gl, m_id, m_buffer); 1682 Data(gl, m_buffer, usage, size, data); 1683 } 1684 1685 /** Release buffer instance 1686 * 1687 **/ 1688 void Buffer::Release() 1689 { 1690 if (m_invalid_id != m_id) 1691 { 1692 const Functions& gl = m_context.getRenderContext().getFunctions(); 1693 1694 gl.deleteBuffers(1, &m_id); 1695 m_id = m_invalid_id; 1696 } 1697 } 1698 1699 /** Binds buffer to its target 1700 * 1701 **/ 1702 void Buffer::Bind() const 1703 { 1704 const Functions& gl = m_context.getRenderContext().getFunctions(); 1705 1706 Bind(gl, m_id, m_buffer); 1707 } 1708 1709 /** Binds indexed buffer 1710 * 1711 * @param index <index> parameter 1712 **/ 1713 void Buffer::BindBase(GLuint index) const 1714 { 1715 const Functions& gl = m_context.getRenderContext().getFunctions(); 1716 1717 BindBase(gl, m_id, m_buffer, index); 1718 } 1719 1720 /** Binds range of buffer 1721 * 1722 * @param index <index> parameter 1723 * @param offset <offset> parameter 1724 * @param size <size> parameter 1725 **/ 1726 void Buffer::BindRange(GLuint index, GLintptr offset, GLsizeiptr size) const 1727 { 1728 const Functions& gl = m_context.getRenderContext().getFunctions(); 1729 1730 BindRange(gl, m_id, m_buffer, index, offset, size); 1731 } 1732 1733 /** Allocate memory for buffer and sends initial content 1734 * 1735 * @param usage Buffer usage enum 1736 * @param size <size> parameter 1737 * @param data <data> parameter 1738 **/ 1739 void Buffer::Data(USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data) 1740 { 1741 const Functions& gl = m_context.getRenderContext().getFunctions(); 1742 1743 Data(gl, m_buffer, usage, size, data); 1744 } 1745 1746 /** Maps contents of buffer into CPU space 1747 * 1748 * @param access Requested access 1749 * 1750 * @return Pointer to memory region available for CPU 1751 **/ 1752 GLvoid* Buffer::Map(ACCESS access) 1753 { 1754 const Functions& gl = m_context.getRenderContext().getFunctions(); 1755 1756 return Map(gl, m_buffer, access); 1757 } 1758 1759 /** Allocate memory for buffer and sends initial content 1760 * 1761 * @param offset Offset in buffer 1762 * @param size <size> parameter 1763 * @param data <data> parameter 1764 **/ 1765 void Buffer::SubData(glw::GLintptr offset, glw::GLsizeiptr size, glw::GLvoid* data) 1766 { 1767 const Functions& gl = m_context.getRenderContext().getFunctions(); 1768 1769 SubData(gl, m_buffer, offset, size, data); 1770 } 1771 1772 /** Maps contents of buffer into CPU space 1773 **/ 1774 void Buffer::UnMap() 1775 { 1776 const Functions& gl = m_context.getRenderContext().getFunctions(); 1777 1778 return UnMap(gl, m_buffer); 1779 } 1780 1781 /** Bind buffer to given target 1782 * 1783 * @param gl GL functions 1784 * @param id Id of buffer 1785 * @param buffer Buffer enum 1786 **/ 1787 void Buffer::Bind(const Functions& gl, GLuint id, BUFFERS buffer) 1788 { 1789 GLenum target = GetBufferGLenum(buffer); 1790 1791 gl.bindBuffer(target, id); 1792 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer"); 1793 } 1794 1795 /** Binds indexed buffer 1796 * 1797 * @param gl GL functions 1798 * @param id Id of buffer 1799 * @param buffer Buffer enum 1800 * @param index <index> parameter 1801 **/ 1802 void Buffer::BindBase(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index) 1803 { 1804 GLenum target = GetBufferGLenum(buffer); 1805 1806 gl.bindBufferBase(target, index, id); 1807 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase"); 1808 } 1809 1810 /** Binds buffer range 1811 * 1812 * @param gl GL functions 1813 * @param id Id of buffer 1814 * @param buffer Buffer enum 1815 * @param index <index> parameter 1816 * @param offset <offset> parameter 1817 * @param size <size> parameter 1818 **/ 1819 void Buffer::BindRange(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index, GLintptr offset, GLsizeiptr size) 1820 { 1821 GLenum target = GetBufferGLenum(buffer); 1822 1823 gl.bindBufferRange(target, index, id, offset, size); 1824 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange"); 1825 } 1826 1827 /** Allocate memory for buffer and sends initial content 1828 * 1829 * @param gl GL functions 1830 * @param buffer Buffer enum 1831 * @param usage Buffer usage enum 1832 * @param size <size> parameter 1833 * @param data <data> parameter 1834 **/ 1835 void Buffer::Data(const glw::Functions& gl, BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data) 1836 { 1837 GLenum target = GetBufferGLenum(buffer); 1838 GLenum gl_usage = GetUsageGLenum(usage); 1839 1840 gl.bufferData(target, size, data, gl_usage); 1841 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData"); 1842 } 1843 1844 /** Allocate memory for buffer and sends initial content 1845 * 1846 * @param gl GL functions 1847 * @param buffer Buffer enum 1848 * @param offset Offset in buffer 1849 * @param size <size> parameter 1850 * @param data <data> parameter 1851 **/ 1852 void Buffer::SubData(const glw::Functions& gl, BUFFERS buffer, glw::GLintptr offset, glw::GLsizeiptr size, 1853 glw::GLvoid* data) 1854 { 1855 GLenum target = GetBufferGLenum(buffer); 1856 1857 gl.bufferSubData(target, offset, size, data); 1858 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData"); 1859 } 1860 1861 /** Generate buffer 1862 * 1863 * @param gl GL functions 1864 * @param out_id Id of buffer 1865 **/ 1866 void Buffer::Generate(const Functions& gl, GLuint& out_id) 1867 { 1868 GLuint id = m_invalid_id; 1869 1870 gl.genBuffers(1, &id); 1871 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers"); 1872 1873 if (m_invalid_id == id) 1874 { 1875 TCU_FAIL("Got invalid id"); 1876 } 1877 1878 out_id = id; 1879 } 1880 1881 /** Maps buffer content 1882 * 1883 * @param gl GL functions 1884 * @param buffer Buffer enum 1885 * @param access Access rights for mapped region 1886 * 1887 * @return Mapped memory 1888 **/ 1889 void* Buffer::Map(const Functions& gl, BUFFERS buffer, ACCESS access) 1890 { 1891 GLenum target = GetBufferGLenum(buffer); 1892 GLenum gl_access = GetAccessGLenum(access); 1893 1894 void* result = gl.mapBuffer(target, gl_access); 1895 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 1896 1897 return result; 1898 } 1899 1900 /** Unmaps buffer 1901 * 1902 **/ 1903 void Buffer::UnMap(const Functions& gl, BUFFERS buffer) 1904 { 1905 GLenum target = GetBufferGLenum(buffer); 1906 1907 gl.unmapBuffer(target); 1908 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 1909 } 1910 1911 /** Return GLenum representation of requested access 1912 * 1913 * @param access Requested access 1914 * 1915 * @return GLenum value 1916 **/ 1917 GLenum Buffer::GetAccessGLenum(ACCESS access) 1918 { 1919 GLenum result = 0; 1920 1921 switch (access) 1922 { 1923 case ReadOnly: 1924 result = GL_READ_ONLY; 1925 break; 1926 case WriteOnly: 1927 result = GL_WRITE_ONLY; 1928 break; 1929 case ReadWrite: 1930 result = GL_READ_WRITE; 1931 break; 1932 default: 1933 TCU_FAIL("Invalid enum"); 1934 } 1935 1936 return result; 1937 } 1938 1939 /** Return GLenum representation of requested buffer type 1940 * 1941 * @param buffer Requested buffer type 1942 * 1943 * @return GLenum value 1944 **/ 1945 GLenum Buffer::GetBufferGLenum(BUFFERS buffer) 1946 { 1947 GLenum result = 0; 1948 1949 switch (buffer) 1950 { 1951 case Array: 1952 result = GL_ARRAY_BUFFER; 1953 break; 1954 case Element: 1955 result = GL_ELEMENT_ARRAY_BUFFER; 1956 break; 1957 case Shader_Storage: 1958 result = GL_SHADER_STORAGE_BUFFER; 1959 break; 1960 case Texture: 1961 result = GL_TEXTURE_BUFFER; 1962 break; 1963 case Transform_feedback: 1964 result = GL_TRANSFORM_FEEDBACK_BUFFER; 1965 break; 1966 case Uniform: 1967 result = GL_UNIFORM_BUFFER; 1968 break; 1969 default: 1970 TCU_FAIL("Invalid enum"); 1971 } 1972 1973 return result; 1974 } 1975 1976 /** Return GLenum representation of requested usage 1977 * 1978 * @param usage Requested usage 1979 * 1980 * @return GLenum value 1981 **/ 1982 GLenum Buffer::GetUsageGLenum(USAGE usage) 1983 { 1984 GLenum result = 0; 1985 1986 switch (usage) 1987 { 1988 case DynamicCopy: 1989 result = GL_DYNAMIC_COPY; 1990 break; 1991 case DynamicDraw: 1992 result = GL_DYNAMIC_DRAW; 1993 break; 1994 case DynamicRead: 1995 result = GL_DYNAMIC_READ; 1996 break; 1997 case StaticCopy: 1998 result = GL_STATIC_COPY; 1999 break; 2000 case StaticDraw: 2001 result = GL_STATIC_DRAW; 2002 break; 2003 case StaticRead: 2004 result = GL_STATIC_READ; 2005 break; 2006 case StreamCopy: 2007 result = GL_STREAM_COPY; 2008 break; 2009 case StreamDraw: 2010 result = GL_STREAM_DRAW; 2011 break; 2012 case StreamRead: 2013 result = GL_STREAM_READ; 2014 break; 2015 default: 2016 TCU_FAIL("Invalid enum"); 2017 } 2018 2019 return result; 2020 } 2021 2022 /** Returns name of buffer target 2023 * 2024 * @param buffer Target enum 2025 * 2026 * @return Name of target 2027 **/ 2028 const GLchar* Buffer::GetBufferName(BUFFERS buffer) 2029 { 2030 const GLchar* name = 0; 2031 2032 switch (buffer) 2033 { 2034 case Array: 2035 name = "Array"; 2036 break; 2037 case Element: 2038 name = "Element"; 2039 break; 2040 case Shader_Storage: 2041 name = "Shader_Storage"; 2042 break; 2043 case Texture: 2044 name = "Texture"; 2045 break; 2046 case Transform_feedback: 2047 name = "Transform_feedback"; 2048 break; 2049 case Uniform: 2050 name = "Uniform"; 2051 break; 2052 default: 2053 TCU_FAIL("Invalid enum"); 2054 } 2055 2056 return name; 2057 } 2058 2059 /* Framebuffer constants */ 2060 const GLuint Framebuffer::m_invalid_id = -1; 2061 2062 /** Constructor 2063 * 2064 * @param context CTS context 2065 **/ 2066 Framebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 2067 { 2068 /* Nothing to be done here */ 2069 } 2070 2071 /** Destructor 2072 * 2073 **/ 2074 Framebuffer::~Framebuffer() 2075 { 2076 Release(); 2077 } 2078 2079 /** Initialize framebuffer instance 2080 * 2081 **/ 2082 void Framebuffer::Init() 2083 { 2084 /* Delete previous instance */ 2085 Release(); 2086 2087 const Functions& gl = m_context.getRenderContext().getFunctions(); 2088 2089 Generate(gl, m_id); 2090 } 2091 2092 /** Release framebuffer instance 2093 * 2094 **/ 2095 void Framebuffer::Release() 2096 { 2097 if (m_invalid_id != m_id) 2098 { 2099 const Functions& gl = m_context.getRenderContext().getFunctions(); 2100 2101 gl.deleteFramebuffers(1, &m_id); 2102 m_id = m_invalid_id; 2103 } 2104 } 2105 2106 /** Attach texture to specified attachment 2107 * 2108 * @param attachment Attachment 2109 * @param texture_id Texture id 2110 * @param width Texture width 2111 * @param height Texture height 2112 **/ 2113 void Framebuffer::AttachTexture(GLenum attachment, GLuint texture_id, GLuint width, GLuint height) 2114 { 2115 const Functions& gl = m_context.getRenderContext().getFunctions(); 2116 2117 AttachTexture(gl, attachment, texture_id, width, height); 2118 } 2119 2120 /** Binds framebuffer to DRAW_FRAMEBUFFER 2121 * 2122 **/ 2123 void Framebuffer::Bind() 2124 { 2125 const Functions& gl = m_context.getRenderContext().getFunctions(); 2126 2127 Bind(gl, m_id); 2128 } 2129 2130 /** Clear framebuffer 2131 * 2132 * @param mask <mask> parameter of glClear. Decides which shall be cleared 2133 **/ 2134 void Framebuffer::Clear(GLenum mask) 2135 { 2136 const Functions& gl = m_context.getRenderContext().getFunctions(); 2137 2138 Clear(gl, mask); 2139 } 2140 2141 /** Specifies clear color 2142 * 2143 * @param red Red channel 2144 * @param green Green channel 2145 * @param blue Blue channel 2146 * @param alpha Alpha channel 2147 **/ 2148 void Framebuffer::ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) 2149 { 2150 const Functions& gl = m_context.getRenderContext().getFunctions(); 2151 2152 ClearColor(gl, red, green, blue, alpha); 2153 } 2154 2155 /** Attach texture to specified attachment 2156 * 2157 * @param gl GL functions 2158 * @param attachment Attachment 2159 * @param texture_id Texture id 2160 * @param width Texture width 2161 * @param height Texture height 2162 **/ 2163 void Framebuffer::AttachTexture(const Functions& gl, GLenum attachment, GLuint texture_id, GLuint width, GLuint height) 2164 { 2165 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */); 2166 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture"); 2167 2168 gl.viewport(0 /* x */, 0 /* y */, width, height); 2169 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport"); 2170 } 2171 2172 /** Binds framebuffer to DRAW_FRAMEBUFFER 2173 * 2174 * @param gl GL functions 2175 * @param id ID of framebuffer 2176 **/ 2177 void Framebuffer::Bind(const Functions& gl, GLuint id) 2178 { 2179 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, id); 2180 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer"); 2181 } 2182 2183 /** Clear framebuffer 2184 * 2185 * @param gl GL functions 2186 * @param mask <mask> parameter of glClear. Decides which shall be cleared 2187 **/ 2188 void Framebuffer::Clear(const Functions& gl, GLenum mask) 2189 { 2190 gl.clear(mask); 2191 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear"); 2192 } 2193 2194 /** Specifies clear color 2195 * 2196 * @param gl GL functions 2197 * @param red Red channel 2198 * @param green Green channel 2199 * @param blue Blue channel 2200 * @param alpha Alpha channel 2201 **/ 2202 void Framebuffer::ClearColor(const Functions& gl, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) 2203 { 2204 gl.clearColor(red, green, blue, alpha); 2205 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor"); 2206 } 2207 2208 /** Generate framebuffer 2209 * 2210 **/ 2211 void Framebuffer::Generate(const Functions& gl, GLuint& out_id) 2212 { 2213 GLuint id = m_invalid_id; 2214 2215 gl.genFramebuffers(1, &id); 2216 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers"); 2217 2218 if (m_invalid_id == id) 2219 { 2220 TCU_FAIL("Invalid id"); 2221 } 2222 2223 out_id = id; 2224 } 2225 2226 /* Shader's constants */ 2227 const GLuint Shader::m_invalid_id = 0; 2228 2229 /** Constructor. 2230 * 2231 * @param context CTS context. 2232 **/ 2233 Shader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 2234 { 2235 /* Nothing to be done here */ 2236 } 2237 2238 /** Destructor 2239 * 2240 **/ 2241 Shader::~Shader() 2242 { 2243 Release(); 2244 } 2245 2246 /** Initialize shader instance 2247 * 2248 * @param stage Shader stage 2249 * @param source Source code 2250 **/ 2251 void Shader::Init(STAGES stage, const std::string& source) 2252 { 2253 if (true == source.empty()) 2254 { 2255 /* No source == no shader */ 2256 return; 2257 } 2258 2259 /* Delete any previous shader */ 2260 Release(); 2261 2262 /* Create, set source and compile */ 2263 const Functions& gl = m_context.getRenderContext().getFunctions(); 2264 2265 Create(gl, stage, m_id); 2266 Source(gl, m_id, source); 2267 2268 try 2269 { 2270 Compile(gl, m_id); 2271 } 2272 catch (const CompilationException& exc) 2273 { 2274 throw InvalidSourceException(exc.what(), source, stage); 2275 } 2276 } 2277 2278 /** Release shader instance 2279 * 2280 **/ 2281 void Shader::Release() 2282 { 2283 if (m_invalid_id != m_id) 2284 { 2285 const Functions& gl = m_context.getRenderContext().getFunctions(); 2286 2287 gl.deleteShader(m_id); 2288 m_id = m_invalid_id; 2289 } 2290 } 2291 2292 /** Compile shader 2293 * 2294 * @param gl GL functions 2295 * @param id Shader id 2296 **/ 2297 void Shader::Compile(const Functions& gl, GLuint id) 2298 { 2299 GLint status = GL_FALSE; 2300 2301 /* Compile */ 2302 gl.compileShader(id); 2303 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader"); 2304 2305 /* Get compilation status */ 2306 gl.getShaderiv(id, GL_COMPILE_STATUS, &status); 2307 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 2308 2309 /* Log compilation error */ 2310 if (GL_TRUE != status) 2311 { 2312 glw::GLint length = 0; 2313 std::string message; 2314 2315 /* Error log length */ 2316 gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length); 2317 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 2318 2319 /* Prepare storage */ 2320 message.resize(length, 0); 2321 2322 /* Get error log */ 2323 gl.getShaderInfoLog(id, length, 0, &message[0]); 2324 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog"); 2325 2326 throw CompilationException(message.c_str()); 2327 } 2328 } 2329 2330 /** Create shader 2331 * 2332 * @param gl GL functions 2333 * @param stage Shader stage 2334 * @param out_id Shader id 2335 **/ 2336 void Shader::Create(const Functions& gl, STAGES stage, GLuint& out_id) 2337 { 2338 const GLenum shaderType = GetShaderStageGLenum(stage); 2339 const GLuint id = gl.createShader(shaderType); 2340 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 2341 2342 if (m_invalid_id == id) 2343 { 2344 TCU_FAIL("Failed to create shader"); 2345 } 2346 2347 out_id = id; 2348 } 2349 2350 /** Set shader's source code 2351 * 2352 * @param gl GL functions 2353 * @param id Shader id 2354 * @param source Shader source code 2355 **/ 2356 void Shader::Source(const Functions& gl, GLuint id, const std::string& source) 2357 { 2358 const GLchar* code = source.c_str(); 2359 2360 gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */); 2361 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource"); 2362 } 2363 2364 /** Get GLenum repesenting shader stage 2365 * 2366 * @param stage Shader stage 2367 * 2368 * @return GLenum 2369 **/ 2370 GLenum Shader::GetShaderStageGLenum(STAGES stage) 2371 { 2372 GLenum result = 0; 2373 2374 switch (stage) 2375 { 2376 case COMPUTE: 2377 result = GL_COMPUTE_SHADER; 2378 break; 2379 case FRAGMENT: 2380 result = GL_FRAGMENT_SHADER; 2381 break; 2382 case GEOMETRY: 2383 result = GL_GEOMETRY_SHADER; 2384 break; 2385 case TESS_CTRL: 2386 result = GL_TESS_CONTROL_SHADER; 2387 break; 2388 case TESS_EVAL: 2389 result = GL_TESS_EVALUATION_SHADER; 2390 break; 2391 case VERTEX: 2392 result = GL_VERTEX_SHADER; 2393 break; 2394 default: 2395 TCU_FAIL("Invalid enum"); 2396 } 2397 2398 return result; 2399 } 2400 2401 /** Get string representing name of shader stage 2402 * 2403 * @param stage Shader stage 2404 * 2405 * @return String with name of shader stage 2406 **/ 2407 const glw::GLchar* Shader::GetStageName(STAGES stage) 2408 { 2409 const GLchar* result = 0; 2410 2411 switch (stage) 2412 { 2413 case COMPUTE: 2414 result = "compute"; 2415 break; 2416 case VERTEX: 2417 result = "vertex"; 2418 break; 2419 case TESS_CTRL: 2420 result = "tessellation control"; 2421 break; 2422 case TESS_EVAL: 2423 result = "tessellation evaluation"; 2424 break; 2425 case GEOMETRY: 2426 result = "geometry"; 2427 break; 2428 case FRAGMENT: 2429 result = "fragment"; 2430 break; 2431 default: 2432 TCU_FAIL("Invalid enum"); 2433 } 2434 2435 return result; 2436 } 2437 2438 /** Logs shader source 2439 * 2440 * @param context CTS context 2441 * @param source Source of shader 2442 * @param stage Shader stage 2443 **/ 2444 void Shader::LogSource(deqp::Context& context, const std::string& source, STAGES stage) 2445 { 2446 /* Skip empty shaders */ 2447 if (true == source.empty()) 2448 { 2449 return; 2450 } 2451 2452 context.getTestContext().getLog() << tcu::TestLog::Message 2453 << "Shader source. Stage: " << Shader::GetStageName(stage) 2454 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(source); 2455 } 2456 2457 /** Constructor 2458 * 2459 * @param message Compilation error message 2460 **/ 2461 Shader::CompilationException::CompilationException(const GLchar* message) 2462 { 2463 m_message = message; 2464 } 2465 2466 /** Returns error messages 2467 * 2468 * @return Compilation error message 2469 **/ 2470 const char* Shader::CompilationException::what() const throw() 2471 { 2472 return m_message.c_str(); 2473 } 2474 2475 /** Constructor 2476 * 2477 * @param message Compilation error message 2478 **/ 2479 Shader::InvalidSourceException::InvalidSourceException(const GLchar* error_message, const std::string& source, 2480 STAGES stage) 2481 : m_message(error_message), m_source(source), m_stage(stage) 2482 { 2483 } 2484 2485 /** Returns error messages 2486 * 2487 * @return Compilation error message 2488 **/ 2489 const char* Shader::InvalidSourceException::what() const throw() 2490 { 2491 return "Compilation error"; 2492 } 2493 2494 /** Logs error message and shader sources **/ 2495 void Shader::InvalidSourceException::log(deqp::Context& context) const 2496 { 2497 context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader: " << m_message.c_str() 2498 << tcu::TestLog::EndMessage; 2499 2500 LogSource(context, m_source, m_stage); 2501 } 2502 2503 /* Program constants */ 2504 const GLuint Pipeline::m_invalid_id = 0; 2505 2506 /** Constructor. 2507 * 2508 * @param context CTS context. 2509 **/ 2510 Pipeline::Pipeline(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 2511 { 2512 /* Nothing to be done here */ 2513 } 2514 2515 /** Destructor 2516 * 2517 **/ 2518 Pipeline::~Pipeline() 2519 { 2520 Release(); 2521 } 2522 2523 /** Initialize pipline object 2524 * 2525 **/ 2526 void Pipeline::Init() 2527 { 2528 Release(); 2529 2530 const Functions& gl = m_context.getRenderContext().getFunctions(); 2531 2532 /* Generate */ 2533 gl.genProgramPipelines(1, &m_id); 2534 GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines"); 2535 } 2536 2537 /** Release pipeline object 2538 * 2539 **/ 2540 void Pipeline::Release() 2541 { 2542 if (m_invalid_id != m_id) 2543 { 2544 const Functions& gl = m_context.getRenderContext().getFunctions(); 2545 2546 /* Generate */ 2547 gl.deleteProgramPipelines(1, &m_id); 2548 GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteProgramPipelines"); 2549 2550 m_id = m_invalid_id; 2551 } 2552 } 2553 2554 /** Bind pipeline 2555 * 2556 **/ 2557 void Pipeline::Bind() 2558 { 2559 const Functions& gl = m_context.getRenderContext().getFunctions(); 2560 2561 Bind(gl, m_id); 2562 } 2563 2564 /** Set which stages should be active 2565 * 2566 * @param program_id Id of program 2567 * @param stages Logical combination of enums representing stages 2568 **/ 2569 void Pipeline::UseProgramStages(GLuint program_id, GLenum stages) 2570 { 2571 const Functions& gl = m_context.getRenderContext().getFunctions(); 2572 2573 UseProgramStages(gl, m_id, program_id, stages); 2574 } 2575 2576 /** Bind pipeline 2577 * 2578 * @param gl Functiions 2579 * @param id Pipeline id 2580 **/ 2581 void Pipeline::Bind(const Functions& gl, GLuint id) 2582 { 2583 gl.bindProgramPipeline(id); 2584 GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline"); 2585 } 2586 2587 /** Set which stages should be active 2588 * 2589 * @param gl Functiions 2590 * @param id Pipeline id 2591 * @param program_id Id of program 2592 * @param stages Logical combination of enums representing stages 2593 **/ 2594 void Pipeline::UseProgramStages(const Functions& gl, GLuint id, GLuint program_id, GLenum stages) 2595 { 2596 gl.useProgramStages(id, stages, program_id); 2597 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages"); 2598 } 2599 2600 /* Program constants */ 2601 const GLuint Program::m_invalid_id = 0; 2602 2603 /** Constructor. 2604 * 2605 * @param context CTS context. 2606 **/ 2607 Program::Program(deqp::Context& context) 2608 : m_id(m_invalid_id) 2609 , m_compute(context) 2610 , m_fragment(context) 2611 , m_geometry(context) 2612 , m_tess_ctrl(context) 2613 , m_tess_eval(context) 2614 , m_vertex(context) 2615 , m_context(context) 2616 { 2617 /* Nothing to be done here */ 2618 } 2619 2620 /** Destructor 2621 * 2622 **/ 2623 Program::~Program() 2624 { 2625 Release(); 2626 } 2627 2628 /** Initialize program instance 2629 * 2630 * @param compute_shader Compute shader source code 2631 * @param fragment_shader Fragment shader source code 2632 * @param geometry_shader Geometry shader source code 2633 * @param tessellation_control_shader Tessellation control shader source code 2634 * @param tessellation_evaluation_shader Tessellation evaluation shader source code 2635 * @param vertex_shader Vertex shader source code 2636 * @param captured_varyings Vector of variables to be captured with transfrom feedback 2637 * @param capture_interleaved Select mode of transform feedback (separate or interleaved) 2638 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false 2639 **/ 2640 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader, 2641 const std::string& geometry_shader, const std::string& tessellation_control_shader, 2642 const std::string& tessellation_evaluation_shader, const std::string& vertex_shader, 2643 const NameVector& captured_varyings, bool capture_interleaved, bool is_separable) 2644 { 2645 /* Delete previous program */ 2646 Release(); 2647 2648 /* GL entry points */ 2649 const Functions& gl = m_context.getRenderContext().getFunctions(); 2650 2651 /* Initialize shaders */ 2652 m_compute.Init(Shader::COMPUTE, compute_shader); 2653 m_fragment.Init(Shader::FRAGMENT, fragment_shader); 2654 m_geometry.Init(Shader::GEOMETRY, geometry_shader); 2655 m_tess_ctrl.Init(Shader::TESS_CTRL, tessellation_control_shader); 2656 m_tess_eval.Init(Shader::TESS_EVAL, tessellation_evaluation_shader); 2657 m_vertex.Init(Shader::VERTEX, vertex_shader); 2658 2659 /* Create program, set up transform feedback and attach shaders */ 2660 Create(gl, m_id); 2661 Capture(gl, m_id, captured_varyings, capture_interleaved); 2662 Attach(gl, m_id, m_compute.m_id); 2663 Attach(gl, m_id, m_fragment.m_id); 2664 Attach(gl, m_id, m_geometry.m_id); 2665 Attach(gl, m_id, m_tess_ctrl.m_id); 2666 Attach(gl, m_id, m_tess_eval.m_id); 2667 Attach(gl, m_id, m_vertex.m_id); 2668 2669 /* Set separable parameter */ 2670 if (true == is_separable) 2671 { 2672 gl.programParameteri(m_id, GL_PROGRAM_SEPARABLE, GL_TRUE); 2673 GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri"); 2674 } 2675 2676 try 2677 { 2678 /* Link program */ 2679 Link(gl, m_id); 2680 } 2681 catch (const LinkageException& exc) 2682 { 2683 throw BuildException(exc.what(), compute_shader, fragment_shader, geometry_shader, tessellation_control_shader, 2684 tessellation_evaluation_shader, vertex_shader); 2685 } 2686 } 2687 2688 /** Initialize program instance 2689 * 2690 * @param compute_shader Compute shader source code 2691 * @param fragment_shader Fragment shader source code 2692 * @param geometry_shader Geometry shader source code 2693 * @param tessellation_control_shader Tessellation control shader source code 2694 * @param tessellation_evaluation_shader Tessellation evaluation shader source code 2695 * @param vertex_shader Vertex shader source code 2696 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false 2697 **/ 2698 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader, 2699 const std::string& geometry_shader, const std::string& tessellation_control_shader, 2700 const std::string& tessellation_evaluation_shader, const std::string& vertex_shader, 2701 bool is_separable) 2702 { 2703 NameVector captured_varying; 2704 2705 Init(compute_shader, fragment_shader, geometry_shader, tessellation_control_shader, tessellation_evaluation_shader, 2706 vertex_shader, captured_varying, true, is_separable); 2707 } 2708 2709 /** Release program instance 2710 * 2711 **/ 2712 void Program::Release() 2713 { 2714 const Functions& gl = m_context.getRenderContext().getFunctions(); 2715 2716 if (m_invalid_id != m_id) 2717 { 2718 Use(gl, m_invalid_id); 2719 2720 gl.deleteProgram(m_id); 2721 m_id = m_invalid_id; 2722 } 2723 2724 m_compute.Release(); 2725 m_fragment.Release(); 2726 m_geometry.Release(); 2727 m_tess_ctrl.Release(); 2728 m_tess_eval.Release(); 2729 m_vertex.Release(); 2730 } 2731 2732 /** Get <pname> for a set of active uniforms 2733 * 2734 * @param count Number of indices 2735 * @param indices Indices of uniforms 2736 * @param pname Queired pname 2737 * @param params Array that will be filled with values of parameters 2738 **/ 2739 void Program::GetActiveUniformsiv(GLsizei count, const GLuint* indices, GLenum pname, GLint* params) const 2740 { 2741 const Functions& gl = m_context.getRenderContext().getFunctions(); 2742 2743 GetActiveUniformsiv(gl, m_id, count, indices, pname, params); 2744 } 2745 2746 /** Get location of attribute 2747 * 2748 * @param name Name of attribute 2749 * 2750 * @return Result of query 2751 **/ 2752 glw::GLint Program::GetAttribLocation(const std::string& name) const 2753 { 2754 const Functions& gl = m_context.getRenderContext().getFunctions(); 2755 2756 return GetAttribLocation(gl, m_id, name); 2757 } 2758 2759 /** Query resource 2760 * 2761 * @param interface Interface to be queried 2762 * @param index Index of resource 2763 * @param property Property to be queried 2764 * @param buf_size Size of <params> buffer 2765 * @param params Results of query 2766 **/ 2767 void Program::GetResource(GLenum interface, GLuint index, GLenum property, GLsizei buf_size, GLint* params) const 2768 { 2769 const Functions& gl = m_context.getRenderContext().getFunctions(); 2770 2771 GetResource(gl, m_id, interface, index, property, buf_size, params); 2772 } 2773 2774 /** Query for index of resource 2775 * 2776 * @param name Name of resource 2777 * @param interface Interface to be queried 2778 * 2779 * @return Result of query 2780 **/ 2781 glw::GLuint Program::GetResourceIndex(const std::string& name, GLenum interface) const 2782 { 2783 const Functions& gl = m_context.getRenderContext().getFunctions(); 2784 2785 return GetResourceIndex(gl, m_id, name, interface); 2786 } 2787 2788 /** Get indices for a set of uniforms 2789 * 2790 * @param count Count number of uniforms 2791 * @param names Names of uniforms 2792 * @param indices Buffer that will be filled with indices 2793 **/ 2794 void Program::GetUniformIndices(GLsizei count, const GLchar** names, GLuint* indices) const 2795 { 2796 const Functions& gl = m_context.getRenderContext().getFunctions(); 2797 2798 GetUniformIndices(gl, m_id, count, names, indices); 2799 } 2800 2801 /** Get uniform location 2802 * 2803 * @param name Name of uniform 2804 * 2805 * @return Results of query 2806 **/ 2807 glw::GLint Program::GetUniformLocation(const std::string& name) const 2808 { 2809 const Functions& gl = m_context.getRenderContext().getFunctions(); 2810 2811 return GetUniformLocation(gl, m_id, name); 2812 } 2813 2814 /** Set program as active 2815 * 2816 **/ 2817 void Program::Use() const 2818 { 2819 const Functions& gl = m_context.getRenderContext().getFunctions(); 2820 2821 Use(gl, m_id); 2822 } 2823 2824 /** Attach shader to program 2825 * 2826 * @param gl GL functions 2827 * @param program_id Id of program 2828 * @param shader_id Id of shader 2829 **/ 2830 void Program::Attach(const Functions& gl, GLuint program_id, GLuint shader_id) 2831 { 2832 /* Sanity checks */ 2833 if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id)) 2834 { 2835 return; 2836 } 2837 2838 gl.attachShader(program_id, shader_id); 2839 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 2840 } 2841 2842 /** Set up captured varyings 2843 * 2844 * @param gl GL functions 2845 * @param id Id of program 2846 * @param captured_varyings Vector of varyings 2847 * @param capture_interleaved Selects if interleaved or separate mode should be used 2848 **/ 2849 void Program::Capture(const Functions& gl, GLuint id, const NameVector& captured_varyings, bool capture_interleaved) 2850 { 2851 const size_t n_varyings = captured_varyings.size(); 2852 2853 if (0 == n_varyings) 2854 { 2855 /* empty list, skip */ 2856 return; 2857 } 2858 2859 std::vector<const GLchar*> varying_names; 2860 varying_names.resize(n_varyings); 2861 2862 for (size_t i = 0; i < n_varyings; ++i) 2863 { 2864 varying_names[i] = captured_varyings[i].c_str(); 2865 } 2866 2867 GLenum mode = 0; 2868 if (true == capture_interleaved) 2869 { 2870 mode = GL_INTERLEAVED_ATTRIBS; 2871 } 2872 else 2873 { 2874 mode = GL_SEPARATE_ATTRIBS; 2875 } 2876 2877 gl.transformFeedbackVaryings(id, static_cast<GLsizei>(n_varyings), &varying_names[0], mode); 2878 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings"); 2879 } 2880 2881 /** Create program instance 2882 * 2883 * @param gl GL functions 2884 * @param out_id Id of program 2885 **/ 2886 void Program::Create(const Functions& gl, GLuint& out_id) 2887 { 2888 const GLuint id = gl.createProgram(); 2889 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram"); 2890 2891 if (m_invalid_id == id) 2892 { 2893 TCU_FAIL("Failed to create program"); 2894 } 2895 2896 out_id = id; 2897 } 2898 2899 /** Get <pname> for a set of active uniforms 2900 * 2901 * @param gl Functions 2902 * @param program_id Id of program 2903 * @param count Number of indices 2904 * @param indices Indices of uniforms 2905 * @param pname Queired pname 2906 * @param params Array that will be filled with values of parameters 2907 **/ 2908 void Program::GetActiveUniformsiv(const Functions& gl, GLuint program_id, GLsizei count, const GLuint* indices, 2909 GLenum pname, GLint* params) 2910 { 2911 gl.getActiveUniformsiv(program_id, count, indices, pname, params); 2912 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv"); 2913 } 2914 2915 /** Get indices for a set of uniforms 2916 * 2917 * @param gl Functions 2918 * @param program_id Id of program 2919 * @param count Count number of uniforms 2920 * @param names Names of uniforms 2921 * @param indices Buffer that will be filled with indices 2922 **/ 2923 void Program::GetUniformIndices(const Functions& gl, GLuint program_id, GLsizei count, const GLchar** names, 2924 GLuint* indices) 2925 { 2926 gl.getUniformIndices(program_id, count, names, indices); 2927 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices"); 2928 } 2929 2930 /** Link program 2931 * 2932 * @param gl GL functions 2933 * @param id Id of program 2934 **/ 2935 void Program::Link(const Functions& gl, GLuint id) 2936 { 2937 GLint status = GL_FALSE; 2938 2939 gl.linkProgram(id); 2940 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram"); 2941 2942 /* Get link status */ 2943 gl.getProgramiv(id, GL_LINK_STATUS, &status); 2944 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 2945 2946 /* Log link error */ 2947 if (GL_TRUE != status) 2948 { 2949 glw::GLint length = 0; 2950 std::string message; 2951 2952 /* Get error log length */ 2953 gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length); 2954 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 2955 2956 message.resize(length, 0); 2957 2958 /* Get error log */ 2959 gl.getProgramInfoLog(id, length, 0, &message[0]); 2960 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog"); 2961 2962 throw LinkageException(message.c_str()); 2963 } 2964 } 2965 2966 /** Set generic uniform 2967 * 2968 * @param gl Functions 2969 * @param type Type of uniform 2970 * @param count Length of array 2971 * @param location Location of uniform 2972 * @param data Data that will be used 2973 **/ 2974 void Program::Uniform(const Functions& gl, const Type& type, GLsizei count, GLint location, const GLvoid* data) 2975 { 2976 if (-1 == location) 2977 { 2978 TCU_FAIL("Uniform is inactive"); 2979 } 2980 2981 switch (type.m_basic_type) 2982 { 2983 case Type::Double: 2984 if (1 == type.m_n_columns) 2985 { 2986 getUniformNdv(gl, type.m_n_rows)(location, count, (const GLdouble*)data); 2987 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNdv"); 2988 } 2989 else 2990 { 2991 getUniformMatrixNdv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLdouble*)data); 2992 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNdv"); 2993 } 2994 break; 2995 case Type::Float: 2996 if (1 == type.m_n_columns) 2997 { 2998 getUniformNfv(gl, type.m_n_rows)(location, count, (const GLfloat*)data); 2999 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNfv"); 3000 } 3001 else 3002 { 3003 getUniformMatrixNfv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLfloat*)data); 3004 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNfv"); 3005 } 3006 break; 3007 case Type::Int: 3008 getUniformNiv(gl, type.m_n_rows)(location, count, (const GLint*)data); 3009 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNiv"); 3010 break; 3011 case Type::Uint: 3012 getUniformNuiv(gl, type.m_n_rows)(location, count, (const GLuint*)data); 3013 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNuiv"); 3014 break; 3015 default: 3016 TCU_FAIL("Invalid enum"); 3017 } 3018 } 3019 3020 /** Use program 3021 * 3022 * @param gl GL functions 3023 * @param id Id of program 3024 **/ 3025 void Program::Use(const Functions& gl, GLuint id) 3026 { 3027 gl.useProgram(id); 3028 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram"); 3029 } 3030 3031 /** Get location of attribute 3032 * 3033 * @param gl GL functions 3034 * @param id Id of program 3035 * @param name Name of attribute 3036 * 3037 * @return Location of attribute 3038 **/ 3039 GLint Program::GetAttribLocation(const Functions& gl, GLuint id, const std::string& name) 3040 { 3041 GLint location = gl.getAttribLocation(id, name.c_str()); 3042 GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation"); 3043 3044 return location; 3045 } 3046 3047 /** Query resource 3048 * 3049 * @param gl GL functions 3050 * @param id Id of program 3051 * @param interface Interface to be queried 3052 * @param index Index of resource 3053 * @param property Property to be queried 3054 * @param buf_size Size of <params> buffer 3055 * @param params Results of query 3056 **/ 3057 void Program::GetResource(const Functions& gl, GLuint id, GLenum interface, GLuint index, GLenum property, 3058 GLsizei buf_size, GLint* params) 3059 { 3060 gl.getProgramResourceiv(id, interface, index, 1 /* propCount */, &property, buf_size /* bufSize */, 0 /* length */, 3061 params); 3062 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv"); 3063 } 3064 3065 /** Get index of resource 3066 * 3067 * @param gl GL functions 3068 * @param id Id of program 3069 * @param name Name of resource 3070 * @param interface Program interface to queried 3071 * 3072 * @return Location of attribute 3073 **/ 3074 GLuint Program::GetResourceIndex(const Functions& gl, GLuint id, const std::string& name, GLenum interface) 3075 { 3076 GLuint index = gl.getProgramResourceIndex(id, interface, name.c_str()); 3077 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex"); 3078 3079 return index; 3080 } 3081 3082 /** Get location of attribute 3083 * 3084 * @param gl GL functions 3085 * @param id Id of program 3086 * @param name Name of attribute 3087 * 3088 * @return Location of uniform 3089 **/ 3090 GLint Program::GetUniformLocation(const Functions& gl, GLuint id, const std::string& name) 3091 { 3092 GLint location = gl.getUniformLocation(id, name.c_str()); 3093 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation"); 3094 3095 return location; 3096 } 3097 3098 /** Constructor 3099 * 3100 * @param error_message Error message 3101 * @param compute_shader Source code for compute stage 3102 * @param fragment_shader Source code for fragment stage 3103 * @param geometry_shader Source code for geometry stage 3104 * @param tess_ctrl_shader Source code for tessellation control stage 3105 * @param tess_eval_shader Source code for tessellation evaluation stage 3106 * @param vertex_shader Source code for vertex stage 3107 **/ 3108 Program::BuildException::BuildException(const glw::GLchar* error_message, const std::string compute_shader, 3109 const std::string fragment_shader, const std::string geometry_shader, 3110 const std::string tess_ctrl_shader, const std::string tess_eval_shader, 3111 const std::string vertex_shader) 3112 : m_error_message(error_message) 3113 , m_compute_shader(compute_shader) 3114 , m_fragment_shader(fragment_shader) 3115 , m_geometry_shader(geometry_shader) 3116 , m_tess_ctrl_shader(tess_ctrl_shader) 3117 , m_tess_eval_shader(tess_eval_shader) 3118 , m_vertex_shader(vertex_shader) 3119 { 3120 } 3121 3122 /** Overwrites std::exception::what method 3123 * 3124 * @return Message compossed from error message and shader sources 3125 **/ 3126 const char* Program::BuildException::what() const throw() 3127 { 3128 return "Failed to link program"; 3129 } 3130 3131 /** Logs error message and shader sources **/ 3132 void Program::BuildException::log(deqp::Context& context) const 3133 { 3134 context.getTestContext().getLog() << tcu::TestLog::Message << "Link failure: " << m_error_message 3135 << tcu::TestLog::EndMessage; 3136 3137 Shader::LogSource(context, m_vertex_shader, Shader::VERTEX); 3138 Shader::LogSource(context, m_tess_ctrl_shader, Shader::TESS_CTRL); 3139 Shader::LogSource(context, m_tess_eval_shader, Shader::TESS_EVAL); 3140 Shader::LogSource(context, m_geometry_shader, Shader::GEOMETRY); 3141 Shader::LogSource(context, m_fragment_shader, Shader::FRAGMENT); 3142 Shader::LogSource(context, m_compute_shader, Shader::COMPUTE); 3143 } 3144 3145 /** Constructor 3146 * 3147 * @param message Linking error message 3148 **/ 3149 Program::LinkageException::LinkageException(const glw::GLchar* message) : m_error_message(message) 3150 { 3151 /* Nothing to be done */ 3152 } 3153 3154 /** Returns error messages 3155 * 3156 * @return Linking error message 3157 **/ 3158 const char* Program::LinkageException::what() const throw() 3159 { 3160 return m_error_message.c_str(); 3161 } 3162 3163 /* Texture constants */ 3164 const GLuint Texture::m_invalid_id = -1; 3165 3166 /** Constructor. 3167 * 3168 * @param context CTS context. 3169 **/ 3170 Texture::Texture(deqp::Context& context) : m_id(m_invalid_id), m_context(context), m_type(TEX_2D) 3171 { 3172 /* Nothing to done here */ 3173 } 3174 3175 /** Destructor 3176 * 3177 **/ 3178 Texture::~Texture() 3179 { 3180 Release(); 3181 } 3182 3183 /** Initialize texture instance 3184 * 3185 * @param tex_type Type of texture 3186 * @param width Width of texture 3187 * @param height Height of texture 3188 * @param depth Depth of texture 3189 * @param internal_format Internal format of texture 3190 * @param format Format of texture data 3191 * @param type Type of texture data 3192 * @param data Texture data 3193 **/ 3194 void Texture::Init(TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum internal_format, GLenum format, 3195 GLenum type, GLvoid* data) 3196 { 3197 const Functions& gl = m_context.getRenderContext().getFunctions(); 3198 3199 /* Delete previous texture */ 3200 Release(); 3201 3202 m_type = tex_type; 3203 3204 /* Generate, bind, allocate storage and upload data */ 3205 Generate(gl, m_id); 3206 Bind(gl, m_id, tex_type); 3207 Storage(gl, tex_type, width, height, depth, internal_format); 3208 Update(gl, tex_type, width, height, depth, format, type, data); 3209 } 3210 3211 /** Initialize buffer texture 3212 * 3213 * @param internal_format Internal format of texture 3214 * @param buffer_id Id of buffer that will be used as data source 3215 **/ 3216 void Texture::Init(GLenum internal_format, GLuint buffer_id) 3217 { 3218 const Functions& gl = m_context.getRenderContext().getFunctions(); 3219 3220 /* Delete previous texture */ 3221 Release(); 3222 3223 m_type = TEX_BUFFER; 3224 3225 /* Generate, bind and attach buffer */ 3226 Generate(gl, m_id); 3227 Bind(gl, m_id, TEX_BUFFER); 3228 TexBuffer(gl, buffer_id, internal_format); 3229 } 3230 3231 /** Release texture instance 3232 * 3233 **/ 3234 void Texture::Release() 3235 { 3236 if (m_invalid_id != m_id) 3237 { 3238 const Functions& gl = m_context.getRenderContext().getFunctions(); 3239 3240 gl.deleteTextures(1, &m_id); 3241 m_id = m_invalid_id; 3242 } 3243 } 3244 3245 /** Bind texture to its target 3246 * 3247 **/ 3248 void Texture::Bind() const 3249 { 3250 const Functions& gl = m_context.getRenderContext().getFunctions(); 3251 3252 Bind(gl, m_id, m_type); 3253 } 3254 3255 /** Get texture data 3256 * 3257 * @param format Format of data 3258 * @param type Type of data 3259 * @param out_data Buffer for data 3260 **/ 3261 void Texture::Get(GLenum format, GLenum type, GLvoid* out_data) const 3262 { 3263 const Functions& gl = m_context.getRenderContext().getFunctions(); 3264 3265 Bind(gl, m_id, m_type); 3266 Get(gl, m_type, format, type, out_data); 3267 } 3268 3269 /** Bind texture to target 3270 * 3271 * @param gl GL functions 3272 * @param id Id of texture 3273 * @param tex_type Type of texture 3274 **/ 3275 void Texture::Bind(const Functions& gl, GLuint id, TYPES tex_type) 3276 { 3277 GLenum target = GetTargetGLenum(tex_type); 3278 3279 gl.bindTexture(target, id); 3280 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 3281 } 3282 3283 /** Generate texture instance 3284 * 3285 * @param gl GL functions 3286 * @param out_id Id of texture 3287 **/ 3288 void Texture::Generate(const Functions& gl, GLuint& out_id) 3289 { 3290 GLuint id = m_invalid_id; 3291 3292 gl.genTextures(1, &id); 3293 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures"); 3294 3295 if (m_invalid_id == id) 3296 { 3297 TCU_FAIL("Invalid id"); 3298 } 3299 3300 out_id = id; 3301 } 3302 3303 /** Get texture data 3304 * 3305 * @param gl GL functions 3306 * @param format Format of data 3307 * @param type Type of data 3308 * @param out_data Buffer for data 3309 **/ 3310 void Texture::Get(const Functions& gl, TYPES tex_type, GLenum format, GLenum type, GLvoid* out_data) 3311 { 3312 GLenum target = GetTargetGLenum(tex_type); 3313 3314 if (TEX_CUBE != tex_type) 3315 { 3316 gl.getTexImage(target, 0 /* level */, format, type, out_data); 3317 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage"); 3318 } 3319 else 3320 { 3321 GLint width; 3322 GLint height; 3323 3324 if ((GL_RGBA != format) && (GL_UNSIGNED_BYTE != type)) 3325 { 3326 TCU_FAIL("Not implemented"); 3327 } 3328 3329 GLuint texel_size = 4; 3330 3331 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_WIDTH, &width); 3332 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv"); 3333 3334 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_HEIGHT, &height); 3335 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv"); 3336 3337 const GLuint image_size = width * height * texel_size; 3338 3339 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, format, type, 3340 (GLvoid*)((GLchar*)out_data + (image_size * 0))); 3341 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0 /* level */, format, type, 3342 (GLvoid*)((GLchar*)out_data + (image_size * 1))); 3343 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0 /* level */, format, type, 3344 (GLvoid*)((GLchar*)out_data + (image_size * 2))); 3345 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0 /* level */, format, type, 3346 (GLvoid*)((GLchar*)out_data + (image_size * 3))); 3347 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0 /* level */, format, type, 3348 (GLvoid*)((GLchar*)out_data + (image_size * 4))); 3349 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0 /* level */, format, type, 3350 (GLvoid*)((GLchar*)out_data + (image_size * 5))); 3351 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage"); 3352 } 3353 } 3354 3355 /** Allocate storage for texture 3356 * 3357 * @param gl GL functions 3358 * @param tex_type Type of texture 3359 * @param width Width of texture 3360 * @param height Height of texture 3361 * @param depth Depth of texture 3362 * @param internal_format Internal format of texture 3363 **/ 3364 void Texture::Storage(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, 3365 GLenum internal_format) 3366 { 3367 static const GLuint levels = 1; 3368 3369 GLenum target = GetTargetGLenum(tex_type); 3370 3371 switch (tex_type) 3372 { 3373 case TEX_1D: 3374 gl.texStorage1D(target, levels, internal_format, width); 3375 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D"); 3376 break; 3377 case TEX_2D: 3378 case TEX_1D_ARRAY: 3379 case TEX_2D_RECT: 3380 case TEX_CUBE: 3381 gl.texStorage2D(target, levels, internal_format, width, height); 3382 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D"); 3383 break; 3384 case TEX_3D: 3385 case TEX_2D_ARRAY: 3386 gl.texStorage3D(target, levels, internal_format, width, height, depth); 3387 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D"); 3388 break; 3389 default: 3390 TCU_FAIL("Invliad enum"); 3391 break; 3392 } 3393 } 3394 3395 /** Attach buffer as source of texture buffer data 3396 * 3397 * @param gl GL functions 3398 * @param internal_format Internal format of texture 3399 * @param buffer_id Id of buffer that will be used as data source 3400 **/ 3401 void Texture::TexBuffer(const Functions& gl, GLenum internal_format, GLuint& buffer_id) 3402 { 3403 gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id); 3404 GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer"); 3405 } 3406 3407 /** Update contents of texture 3408 * 3409 * @param gl GL functions 3410 * @param tex_type Type of texture 3411 * @param width Width of texture 3412 * @param height Height of texture 3413 * @param format Format of data 3414 * @param type Type of data 3415 * @param data Buffer with image data 3416 **/ 3417 void Texture::Update(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum format, 3418 GLenum type, GLvoid* data) 3419 { 3420 static const GLuint level = 0; 3421 3422 GLenum target = GetTargetGLenum(tex_type); 3423 3424 switch (tex_type) 3425 { 3426 case TEX_1D: 3427 gl.texSubImage1D(target, level, 0 /* x */, width, format, type, data); 3428 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D"); 3429 break; 3430 case TEX_2D: 3431 case TEX_1D_ARRAY: 3432 case TEX_2D_RECT: 3433 gl.texSubImage2D(target, level, 0 /* x */, 0 /* y */, width, height, format, type, data); 3434 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D"); 3435 break; 3436 case TEX_CUBE: 3437 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type, 3438 data); 3439 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type, 3440 data); 3441 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type, 3442 data); 3443 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type, 3444 data); 3445 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type, 3446 data); 3447 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type, 3448 data); 3449 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D"); 3450 break; 3451 case TEX_3D: 3452 case TEX_2D_ARRAY: 3453 gl.texSubImage3D(target, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format, type, data); 3454 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D"); 3455 break; 3456 default: 3457 TCU_FAIL("Invliad enum"); 3458 break; 3459 } 3460 } 3461 3462 /** Get target for given texture type 3463 * 3464 * @param type Type of texture 3465 * 3466 * @return Target 3467 **/ 3468 GLenum Texture::GetTargetGLenum(TYPES type) 3469 { 3470 GLenum result = 0; 3471 3472 switch (type) 3473 { 3474 case TEX_BUFFER: 3475 result = GL_TEXTURE_BUFFER; 3476 break; 3477 case TEX_2D: 3478 result = GL_TEXTURE_2D; 3479 break; 3480 case TEX_2D_RECT: 3481 result = GL_TEXTURE_RECTANGLE; 3482 break; 3483 case TEX_2D_ARRAY: 3484 result = GL_TEXTURE_2D_ARRAY; 3485 break; 3486 case TEX_3D: 3487 result = GL_TEXTURE_3D; 3488 break; 3489 case TEX_CUBE: 3490 result = GL_TEXTURE_CUBE_MAP; 3491 break; 3492 case TEX_1D: 3493 result = GL_TEXTURE_1D; 3494 break; 3495 case TEX_1D_ARRAY: 3496 result = GL_TEXTURE_1D_ARRAY; 3497 break; 3498 } 3499 3500 return result; 3501 } 3502 3503 /* VertexArray constants */ 3504 const GLuint VertexArray::m_invalid_id = -1; 3505 3506 /** Constructor. 3507 * 3508 * @param context CTS context. 3509 **/ 3510 VertexArray::VertexArray(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 3511 { 3512 } 3513 3514 /** Destructor 3515 * 3516 **/ 3517 VertexArray::~VertexArray() 3518 { 3519 Release(); 3520 } 3521 3522 /** Initialize vertex array instance 3523 * 3524 **/ 3525 void VertexArray::Init() 3526 { 3527 /* Delete previous instance */ 3528 Release(); 3529 3530 const Functions& gl = m_context.getRenderContext().getFunctions(); 3531 3532 Generate(gl, m_id); 3533 } 3534 3535 /** Release vertex array object instance 3536 * 3537 **/ 3538 void VertexArray::Release() 3539 { 3540 if (m_invalid_id != m_id) 3541 { 3542 const Functions& gl = m_context.getRenderContext().getFunctions(); 3543 3544 gl.deleteVertexArrays(1, &m_id); 3545 3546 m_id = m_invalid_id; 3547 } 3548 } 3549 3550 /** Set attribute in VAO 3551 * 3552 * @param index Index of attribute 3553 * @param type Type of attribute 3554 * @param n_array_elements Arary length 3555 * @param normalized Selectis if values should be normalized 3556 * @param stride Stride 3557 * @param pointer Pointer to data, or offset in buffer 3558 **/ 3559 void VertexArray::Attribute(GLuint index, const Type& type, GLuint n_array_elements, GLboolean normalized, 3560 GLsizei stride, const GLvoid* pointer) 3561 { 3562 const Functions& gl = m_context.getRenderContext().getFunctions(); 3563 3564 AttribPointer(gl, index, type, n_array_elements, normalized, stride, pointer); 3565 Enable(gl, index, type, n_array_elements); 3566 } 3567 3568 /** Binds Vertex array object 3569 * 3570 **/ 3571 void VertexArray::Bind() 3572 { 3573 const Functions& gl = m_context.getRenderContext().getFunctions(); 3574 3575 Bind(gl, m_id); 3576 } 3577 3578 /** Set attribute in VAO 3579 * 3580 * @param gl Functions 3581 * @param index Index of attribute 3582 * @param type Type of attribute 3583 * @param n_array_elements Arary length 3584 * @param normalized Selectis if values should be normalized 3585 * @param stride Stride 3586 * @param pointer Pointer to data, or offset in buffer 3587 **/ 3588 void VertexArray::AttribPointer(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements, 3589 GLboolean normalized, GLsizei stride, const GLvoid* pointer) 3590 { 3591 const GLuint basic_type_size = Type::GetTypeSize(type.m_basic_type); 3592 const GLint size = (GLint)type.m_n_rows; 3593 const GLuint column_size = (GLuint)size * basic_type_size; 3594 const GLenum gl_type = Type::GetTypeGLenum(type.m_basic_type); 3595 3596 GLuint offset = 0; 3597 3598 /* If attribute is not an array */ 3599 if (0 == n_array_elements) 3600 { 3601 n_array_elements = 1; 3602 } 3603 3604 /* For each element in array */ 3605 for (GLuint element = 0; element < n_array_elements; ++element) 3606 { 3607 /* For each column in matrix */ 3608 for (GLuint column = 1; column <= type.m_n_columns; ++column) 3609 { 3610 /* Calculate offset */ 3611 const GLvoid* ptr = (GLubyte*)pointer + offset; 3612 3613 /* Set up attribute */ 3614 switch (type.m_basic_type) 3615 { 3616 case Type::Float: 3617 gl.vertexAttribPointer(index, size, gl_type, normalized, stride, ptr); 3618 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribPointer"); 3619 break; 3620 case Type::Int: 3621 case Type::Uint: 3622 gl.vertexAttribIPointer(index, size, gl_type, stride, ptr); 3623 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribIPointer"); 3624 break; 3625 case Type::Double: 3626 gl.vertexAttribLPointer(index, size, gl_type, stride, ptr); 3627 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribLPointer"); 3628 break; 3629 default: 3630 TCU_FAIL("Invalid enum"); 3631 } 3632 3633 /* Next location */ 3634 offset += column_size; 3635 index += 1; 3636 } 3637 } 3638 } 3639 3640 /** Binds Vertex array object 3641 * 3642 * @param gl GL functions 3643 * @param id ID of vertex array object 3644 **/ 3645 void VertexArray::Bind(const glw::Functions& gl, glw::GLuint id) 3646 { 3647 gl.bindVertexArray(id); 3648 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray"); 3649 } 3650 3651 /** Disable attribute in VAO 3652 * 3653 * @param gl Functions 3654 * @param index Index of attribute 3655 * @param type Type of attribute 3656 * @param n_array_elements Arary length 3657 **/ 3658 void VertexArray::Disable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements) 3659 { 3660 /* If attribute is not an array */ 3661 if (0 == n_array_elements) 3662 { 3663 n_array_elements = 1; 3664 } 3665 3666 /* For each element in array */ 3667 for (GLuint element = 0; element < n_array_elements; ++element) 3668 { 3669 /* For each column in matrix */ 3670 for (GLuint column = 1; column <= type.m_n_columns; ++column) 3671 { 3672 /* Enable attribute array */ 3673 gl.disableVertexAttribArray(index); 3674 GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray"); 3675 3676 /* Next location */ 3677 index += 1; 3678 } 3679 } 3680 } 3681 3682 /** Set divisor for attribute 3683 * 3684 * @param gl Functions 3685 * @param index Index of attribute 3686 * @param divisor New divisor value 3687 **/ 3688 void VertexArray::Divisor(const Functions& gl, GLuint index, GLuint divisor) 3689 { 3690 gl.vertexAttribDivisor(index, divisor); 3691 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribDivisor"); 3692 } 3693 3694 /** Enables attribute in VAO 3695 * 3696 * @param gl Functions 3697 * @param index Index of attribute 3698 * @param type Type of attribute 3699 * @param n_array_elements Arary length 3700 **/ 3701 void VertexArray::Enable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements) 3702 { 3703 /* If attribute is not an array */ 3704 if (0 == n_array_elements) 3705 { 3706 n_array_elements = 1; 3707 } 3708 3709 /* For each element in array */ 3710 for (GLuint element = 0; element < n_array_elements; ++element) 3711 { 3712 /* For each column in matrix */ 3713 for (GLuint column = 1; column <= type.m_n_columns; ++column) 3714 { 3715 /* Enable attribute array */ 3716 gl.enableVertexAttribArray(index); 3717 GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray"); 3718 3719 /* Next location */ 3720 index += 1; 3721 } 3722 } 3723 } 3724 3725 /** Generates Vertex array object 3726 * 3727 * @param gl GL functions 3728 * @param out_id ID of vertex array object 3729 **/ 3730 void VertexArray::Generate(const glw::Functions& gl, glw::GLuint& out_id) 3731 { 3732 GLuint id = m_invalid_id; 3733 3734 gl.genVertexArrays(1, &id); 3735 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays"); 3736 3737 if (m_invalid_id == id) 3738 { 3739 TCU_FAIL("Invalid id"); 3740 } 3741 3742 out_id = id; 3743 } 3744 3745 /* Constatns used by Variable */ 3746 const GLint Variable::m_automatic_location = -1; 3747 3748 /** Copy constructor 3749 * 3750 **/ 3751 Variable::Variable(const Variable& var) 3752 : m_data(var.m_data) 3753 , m_data_size(var.m_data_size) 3754 , m_descriptor(var.m_descriptor.m_name.c_str(), var.m_descriptor.m_qualifiers.c_str(), 3755 var.m_descriptor.m_expected_component, var.m_descriptor.m_expected_location, 3756 var.m_descriptor.m_builtin, var.m_descriptor.m_normalized, var.m_descriptor.m_n_array_elements, 3757 var.m_descriptor.m_expected_stride_of_element, var.m_descriptor.m_offset) 3758 , m_storage(var.m_storage) 3759 { 3760 m_descriptor.m_type = var.m_descriptor.m_type; 3761 3762 if (BUILTIN != var.m_descriptor.m_type) 3763 { 3764 m_descriptor.m_interface = var.m_descriptor.m_interface; 3765 } 3766 } 3767 3768 /** Get code that defines variable 3769 * 3770 * @param flavour Provides info if variable is array or not 3771 * 3772 * @return String with code 3773 **/ 3774 std::string Variable::GetDefinition(FLAVOUR flavour) const 3775 { 3776 return m_descriptor.GetDefinition(flavour, m_storage); 3777 } 3778 3779 /** Calcualtes stride of variable 3780 * 3781 * @return Calculated value 3782 **/ 3783 GLuint Variable::GetStride() const 3784 { 3785 GLint variable_stride = 0; 3786 3787 if (0 == m_descriptor.m_n_array_elements) 3788 { 3789 variable_stride = m_descriptor.m_expected_stride_of_element; 3790 } 3791 else 3792 { 3793 variable_stride = m_descriptor.m_expected_stride_of_element * m_descriptor.m_n_array_elements; 3794 } 3795 3796 return variable_stride; 3797 } 3798 3799 /** Check if variable is block 3800 * 3801 * @return true if variable type is block, false otherwise 3802 **/ 3803 bool Variable::IsBlock() const 3804 { 3805 if (BUILTIN == m_descriptor.m_type) 3806 { 3807 return false; 3808 } 3809 3810 const Interface* interface = m_descriptor.m_interface; 3811 if (0 == interface) 3812 { 3813 TCU_FAIL("Nullptr"); 3814 } 3815 3816 return (Interface::BLOCK == interface->m_type); 3817 } 3818 3819 /** Check if variable is struct 3820 * 3821 * @return true if variable type is struct, false otherwise 3822 **/ 3823 bool Variable::IsStruct() const 3824 { 3825 if (BUILTIN == m_descriptor.m_type) 3826 { 3827 return false; 3828 } 3829 3830 const Interface* interface = m_descriptor.m_interface; 3831 if (0 == interface) 3832 { 3833 TCU_FAIL("Nullptr"); 3834 } 3835 3836 return (Interface::STRUCT == interface->m_type); 3837 } 3838 /** Get code that reference variable 3839 * 3840 * @param parent_name Name of parent 3841 * @param variable Descriptor of variable 3842 * @param flavour Provides info about how variable should be referenced 3843 * @param array_index Index of array, ignored when variable is not array 3844 * 3845 * @return String with code 3846 **/ 3847 std::string Variable::GetReference(const std::string& parent_name, const Descriptor& variable, FLAVOUR flavour, 3848 GLuint array_index) 3849 { 3850 std::string name; 3851 3852 /* Prepare name */ 3853 if (false == parent_name.empty()) 3854 { 3855 name = parent_name; 3856 name.append("."); 3857 name.append(variable.m_name); 3858 } 3859 else 3860 { 3861 name = variable.m_name; 3862 } 3863 3864 /* */ 3865 switch (flavour) 3866 { 3867 case Utils::Variable::BASIC: 3868 break; 3869 3870 case Utils::Variable::ARRAY: 3871 name.append("[0]"); 3872 break; 3873 3874 case Utils::Variable::INDEXED_BY_INVOCATION_ID: 3875 name.append("[gl_InvocationID]"); 3876 break; 3877 } 3878 3879 /* Assumption that both variables have same lengths */ 3880 if (0 != variable.m_n_array_elements) 3881 { 3882 GLchar buffer[16]; 3883 sprintf(buffer, "%d", array_index); 3884 name.append("["); 3885 name.append(buffer); 3886 name.append("]"); 3887 } 3888 3889 return name; 3890 } 3891 3892 /** Get "flavour" of varying 3893 * 3894 * @param stage Stage of shader 3895 * @param direction Selects if varying is in or out 3896 * 3897 * @return Flavour 3898 **/ 3899 Variable::FLAVOUR Variable::GetFlavour(Shader::STAGES stage, VARYING_DIRECTION direction) 3900 { 3901 FLAVOUR result = BASIC; 3902 3903 switch (stage) 3904 { 3905 case Shader::GEOMETRY: 3906 case Shader::TESS_EVAL: 3907 if (INPUT == direction) 3908 { 3909 result = ARRAY; 3910 } 3911 break; 3912 case Shader::TESS_CTRL: 3913 result = INDEXED_BY_INVOCATION_ID; 3914 break; 3915 default: 3916 break; 3917 } 3918 3919 return result; 3920 } 3921 3922 /** Constructor, for built-in types 3923 * 3924 * @param name Name 3925 * @param qualifiers Qualifiers 3926 * @param expected_component Expected component of variable 3927 * @param expected_location Expected location 3928 * @param type Type 3929 * @param normalized Selects if data should be normalized 3930 * @param n_array_elements Length of array 3931 * @param expected_stride_of_element Expected stride of element 3932 * @param offset Offset 3933 **/ 3934 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_component, 3935 GLint expected_location, const Type& type, GLboolean normalized, 3936 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset) 3937 : m_expected_component(expected_component) 3938 , m_expected_location(expected_location) 3939 , m_expected_stride_of_element(expected_stride_of_element) 3940 , m_n_array_elements(n_array_elements) 3941 , m_name(name) 3942 , m_normalized(normalized) 3943 , m_offset(offset) 3944 , m_qualifiers(qualifiers) 3945 , m_type(BUILTIN) 3946 , m_builtin(type) 3947 { 3948 } 3949 3950 /** Constructor, for interface types 3951 * 3952 * @param name Name 3953 * @param qualifiers Qualifiers 3954 * @param expected_component Expected component of variable 3955 * @param expected_location Expected location 3956 * @param interface Interface of variable 3957 * @param n_array_elements Length of array 3958 * @param expected_stride_of_element Expected stride of element 3959 * @param offset Offset 3960 **/ 3961 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_componenet, 3962 GLint expected_location, Interface* interface, GLuint n_array_elements, 3963 GLint expected_stride_of_element, GLuint offset) 3964 : m_expected_component(expected_componenet) 3965 , m_expected_location(expected_location) 3966 , m_expected_stride_of_element(expected_stride_of_element) 3967 , m_n_array_elements(n_array_elements) 3968 , m_name(name) 3969 , m_normalized(GL_FALSE) 3970 , m_offset(offset) 3971 , m_qualifiers(qualifiers) 3972 , m_type(INTERFACE) 3973 , m_interface(interface) 3974 { 3975 } 3976 3977 /** Get definition of variable 3978 * 3979 * @param flavour Flavour of variable 3980 * @param storage Storage used for variable 3981 * 3982 * @return code with defintion 3983 **/ 3984 std::string Variable::Descriptor::GetDefinition(FLAVOUR flavour, STORAGE storage) const 3985 { 3986 static const GLchar* basic_template = "QUALIFIERS STORAGETYPE NAMEARRAY;"; 3987 static const GLchar* array_template = "QUALIFIERS STORAGETYPE NAME[]ARRAY;"; 3988 const GLchar* storage_str = 0; 3989 3990 std::string definition; 3991 size_t position = 0; 3992 3993 /* Select definition template */ 3994 switch (flavour) 3995 { 3996 case BASIC: 3997 definition = basic_template; 3998 break; 3999 case ARRAY: 4000 case INDEXED_BY_INVOCATION_ID: 4001 definition = array_template; 4002 break; 4003 default: 4004 TCU_FAIL("Invliad enum"); 4005 break; 4006 } 4007 4008 if (BUILTIN != m_type) 4009 { 4010 if (0 == m_interface) 4011 { 4012 TCU_FAIL("Nullptr"); 4013 } 4014 } 4015 4016 /* Qualifiers */ 4017 if (true == m_qualifiers.empty()) 4018 { 4019 replaceToken("QUALIFIERS ", position, "", definition); 4020 } 4021 else 4022 { 4023 replaceToken("QUALIFIERS", position, m_qualifiers.c_str(), definition); 4024 } 4025 4026 // According to spec: integer or unsigned integer type must always be declared with flat qualifier 4027 bool flat_qualifier = false; 4028 if (m_type != BUILTIN && m_interface != NULL) 4029 { 4030 if (m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Int || 4031 m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Uint) 4032 { 4033 flat_qualifier = true; 4034 } 4035 } 4036 /* Storage */ 4037 switch (storage) 4038 { 4039 case VARYING_INPUT: 4040 storage_str = flat_qualifier ? "flat in " : "in "; 4041 break; 4042 case VARYING_OUTPUT: 4043 storage_str = "out "; 4044 break; 4045 case UNIFORM: 4046 storage_str = "uniform "; 4047 break; 4048 case SSB: 4049 storage_str = "buffer "; 4050 break; 4051 case MEMBER: 4052 storage_str = ""; 4053 break; 4054 default: 4055 TCU_FAIL("Invalid enum"); 4056 break; 4057 } 4058 4059 replaceToken("STORAGE", position, storage_str, definition); 4060 4061 /* Type */ 4062 if (BUILTIN == m_type) 4063 { 4064 replaceToken("TYPE", position, m_builtin.GetGLSLTypeName(), definition); 4065 } 4066 else 4067 { 4068 if (Interface::STRUCT == m_interface->m_type) 4069 { 4070 replaceToken("TYPE", position, m_interface->m_name.c_str(), definition); 4071 } 4072 else 4073 { 4074 const std::string& block_definition = m_interface->GetDefinition(); 4075 4076 replaceToken("TYPE", position, block_definition.c_str(), definition); 4077 } 4078 } 4079 4080 /* Name */ 4081 replaceToken("NAME", position, m_name.c_str(), definition); 4082 4083 /* Array size */ 4084 if (0 == m_n_array_elements) 4085 { 4086 replaceToken("ARRAY", position, "", definition); 4087 } 4088 else 4089 { 4090 char buffer[16]; 4091 sprintf(buffer, "[%d]", m_n_array_elements); 4092 4093 replaceToken("ARRAY", position, buffer, definition); 4094 } 4095 4096 /* Done */ 4097 return definition; 4098 } 4099 4100 /** Get definitions for variables collected in vector 4101 * 4102 * @param vector Collection of variables 4103 * @param flavour Flavour of variables 4104 * 4105 * @return Code with definitions 4106 **/ 4107 std::string GetDefinitions(const Variable::PtrVector& vector, Variable::FLAVOUR flavour) 4108 { 4109 std::string list = Utils::g_list; 4110 size_t position = 0; 4111 4112 for (GLuint i = 0; i < vector.size(); ++i) 4113 { 4114 Utils::insertElementOfList(vector[i]->GetDefinition(flavour).c_str(), "\n", position, list); 4115 } 4116 4117 Utils::endList("", position, list); 4118 4119 return list; 4120 } 4121 4122 /** Get definitions for interfaces collected in vector 4123 * 4124 * @param vector Collection of interfaces 4125 * 4126 * @return Code with definitions 4127 **/ 4128 std::string GetDefinitions(const Interface::PtrVector& vector) 4129 { 4130 std::string list = Utils::g_list; 4131 size_t position = 0; 4132 4133 for (GLuint i = 0; i < vector.size(); ++i) 4134 { 4135 Utils::insertElementOfList(vector[i]->GetDefinition().c_str(), "\n", position, list); 4136 } 4137 4138 Utils::endList("", position, list); 4139 4140 return list; 4141 } 4142 4143 /** Constructor 4144 * 4145 * @param name Name 4146 * @param type Type of interface 4147 **/ 4148 Interface::Interface(const GLchar* name, Interface::TYPE type) : m_name(name), m_type(type) 4149 { 4150 } 4151 4152 /** Adds member to interface 4153 * 4154 * @param member Descriptor of new member 4155 * 4156 * @return Pointer to just created member 4157 **/ 4158 Variable::Descriptor* Interface::AddMember(const Variable::Descriptor& member) 4159 { 4160 m_members.push_back(member); 4161 4162 return &m_members.back(); 4163 } 4164 4165 /** Get definition of interface 4166 * 4167 * @param Code with definition 4168 **/ 4169 std::string Interface::GetDefinition() const 4170 { 4171 std::string definition; 4172 size_t position = 0; 4173 4174 const GLchar* member_list = " MEMBER_DEFINITION\nMEMBER_LIST"; 4175 4176 if (STRUCT == m_type) 4177 { 4178 definition = "struct NAME {\nMEMBER_LIST};"; 4179 } 4180 else 4181 { 4182 definition = "NAME {\nMEMBER_LIST}"; 4183 } 4184 4185 /* Name */ 4186 replaceToken("NAME", position, m_name.c_str(), definition); 4187 4188 /* Member list */ 4189 for (GLuint i = 0; i < m_members.size(); ++i) 4190 { 4191 const size_t start_position = position; 4192 const std::string& member_definition = m_members[i].GetDefinition(Variable::BASIC, Variable::MEMBER); 4193 4194 /* Member list */ 4195 replaceToken("MEMBER_LIST", position, member_list, definition); 4196 4197 /* Move back position */ 4198 position = start_position; 4199 4200 /* Member definition */ 4201 replaceToken("MEMBER_DEFINITION", position, member_definition.c_str(), definition); 4202 } 4203 4204 /* Remove last member list */ 4205 replaceToken("MEMBER_LIST", position, "", definition); 4206 4207 /* Done */ 4208 return definition; 4209 } 4210 4211 /** Adds member of built-in type to interface 4212 * 4213 * @param name Name 4214 * @param qualifiers Qualifiers 4215 * @param expected_component Expected component of variable 4216 * @param expected_location Expected location 4217 * @param type Type 4218 * @param normalized Selects if data should be normalized 4219 * @param n_array_elements Length of array 4220 * @param expected_stride_of_element Expected stride of element 4221 * @param offset Offset 4222 * 4223 * @return Pointer to just created member 4224 **/ 4225 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component, 4226 GLint expected_location, const Type& type, GLboolean normalized, 4227 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset) 4228 { 4229 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, type, normalized, 4230 n_array_elements, expected_stride_of_element, offset)); 4231 } 4232 4233 /** Adds member of interface type to interface 4234 * 4235 * @param name Name 4236 * @param qualifiers Qualifiers 4237 * @param expected_component Expected component of variable 4238 * @param expected_location Expected location 4239 * @param type Type 4240 * @param normalized Selects if data should be normalized 4241 * @param n_array_elements Length of array 4242 * @param expected_stride_of_element Expected stride of element 4243 * @param offset Offset 4244 * 4245 * @return Pointer to just created member 4246 **/ 4247 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component, 4248 GLint expected_location, Interface* nterface, GLuint n_array_elements, 4249 GLint expected_stride_of_element, GLuint offset) 4250 { 4251 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, nterface, 4252 n_array_elements, expected_stride_of_element, offset)); 4253 } 4254 4255 /** Clears contents of vector of pointers 4256 * 4257 * @tparam T Type of elements 4258 * 4259 * @param vector Collection to be cleared 4260 **/ 4261 template <typename T> 4262 void clearPtrVector(std::vector<T*>& vector) 4263 { 4264 for (size_t i = 0; i < vector.size(); ++i) 4265 { 4266 T* t = vector[i]; 4267 4268 vector[i] = 0; 4269 4270 if (0 != t) 4271 { 4272 delete t; 4273 } 4274 } 4275 4276 vector.clear(); 4277 } 4278 4279 /** Constructor 4280 * 4281 * @param stage Stage described by that interface 4282 **/ 4283 ShaderInterface::ShaderInterface(Shader::STAGES stage) : m_stage(stage) 4284 { 4285 /* Nothing to be done */ 4286 } 4287 4288 /** Get definitions of globals 4289 * 4290 * @return Code with definitions 4291 **/ 4292 std::string ShaderInterface::GetDefinitionsGlobals() const 4293 { 4294 return m_globals; 4295 } 4296 4297 /** Get definitions of inputs 4298 * 4299 * @return Code with definitions 4300 **/ 4301 std::string ShaderInterface::GetDefinitionsInputs() const 4302 { 4303 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::INPUT); 4304 4305 return GetDefinitions(m_inputs, flavour); 4306 } 4307 4308 /** Get definitions of outputs 4309 * 4310 * @return Code with definitions 4311 **/ 4312 std::string ShaderInterface::GetDefinitionsOutputs() const 4313 { 4314 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::OUTPUT); 4315 4316 return GetDefinitions(m_outputs, flavour); 4317 } 4318 4319 /** Get definitions of buffers 4320 * 4321 * @return Code with definitions 4322 **/ 4323 std::string ShaderInterface::GetDefinitionsSSBs() const 4324 { 4325 return GetDefinitions(m_ssb_blocks, Variable::BASIC); 4326 } 4327 4328 /** Get definitions of uniforms 4329 * 4330 * @return Code with definitions 4331 **/ 4332 std::string ShaderInterface::GetDefinitionsUniforms() const 4333 { 4334 return GetDefinitions(m_uniforms, Variable::BASIC); 4335 } 4336 4337 /** Constructor 4338 * 4339 * @param in Input variable 4340 * @param out Output variable 4341 **/ 4342 VaryingConnection::VaryingConnection(Variable* in, Variable* out) : m_in(in), m_out(out) 4343 { 4344 /* NBothing to be done here */ 4345 } 4346 4347 /** Adds new varying connection to given stage 4348 * 4349 * @param stage Shader stage 4350 * @param in In varying 4351 * @param out Out varying 4352 **/ 4353 void VaryingPassthrough::Add(Shader::STAGES stage, Variable* in, Variable* out) 4354 { 4355 VaryingConnection::Vector& vector = Get(stage); 4356 4357 vector.push_back(VaryingConnection(in, out)); 4358 } 4359 4360 /** Get all passthrough connections for given stage 4361 * 4362 * @param stage Shader stage 4363 * 4364 * @return Vector of connections 4365 **/ 4366 VaryingConnection::Vector& VaryingPassthrough::Get(Shader::STAGES stage) 4367 { 4368 VaryingConnection::Vector* result = 0; 4369 4370 switch (stage) 4371 { 4372 case Shader::FRAGMENT: 4373 result = &m_fragment; 4374 break; 4375 case Shader::GEOMETRY: 4376 result = &m_geometry; 4377 break; 4378 case Shader::TESS_CTRL: 4379 result = &m_tess_ctrl; 4380 break; 4381 case Shader::TESS_EVAL: 4382 result = &m_tess_eval; 4383 break; 4384 case Shader::VERTEX: 4385 result = &m_vertex; 4386 break; 4387 default: 4388 TCU_FAIL("Invalid enum"); 4389 } 4390 4391 return *result; 4392 } 4393 4394 /** Constructor 4395 * 4396 **/ 4397 ProgramInterface::ProgramInterface() 4398 : m_compute(Shader::COMPUTE) 4399 , m_vertex(Shader::VERTEX) 4400 , m_tess_ctrl(Shader::TESS_CTRL) 4401 , m_tess_eval(Shader::TESS_EVAL) 4402 , m_geometry(Shader::GEOMETRY) 4403 , m_fragment(Shader::FRAGMENT) 4404 { 4405 } 4406 4407 /** Destructor 4408 * 4409 **/ 4410 ProgramInterface::~ProgramInterface() 4411 { 4412 clearPtrVector(m_blocks); 4413 clearPtrVector(m_structures); 4414 } 4415 4416 /** Adds new interface 4417 * 4418 * @param name 4419 * @param type 4420 * 4421 * @return Pointer to created interface 4422 **/ 4423 Interface* ProgramInterface::AddInterface(const GLchar* name, Interface::TYPE type) 4424 { 4425 Interface* interface = 0; 4426 4427 if (Interface::STRUCT == type) 4428 { 4429 interface = new Interface(name, type); 4430 4431 m_structures.push_back(interface); 4432 } 4433 else 4434 { 4435 interface = new Interface(name, type); 4436 4437 m_blocks.push_back(interface); 4438 } 4439 4440 return interface; 4441 } 4442 4443 /** Adds new block interface 4444 * 4445 * @param name 4446 * 4447 * @return Pointer to created interface 4448 **/ 4449 Interface* ProgramInterface::Block(const GLchar* name) 4450 { 4451 return AddInterface(name, Interface::BLOCK); 4452 } 4453 4454 /** Get interface of given shader stage 4455 * 4456 * @param stage Shader stage 4457 * 4458 * @return Reference to stage interface 4459 **/ 4460 ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage) 4461 { 4462 ShaderInterface* interface = 0; 4463 4464 switch (stage) 4465 { 4466 case Shader::COMPUTE: 4467 interface = &m_compute; 4468 break; 4469 case Shader::FRAGMENT: 4470 interface = &m_fragment; 4471 break; 4472 case Shader::GEOMETRY: 4473 interface = &m_geometry; 4474 break; 4475 case Shader::TESS_CTRL: 4476 interface = &m_tess_ctrl; 4477 break; 4478 case Shader::TESS_EVAL: 4479 interface = &m_tess_eval; 4480 break; 4481 case Shader::VERTEX: 4482 interface = &m_vertex; 4483 break; 4484 default: 4485 TCU_FAIL("Invalid enum"); 4486 } 4487 4488 return *interface; 4489 } 4490 4491 /** Get interface of given shader stage 4492 * 4493 * @param stage Shader stage 4494 * 4495 * @return Reference to stage interface 4496 **/ 4497 const ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage) const 4498 { 4499 const ShaderInterface* interface = 0; 4500 4501 switch (stage) 4502 { 4503 case Shader::COMPUTE: 4504 interface = &m_compute; 4505 break; 4506 case Shader::FRAGMENT: 4507 interface = &m_fragment; 4508 break; 4509 case Shader::GEOMETRY: 4510 interface = &m_geometry; 4511 break; 4512 case Shader::TESS_CTRL: 4513 interface = &m_tess_ctrl; 4514 break; 4515 case Shader::TESS_EVAL: 4516 interface = &m_tess_eval; 4517 break; 4518 case Shader::VERTEX: 4519 interface = &m_vertex; 4520 break; 4521 default: 4522 TCU_FAIL("Invalid enum"); 4523 } 4524 4525 return *interface; 4526 } 4527 4528 /** Clone interface of Vertex shader stage to other stages 4529 * It creates matching inputs, outputs, uniforms and buffers in other stages. 4530 * There are no additional outputs for FRAGMENT shader generated. 4531 * 4532 * @param varying_passthrough Collection of varyings connections 4533 **/ 4534 void ProgramInterface::CloneVertexInterface(VaryingPassthrough& varying_passthrough) 4535 { 4536 /* VS outputs >> TCS inputs >> TCS outputs >> .. >> FS inputs */ 4537 for (size_t i = 0; i < m_vertex.m_outputs.size(); ++i) 4538 { 4539 const Variable& vs_var = *m_vertex.m_outputs[i]; 4540 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage); 4541 4542 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough); 4543 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough); 4544 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough); 4545 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough); 4546 } 4547 4548 /* Copy uniforms from VS to other stages */ 4549 for (size_t i = 0; i < m_vertex.m_uniforms.size(); ++i) 4550 { 4551 Variable& vs_var = *m_vertex.m_uniforms[i]; 4552 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage); 4553 4554 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough); 4555 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough); 4556 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough); 4557 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough); 4558 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough); 4559 4560 /* Uniform blocks needs unique binding */ 4561 if (true == vs_var.IsBlock()) 4562 { 4563 replaceBinding(vs_var, Shader::VERTEX); 4564 } 4565 } 4566 4567 /* Copy SSBs from VS to other stages */ 4568 for (size_t i = 0; i < m_vertex.m_ssb_blocks.size(); ++i) 4569 { 4570 Variable& vs_var = *m_vertex.m_ssb_blocks[i]; 4571 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage); 4572 4573 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough); 4574 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough); 4575 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough); 4576 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough); 4577 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough); 4578 4579 /* SSBs blocks needs unique binding */ 4580 if (true == vs_var.IsBlock()) 4581 { 4582 replaceBinding(vs_var, Shader::VERTEX); 4583 } 4584 } 4585 4586 m_compute.m_globals = m_vertex.m_globals; 4587 m_fragment.m_globals = m_vertex.m_globals; 4588 m_geometry.m_globals = m_vertex.m_globals; 4589 m_tess_ctrl.m_globals = m_vertex.m_globals; 4590 m_tess_eval.m_globals = m_vertex.m_globals; 4591 } 4592 4593 /** Clone variable for specific stage 4594 * 4595 * @param variable Variable 4596 * @param stage Requested stage 4597 * @param prefix Prefix used in variable name that is specific for original stage 4598 * @param varying_passthrough Collection of varyings connections 4599 **/ 4600 void ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage, const GLchar* prefix, 4601 VaryingPassthrough& varying_passthrough) 4602 { 4603 switch (variable.m_storage) 4604 { 4605 case Variable::VARYING_OUTPUT: 4606 { 4607 Variable* in = cloneVariableForStage(variable, stage, Variable::VARYING_INPUT, prefix); 4608 4609 if (Shader::FRAGMENT != stage) 4610 { 4611 Variable* out = cloneVariableForStage(variable, stage, Variable::VARYING_OUTPUT, prefix); 4612 varying_passthrough.Add(stage, in, out); 4613 } 4614 } 4615 break; 4616 case Variable::UNIFORM: 4617 case Variable::SSB: 4618 cloneVariableForStage(variable, stage, variable.m_storage, prefix); 4619 break; 4620 default: 4621 TCU_FAIL("Invalid enum"); 4622 break; 4623 } 4624 } 4625 4626 /** Clone variable for specific stage 4627 * 4628 * @param variable Variable 4629 * @param stage Requested stage 4630 * @param storage Storage used by variable 4631 * @param prefix Prefix used in variable name that is specific for original stage 4632 * 4633 * @return New variable 4634 **/ 4635 Variable* ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage, 4636 Variable::STORAGE storage, const GLchar* prefix) 4637 { 4638 /* Initialize with original variable */ 4639 Variable* var = new Variable(variable); 4640 if (0 == var) 4641 { 4642 TCU_FAIL("Memory allocation"); 4643 } 4644 4645 /* Set up storage */ 4646 var->m_storage = storage; 4647 4648 /* Get name */ 4649 std::string name = variable.m_descriptor.m_name; 4650 4651 /* Prefix name with stage ID, empty means default block */ 4652 if (false == name.empty()) 4653 { 4654 size_t position = 0; 4655 const GLchar* stage_prefix = GetStagePrefix(stage, storage); 4656 Utils::replaceToken(prefix, position, stage_prefix, name); 4657 } 4658 var->m_descriptor.m_name = name; 4659 4660 /* Clone block */ 4661 const bool is_block = variable.IsBlock(); 4662 if (true == is_block) 4663 { 4664 const Interface* interface = variable.m_descriptor.m_interface; 4665 4666 Interface* block = CloneBlockForStage(*interface, stage, storage, prefix); 4667 4668 var->m_descriptor.m_interface = block; 4669 } 4670 4671 /* Store variable */ 4672 ShaderInterface& si = GetShaderInterface(stage); 4673 Variable* result = 0; 4674 4675 switch (storage) 4676 { 4677 case Variable::VARYING_INPUT: 4678 si.m_inputs.push_back(var); 4679 result = si.m_inputs.back(); 4680 break; 4681 case Variable::VARYING_OUTPUT: 4682 si.m_outputs.push_back(var); 4683 result = si.m_outputs.back(); 4684 break; 4685 case Variable::UNIFORM: 4686 /* Uniform blocks needs unique binding */ 4687 if (true == is_block) 4688 { 4689 replaceBinding(*var, stage); 4690 } 4691 4692 si.m_uniforms.push_back(var); 4693 result = si.m_uniforms.back(); 4694 break; 4695 case Variable::SSB: 4696 /* SSBs needs unique binding */ 4697 if (true == is_block) 4698 { 4699 replaceBinding(*var, stage); 4700 } 4701 4702 si.m_ssb_blocks.push_back(var); 4703 result = si.m_ssb_blocks.back(); 4704 break; 4705 default: 4706 TCU_FAIL("Invalid enum"); 4707 break; 4708 } 4709 4710 return result; 4711 } 4712 4713 /** clone block to specific stage 4714 * 4715 * @param block Block to be copied 4716 * @param stage Specific stage 4717 * @param storage Storage used by block 4718 * @param prefix Prefix used in block name 4719 * 4720 * @return New interface 4721 **/ 4722 Interface* ProgramInterface::CloneBlockForStage(const Interface& block, Shader::STAGES stage, Variable::STORAGE storage, 4723 const GLchar* prefix) 4724 { 4725 /* Get name */ 4726 std::string name = block.m_name; 4727 4728 /* Prefix name with stage ID */ 4729 size_t position = 0; 4730 const GLchar* stage_prefix = GetStagePrefix(stage, storage); 4731 Utils::replaceToken(prefix, position, stage_prefix, name); 4732 4733 Interface* ptr = GetBlock(name.c_str()); 4734 4735 if (0 == ptr) 4736 { 4737 ptr = AddInterface(name.c_str(), Interface::BLOCK); 4738 } 4739 4740 ptr->m_members = block.m_members; 4741 4742 return ptr; 4743 } 4744 4745 /** Get stage specific prefix used in names 4746 * 4747 * @param stage Stage 4748 * @param storage Storage class 4749 * 4750 * @return String 4751 **/ 4752 const GLchar* ProgramInterface::GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage) 4753 { 4754 static const GLchar* lut[Shader::STAGE_MAX][Variable::STORAGE_MAX] = { 4755 /* IN OUT UNIFORM SSB MEMBER */ 4756 /* CS */ { 0, 0, "cs_uni_", "cs_buf_", "" }, 4757 /* VS */ { "in_vs_", "vs_tcs_", "vs_uni_", "vs_buf_", "" }, 4758 /* TCS */ { "vs_tcs_", "tcs_tes_", "tcs_uni_", "tcs_buf_", "" }, 4759 /* TES */ { "tcs_tes_", "tes_gs_", "tes_uni_", "tes_buf_", "" }, 4760 /* GS */ { "tes_gs_", "gs_fs_", "gs_uni_", "gs_buf_", "" }, 4761 /* FS */ { "gs_fs_", "fs_out_", "fs_uni_", "fs_buf_", "" }, 4762 }; 4763 4764 const GLchar* result = 0; 4765 4766 result = lut[stage][storage]; 4767 4768 return result; 4769 } 4770 4771 /** Get definitions of all structures used in program interface 4772 * 4773 * @return String with code 4774 **/ 4775 std::string ProgramInterface::GetDefinitionsStructures() const 4776 { 4777 return GetDefinitions(m_structures); 4778 } 4779 4780 /** Get interface code for stage 4781 * 4782 * @param stage Specific stage 4783 * 4784 * @return String with code 4785 **/ 4786 std::string ProgramInterface::GetInterfaceForStage(Shader::STAGES stage) const 4787 { 4788 size_t position = 0; 4789 std::string interface = "/* Globals */\n" 4790 "GLOBALS\n" 4791 "\n" 4792 "/* Structures */\n" 4793 "STRUCTURES\n" 4794 "\n" 4795 "/* Uniforms */\n" 4796 "UNIFORMS\n" 4797 "\n" 4798 "/* Inputs */\n" 4799 "INPUTS\n" 4800 "\n" 4801 "/* Outputs */\n" 4802 "OUTPUTS\n" 4803 "\n" 4804 "/* Storage */\n" 4805 "STORAGE\n"; 4806 4807 const ShaderInterface& si = GetShaderInterface(stage); 4808 4809 const std::string& structures = GetDefinitionsStructures(); 4810 4811 const std::string& globals = si.GetDefinitionsGlobals(); 4812 const std::string& inputs = si.GetDefinitionsInputs(); 4813 const std::string& outputs = si.GetDefinitionsOutputs(); 4814 const std::string& uniforms = si.GetDefinitionsUniforms(); 4815 const std::string& ssbs = si.GetDefinitionsSSBs(); 4816 4817 replaceToken("GLOBALS", position, globals.c_str(), interface); 4818 replaceToken("STRUCTURES", position, structures.c_str(), interface); 4819 replaceToken("UNIFORMS", position, uniforms.c_str(), interface); 4820 replaceToken("INPUTS", position, inputs.c_str(), interface); 4821 replaceToken("OUTPUTS", position, outputs.c_str(), interface); 4822 replaceToken("STORAGE", position, ssbs.c_str(), interface); 4823 4824 return interface; 4825 } 4826 4827 /** Functional object used in find_if algorithm, in search for interface of given name 4828 * 4829 **/ 4830 struct matchInterfaceName 4831 { 4832 matchInterfaceName(const GLchar* name) : m_name(name) 4833 { 4834 } 4835 4836 bool operator()(const Interface* interface) 4837 { 4838 return 0 == interface->m_name.compare(m_name); 4839 } 4840 4841 const GLchar* m_name; 4842 }; 4843 4844 /** Finds interface of given name in given vector of interfaces 4845 * 4846 * @param vector Collection of interfaces 4847 * @param name Requested name 4848 * 4849 * @return Pointer to interface if available, 0 otherwise 4850 **/ 4851 static Interface* findInterfaceByName(Interface::PtrVector& vector, const GLchar* name) 4852 { 4853 Interface::PtrVector::iterator it = std::find_if(vector.begin(), vector.end(), matchInterfaceName(name)); 4854 4855 if (vector.end() != it) 4856 { 4857 return *it; 4858 } 4859 else 4860 { 4861 return 0; 4862 } 4863 } 4864 4865 /** Search for block of given name 4866 * 4867 * @param name Name of block 4868 * 4869 * @return Pointer to block or 0 4870 **/ 4871 Interface* ProgramInterface::GetBlock(const GLchar* name) 4872 { 4873 return findInterfaceByName(m_blocks, name); 4874 } 4875 4876 /** Search for structure of given name 4877 * 4878 * @param name Name of structure 4879 * 4880 * @return Pointer to structure or 0 4881 **/ 4882 Interface* ProgramInterface::GetStructure(const GLchar* name) 4883 { 4884 return findInterfaceByName(m_structures, name); 4885 } 4886 4887 /** Adds new sturcture to interface 4888 * 4889 * @param name Name of structure 4890 * 4891 * @return Created structure 4892 **/ 4893 Interface* ProgramInterface::Structure(const GLchar* name) 4894 { 4895 return AddInterface(name, Interface::STRUCT); 4896 } 4897 4898 /** Replace "BINDING" token in qualifiers string to value specific for given stage 4899 * 4900 * @param variable Variable to modify 4901 * @param stage Requested stage 4902 **/ 4903 void ProgramInterface::replaceBinding(Variable& variable, Shader::STAGES stage) 4904 { 4905 GLchar binding[16]; 4906 sprintf(binding, "%d", stage); 4907 replaceAllTokens("BINDING", binding, variable.m_descriptor.m_qualifiers); 4908 } 4909 } /* Utils namespace */ 4910 4911 /** Debuging procedure. Logs parameters. 4912 * 4913 * @param source As specified in GL spec. 4914 * @param type As specified in GL spec. 4915 * @param id As specified in GL spec. 4916 * @param severity As specified in GL spec. 4917 * @param ignored 4918 * @param message As specified in GL spec. 4919 * @param info Pointer to instance of Context used by test. 4920 */ 4921 void GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */, 4922 const GLchar* message, void* info) 4923 { 4924 deqp::Context* ctx = (deqp::Context*)info; 4925 4926 const GLchar* source_str = "Unknown"; 4927 const GLchar* type_str = "Unknown"; 4928 const GLchar* severity_str = "Unknown"; 4929 4930 switch (source) 4931 { 4932 case GL_DEBUG_SOURCE_API: 4933 source_str = "API"; 4934 break; 4935 case GL_DEBUG_SOURCE_APPLICATION: 4936 source_str = "APP"; 4937 break; 4938 case GL_DEBUG_SOURCE_OTHER: 4939 source_str = "OTR"; 4940 break; 4941 case GL_DEBUG_SOURCE_SHADER_COMPILER: 4942 source_str = "COM"; 4943 break; 4944 case GL_DEBUG_SOURCE_THIRD_PARTY: 4945 source_str = "3RD"; 4946 break; 4947 case GL_DEBUG_SOURCE_WINDOW_SYSTEM: 4948 source_str = "WS"; 4949 break; 4950 default: 4951 break; 4952 } 4953 4954 switch (type) 4955 { 4956 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: 4957 type_str = "DEPRECATED_BEHAVIOR"; 4958 break; 4959 case GL_DEBUG_TYPE_ERROR: 4960 type_str = "ERROR"; 4961 break; 4962 case GL_DEBUG_TYPE_MARKER: 4963 type_str = "MARKER"; 4964 break; 4965 case GL_DEBUG_TYPE_OTHER: 4966 type_str = "OTHER"; 4967 break; 4968 case GL_DEBUG_TYPE_PERFORMANCE: 4969 type_str = "PERFORMANCE"; 4970 break; 4971 case GL_DEBUG_TYPE_POP_GROUP: 4972 type_str = "POP_GROUP"; 4973 break; 4974 case GL_DEBUG_TYPE_PORTABILITY: 4975 type_str = "PORTABILITY"; 4976 break; 4977 case GL_DEBUG_TYPE_PUSH_GROUP: 4978 type_str = "PUSH_GROUP"; 4979 break; 4980 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: 4981 type_str = "UNDEFINED_BEHAVIOR"; 4982 break; 4983 default: 4984 break; 4985 } 4986 4987 switch (severity) 4988 { 4989 case GL_DEBUG_SEVERITY_HIGH: 4990 severity_str = "H"; 4991 break; 4992 case GL_DEBUG_SEVERITY_LOW: 4993 severity_str = "L"; 4994 break; 4995 case GL_DEBUG_SEVERITY_MEDIUM: 4996 severity_str = "M"; 4997 break; 4998 case GL_DEBUG_SEVERITY_NOTIFICATION: 4999 severity_str = "N"; 5000 break; 5001 default: 5002 break; 5003 } 5004 5005 ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|" 5006 << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id 5007 << ": " << message << tcu::TestLog::EndMessage; 5008 } 5009 5010 /** Constructor 5011 * 5012 * @param context Test context 5013 * @param test_name Test name 5014 * @param test_description Test description 5015 **/ 5016 TestBase::TestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description) 5017 : TestCase(context, test_name, test_description) 5018 { 5019 /* Nothing to be done here */ 5020 } 5021 5022 /** Execute test 5023 * 5024 * @return tcu::TestNode::STOP otherwise 5025 **/ 5026 tcu::TestNode::IterateResult TestBase::iterate() 5027 { 5028 bool test_result; 5029 5030 #if DEBUG_ENBALE_MESSAGE_CALLBACK 5031 const Functions& gl = m_context.getRenderContext().getFunctions(); 5032 5033 gl.debugMessageCallback(debug_proc, &m_context); 5034 GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 5035 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 5036 5037 try 5038 { 5039 /* Execute test */ 5040 test_result = test(); 5041 } 5042 catch (std::exception& exc) 5043 { 5044 TCU_FAIL(exc.what()); 5045 } 5046 5047 /* Set result */ 5048 if (true == test_result) 5049 { 5050 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 5051 } 5052 else 5053 { 5054 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 5055 } 5056 5057 /* Done */ 5058 return tcu::TestNode::STOP; 5059 } 5060 5061 /** Get last input location available for given type at specific stage 5062 * 5063 * @param stage Shader stage 5064 * @param type Input type 5065 * @param array_length Length of input array 5066 * 5067 * @return Last location index 5068 **/ 5069 GLint TestBase::getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length) 5070 { 5071 GLint divide = 4; /* 4 components per location */ 5072 GLint param = 0; 5073 GLenum pname = 0; 5074 5075 /* Select pnmae */ 5076 switch (stage) 5077 { 5078 case Utils::Shader::FRAGMENT: 5079 pname = GL_MAX_FRAGMENT_INPUT_COMPONENTS; 5080 break; 5081 case Utils::Shader::GEOMETRY: 5082 pname = GL_MAX_GEOMETRY_INPUT_COMPONENTS; 5083 break; 5084 case Utils::Shader::TESS_CTRL: 5085 pname = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS; 5086 break; 5087 case Utils::Shader::TESS_EVAL: 5088 pname = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS; 5089 break; 5090 case Utils::Shader::VERTEX: 5091 pname = GL_MAX_VERTEX_ATTRIBS; 5092 divide = 1; 5093 break; 5094 default: 5095 TCU_FAIL("Invalid enum"); 5096 break; 5097 } 5098 5099 /* Zero means no array, but 1 slot is required */ 5100 if (0 == array_length) 5101 { 5102 array_length += 1; 5103 } 5104 5105 /* Get MAX */ 5106 const Functions& gl = m_context.getRenderContext().getFunctions(); 5107 5108 gl.getIntegerv(pname, ¶m); 5109 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 5110 5111 /* Calculate */ 5112 #if WRKARD_VARYINGLOCATIONSTEST 5113 5114 const GLint n_avl_locations = 16; 5115 5116 #else 5117 5118 const GLint n_avl_locations = param / divide; 5119 5120 #endif 5121 5122 const GLuint n_req_location = type.GetLocations(stage == Utils::Shader::VERTEX) * array_length; 5123 5124 return n_avl_locations - n_req_location; /* last is max - 1 */ 5125 } 5126 5127 /** Get last input location available for given type at specific stage 5128 * 5129 * @param stage Shader stage 5130 * @param type Input type 5131 * @param array_length Length of input array 5132 * 5133 * @return Last location index 5134 **/ 5135 GLint TestBase::getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length) 5136 { 5137 GLint param = 0; 5138 GLenum pname = 0; 5139 5140 /* Select pnmae */ 5141 switch (stage) 5142 { 5143 case Utils::Shader::GEOMETRY: 5144 pname = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS; 5145 break; 5146 case Utils::Shader::TESS_CTRL: 5147 pname = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS; 5148 break; 5149 case Utils::Shader::TESS_EVAL: 5150 pname = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS; 5151 break; 5152 case Utils::Shader::VERTEX: 5153 pname = GL_MAX_VERTEX_OUTPUT_COMPONENTS; 5154 break; 5155 default: 5156 TCU_FAIL("Invalid enum"); 5157 break; 5158 } 5159 5160 /* Zero means no array, but 1 slot is required */ 5161 if (0 == array_length) 5162 { 5163 array_length += 1; 5164 } 5165 5166 /* Get MAX */ 5167 const Functions& gl = m_context.getRenderContext().getFunctions(); 5168 5169 gl.getIntegerv(pname, ¶m); 5170 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 5171 5172 /* Calculate */ 5173 #if WRKARD_VARYINGLOCATIONSTEST 5174 5175 const GLint n_avl_locations = 16; 5176 5177 #else 5178 5179 const GLint n_avl_locations = param / 4; /* 4 components per location */ 5180 5181 #endif 5182 5183 const GLuint n_req_location = type.GetLocations() * array_length; 5184 5185 return n_avl_locations - n_req_location; /* last is max - 1 */ 5186 } 5187 5188 /** Basic implementation 5189 * 5190 * @param ignored 5191 * 5192 * @return Empty string 5193 **/ 5194 std::string TestBase::getTestCaseName(GLuint /* test_case_index */) 5195 { 5196 std::string result; 5197 5198 return result; 5199 } 5200 5201 /** Basic implementation 5202 * 5203 * @return 1 5204 **/ 5205 GLuint TestBase::getTestCaseNumber() 5206 { 5207 return 1; 5208 } 5209 5210 /** Check if flat qualifier is required for given type, stage and storage 5211 * 5212 * @param stage Shader stage 5213 * @param type Input type 5214 * @param storage Storage of variable 5215 * 5216 * @return Last location index 5217 **/ 5218 bool TestBase::isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type& type, 5219 Utils::Variable::STORAGE storage) const 5220 { 5221 /* Float types do not need flat at all */ 5222 if (Utils::Type::Float == type.m_basic_type) 5223 { 5224 return false; 5225 } 5226 5227 /* Inputs to fragment shader */ 5228 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_INPUT == storage)) 5229 { 5230 return true; 5231 } 5232 5233 /* Outputs from geometry shader */ 5234 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_OUTPUT == storage)) 5235 { 5236 return true; 5237 } 5238 5239 return false; 5240 } 5241 5242 /** Basic implementation of testInit method 5243 * 5244 **/ 5245 void TestBase::testInit() 5246 { 5247 } 5248 5249 /** Calculate stride for interface 5250 * 5251 * @param interface Interface 5252 * 5253 * @return Calculated value 5254 **/ 5255 GLuint TestBase::calculateStride(const Utils::Interface& interface) const 5256 { 5257 const size_t n_members = interface.m_members.size(); 5258 5259 GLuint stride = 0; 5260 5261 for (size_t i = 0; i < n_members; ++i) 5262 { 5263 const Utils::Variable::Descriptor& member = interface.m_members[i]; 5264 const GLuint member_offset = member.m_offset; 5265 const GLuint member_stride = member.m_expected_stride_of_element; 5266 const GLuint member_ends_at = member_offset + member_stride; 5267 5268 stride = std::max(stride, member_ends_at); 5269 } 5270 5271 return stride; 5272 } 5273 5274 /** Generate data for interface. This routine is recursive 5275 * 5276 * @param interface Interface 5277 * @param offset Offset in out_data 5278 * @param out_data Buffer to be filled 5279 **/ 5280 void TestBase::generateData(const Utils::Interface& interface, GLuint offset, std::vector<GLubyte>& out_data) const 5281 { 5282 const size_t n_members = interface.m_members.size(); 5283 GLubyte* ptr = &out_data[offset]; 5284 5285 for (size_t i = 0; i < n_members; ++i) 5286 { 5287 const Utils::Variable::Descriptor& member = interface.m_members[i]; 5288 const GLuint member_offset = member.m_offset; 5289 const GLuint n_elements = (0 == member.m_n_array_elements) ? 1 : member.m_n_array_elements; 5290 5291 for (GLuint element = 0; element < n_elements; ++element) 5292 { 5293 const GLuint element_offset = element * member.m_expected_stride_of_element; 5294 const GLuint data_offfset = member_offset + element_offset; 5295 5296 if (Utils::Variable::BUILTIN == member.m_type) 5297 { 5298 const std::vector<GLubyte>& data = member.m_builtin.GenerateData(); 5299 5300 memcpy(ptr + data_offfset, &data[0], data.size()); 5301 } 5302 else 5303 { 5304 generateData(*member.m_interface, offset + data_offfset, out_data); 5305 } 5306 } 5307 } 5308 } 5309 5310 /** Get type at index 5311 * 5312 * @param index Index of requested type 5313 * 5314 * @return Type 5315 **/ 5316 Utils::Type TestBase::getType(GLuint index) const 5317 { 5318 Utils::Type type; 5319 5320 switch (index) 5321 { 5322 case 0: 5323 type = Utils::Type::_double; 5324 break; 5325 case 1: 5326 type = Utils::Type::dmat2; 5327 break; 5328 case 2: 5329 type = Utils::Type::dmat2x3; 5330 break; 5331 case 3: 5332 type = Utils::Type::dmat2x4; 5333 break; 5334 case 4: 5335 type = Utils::Type::dmat3; 5336 break; 5337 case 5: 5338 type = Utils::Type::dmat3x2; 5339 break; 5340 case 6: 5341 type = Utils::Type::dmat3x4; 5342 break; 5343 case 7: 5344 type = Utils::Type::dmat4; 5345 break; 5346 case 8: 5347 type = Utils::Type::dmat4x2; 5348 break; 5349 case 9: 5350 type = Utils::Type::dmat4x3; 5351 break; 5352 case 10: 5353 type = Utils::Type::dvec2; 5354 break; 5355 case 11: 5356 type = Utils::Type::dvec3; 5357 break; 5358 case 12: 5359 type = Utils::Type::dvec4; 5360 break; 5361 case 13: 5362 type = Utils::Type::_float; 5363 break; 5364 case 14: 5365 type = Utils::Type::mat2; 5366 break; 5367 case 15: 5368 type = Utils::Type::mat2x3; 5369 break; 5370 case 16: 5371 type = Utils::Type::mat2x4; 5372 break; 5373 case 17: 5374 type = Utils::Type::mat3; 5375 break; 5376 case 18: 5377 type = Utils::Type::mat3x2; 5378 break; 5379 case 19: 5380 type = Utils::Type::mat3x4; 5381 break; 5382 case 20: 5383 type = Utils::Type::mat4; 5384 break; 5385 case 21: 5386 type = Utils::Type::mat4x2; 5387 break; 5388 case 22: 5389 type = Utils::Type::mat4x3; 5390 break; 5391 case 23: 5392 type = Utils::Type::vec2; 5393 break; 5394 case 24: 5395 type = Utils::Type::vec3; 5396 break; 5397 case 25: 5398 type = Utils::Type::vec4; 5399 break; 5400 case 26: 5401 type = Utils::Type::_int; 5402 break; 5403 case 27: 5404 type = Utils::Type::ivec2; 5405 break; 5406 case 28: 5407 type = Utils::Type::ivec3; 5408 break; 5409 case 29: 5410 type = Utils::Type::ivec4; 5411 break; 5412 case 30: 5413 type = Utils::Type::uint; 5414 break; 5415 case 31: 5416 type = Utils::Type::uvec2; 5417 break; 5418 case 32: 5419 type = Utils::Type::uvec3; 5420 break; 5421 case 33: 5422 type = Utils::Type::uvec4; 5423 break; 5424 default: 5425 TCU_FAIL("invalid enum"); 5426 } 5427 5428 return type; 5429 } 5430 5431 /** Get name of type at index 5432 * 5433 * @param index Index of type 5434 * 5435 * @return Name 5436 **/ 5437 std::string TestBase::getTypeName(GLuint index) const 5438 { 5439 std::string name = getType(index).GetGLSLTypeName(); 5440 5441 return name; 5442 } 5443 5444 /** Get number of types 5445 * 5446 * @return 34 5447 **/ 5448 glw::GLuint TestBase::getTypesNumber() const 5449 { 5450 return 34; 5451 } 5452 5453 /** Execute test 5454 * 5455 * @return true if test pass, false otherwise 5456 **/ 5457 bool TestBase::test() 5458 { 5459 bool result = true; 5460 GLuint n_test_cases = 0; 5461 5462 /* Prepare test */ 5463 testInit(); 5464 5465 /* GL entry points */ 5466 const Functions& gl = m_context.getRenderContext().getFunctions(); 5467 5468 /* Tessellation patch set up */ 5469 gl.patchParameteri(GL_PATCH_VERTICES, 1); 5470 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri"); 5471 5472 /* Get number of test cases */ 5473 n_test_cases = getTestCaseNumber(); 5474 5475 #if DEBUG_REPEAT_TEST_CASE 5476 5477 while (1) 5478 { 5479 GLuint test_case = DEBUG_REPEATED_TEST_CASE; 5480 5481 #else /* DEBUG_REPEAT_TEST_CASE */ 5482 5483 for (GLuint test_case = 0; test_case < n_test_cases; ++test_case) 5484 { 5485 5486 #endif /* DEBUG_REPEAT_TEST_CASE */ 5487 5488 bool case_result = true; 5489 5490 /* Execute case */ 5491 if (false == testCase(test_case)) 5492 { 5493 case_result = false; 5494 } 5495 5496 /* Log failure */ 5497 if (false == case_result) 5498 { 5499 const std::string& test_case_name = getTestCaseName(test_case); 5500 5501 if (false == test_case_name.empty()) 5502 { 5503 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case_name 5504 << ") failed." << tcu::TestLog::EndMessage; 5505 } 5506 else 5507 { 5508 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case 5509 << ") failed." << tcu::TestLog::EndMessage; 5510 } 5511 5512 result = false; 5513 } 5514 } 5515 5516 /* Done */ 5517 return result; 5518 } 5519 5520 /* Constants used by BufferTestBase */ 5521 const GLuint BufferTestBase::bufferDescriptor::m_non_indexed = -1; 5522 5523 /** Constructor 5524 * 5525 * @param context Test context 5526 * @param test_name Name of test 5527 * @param test_description Description of test 5528 **/ 5529 BufferTestBase::BufferTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description) 5530 : TestBase(context, test_name, test_description) 5531 { 5532 } 5533 5534 /** Execute drawArrays for single vertex 5535 * 5536 * @param ignored 5537 * 5538 * @return true 5539 **/ 5540 bool BufferTestBase::executeDrawCall(bool tesEnabled, GLuint /* test_case_index */) 5541 { 5542 const Functions& gl = m_context.getRenderContext().getFunctions(); 5543 5544 gl.disable(GL_RASTERIZER_DISCARD); 5545 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 5546 5547 gl.beginTransformFeedback(GL_POINTS); 5548 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 5549 5550 // Only TES is existed, glDrawArray can use the parameter GL_PATCHES 5551 if (tesEnabled == false) 5552 { 5553 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 5554 } 5555 else 5556 { 5557 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 5558 } 5559 5560 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 5561 5562 gl.endTransformFeedback(); 5563 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 5564 5565 return true; 5566 } 5567 5568 /** Get descriptors of buffers necessary for test 5569 * 5570 * @param ignored 5571 * @param ignored 5572 **/ 5573 void BufferTestBase::getBufferDescriptors(glw::GLuint /* test_case_index */, 5574 bufferDescriptor::Vector& /* out_descriptors */) 5575 { 5576 /* Nothhing to be done */ 5577 } 5578 5579 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings 5580 * 5581 * @param ignored 5582 * @param ignored 5583 **/ 5584 void BufferTestBase::getCapturedVaryings(glw::GLuint /* test_case_index */, 5585 Utils::Program::NameVector& /* captured_varyings */) 5586 { 5587 /* Nothing to be done */ 5588 } 5589 5590 /** Get body of main function for given shader stage 5591 * 5592 * @param ignored 5593 * @param ignored 5594 * @param out_assignments Set to empty 5595 * @param out_calculations Set to empty 5596 **/ 5597 void BufferTestBase::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */, 5598 std::string& out_assignments, std::string& out_calculations) 5599 { 5600 out_assignments = ""; 5601 out_calculations = ""; 5602 } 5603 5604 /** Get interface of shader 5605 * 5606 * @param ignored 5607 * @param ignored 5608 * @param out_interface Set to "" 5609 **/ 5610 void BufferTestBase::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */, 5611 std::string& out_interface) 5612 { 5613 out_interface = ""; 5614 } 5615 5616 /** Get source code of shader 5617 * 5618 * @param test_case_index Index of test case 5619 * @param stage Shader stage 5620 * 5621 * @return Source 5622 **/ 5623 std::string BufferTestBase::getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage) 5624 { 5625 std::string assignments; 5626 std::string calculations; 5627 std::string interface; 5628 5629 /* */ 5630 getShaderBody(test_case_index, stage, assignments, calculations); 5631 getShaderInterface(test_case_index, stage, interface); 5632 5633 /* */ 5634 std::string source = getShaderTemplate(stage); 5635 5636 /* */ 5637 size_t position = 0; 5638 Utils::replaceToken("INTERFACE", position, interface.c_str(), source); 5639 Utils::replaceToken("CALCULATIONS", position, calculations.c_str(), source); 5640 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source); 5641 5642 /* */ 5643 return source; 5644 } 5645 5646 /** Inspects program to check if all resources are as expected 5647 * 5648 * @param ignored 5649 * @param ignored 5650 * @param ignored 5651 * 5652 * @return true 5653 **/ 5654 bool BufferTestBase::inspectProgram(GLuint /* test_case_index */, Utils::Program& /* program */, 5655 std::stringstream& /* out_stream */) 5656 { 5657 return true; 5658 } 5659 5660 /** Runs test case 5661 * 5662 * @param test_case_index Id of test case 5663 * 5664 * @return true if test case pass, false otherwise 5665 **/ 5666 bool BufferTestBase::testCase(GLuint test_case_index) 5667 { 5668 try 5669 { 5670 bufferCollection buffers; 5671 Utils::Program::NameVector captured_varyings; 5672 bufferDescriptor::Vector descriptors; 5673 Utils::Program program(m_context); 5674 Utils::VertexArray vao(m_context); 5675 5676 /* Get captured varyings */ 5677 getCapturedVaryings(test_case_index, captured_varyings); 5678 5679 /* Get shader sources */ 5680 const std::string& fragment_shader = getShaderSource(test_case_index, Utils::Shader::FRAGMENT); 5681 const std::string& geometry_shader = getShaderSource(test_case_index, Utils::Shader::GEOMETRY); 5682 const std::string& tess_ctrl_shader = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL); 5683 const std::string& tess_eval_shader = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL); 5684 const std::string& vertex_shader = getShaderSource(test_case_index, Utils::Shader::VERTEX); 5685 5686 /* Set up program */ 5687 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader, 5688 vertex_shader, captured_varyings, true, false /* is_separable */); 5689 5690 /* Inspection */ 5691 { 5692 std::stringstream stream; 5693 if (false == inspectProgram(test_case_index, program, stream)) 5694 { 5695 m_context.getTestContext().getLog() 5696 << tcu::TestLog::Message 5697 << "Program inspection failed. Test case: " << getTestCaseName(test_case_index) 5698 << ". Reason: " << stream.str() << tcu::TestLog::EndMessage 5699 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader) 5700 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader) 5701 << tcu::TestLog::KernelSource(fragment_shader); 5702 5703 return false; 5704 } 5705 } 5706 5707 program.Use(); 5708 5709 /* Set up buffers */ 5710 getBufferDescriptors(test_case_index, descriptors); 5711 cleanBuffers(); 5712 prepareBuffers(descriptors, buffers); 5713 5714 /* Set up vao */ 5715 vao.Init(); 5716 vao.Bind(); 5717 5718 /* Draw */ 5719 bool result = executeDrawCall((program.m_tess_eval.m_id != 0), test_case_index); 5720 5721 #if USE_NSIGHT 5722 m_context.getRenderContext().postIterate(); 5723 #endif 5724 5725 if (false == result) 5726 { 5727 m_context.getTestContext().getLog() 5728 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader) 5729 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader) 5730 << tcu::TestLog::KernelSource(fragment_shader); 5731 5732 return false; 5733 } 5734 5735 /* Verify result */ 5736 if (false == verifyBuffers(buffers)) 5737 { 5738 m_context.getTestContext().getLog() 5739 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader) 5740 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader) 5741 << tcu::TestLog::KernelSource(fragment_shader); 5742 5743 return false; 5744 } 5745 } 5746 catch (Utils::Shader::InvalidSourceException& exc) 5747 { 5748 exc.log(m_context); 5749 TCU_FAIL(exc.what()); 5750 } 5751 catch (Utils::Program::BuildException& exc) 5752 { 5753 exc.log(m_context); 5754 TCU_FAIL(exc.what()); 5755 } 5756 5757 /* Done */ 5758 return true; 5759 } 5760 5761 /** Verify contents of buffers 5762 * 5763 * @param buffers Collection of buffers to be verified 5764 * 5765 * @return true if everything is as expected, false otherwise 5766 **/ 5767 bool BufferTestBase::verifyBuffers(bufferCollection& buffers) 5768 { 5769 bool result = true; 5770 5771 for (bufferCollection::Vector::iterator it = buffers.m_vector.begin(), end = buffers.m_vector.end(); end != it; 5772 ++it) 5773 { 5774 bufferCollection::pair& pair = *it; 5775 Utils::Buffer* buffer = pair.m_buffer; 5776 bufferDescriptor* descriptor = pair.m_descriptor; 5777 size_t size = descriptor->m_expected_data.size(); 5778 5779 /* Skip buffers that have no expected data */ 5780 if (0 == size) 5781 { 5782 continue; 5783 } 5784 5785 /* Get pointer to contents of buffer */ 5786 buffer->Bind(); 5787 GLvoid* buffer_data = buffer->Map(Utils::Buffer::ReadOnly); 5788 5789 /* Get pointer to expected data */ 5790 GLvoid* expected_data = &descriptor->m_expected_data[0]; 5791 5792 /* Compare */ 5793 int res = memcmp(buffer_data, expected_data, size); 5794 5795 if (0 != res) 5796 { 5797 m_context.getTestContext().getLog() 5798 << tcu::TestLog::Message 5799 << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target) 5800 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage; 5801 5802 result = false; 5803 } 5804 5805 /* Release buffer mapping */ 5806 buffer->UnMap(); 5807 } 5808 5809 return result; 5810 } 5811 5812 /** Unbinds all uniforms and xfb 5813 * 5814 **/ 5815 void BufferTestBase::cleanBuffers() 5816 { 5817 const Functions& gl = m_context.getRenderContext().getFunctions(); 5818 5819 GLint max_uni = 0; 5820 GLint max_xfb = 0; 5821 5822 gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uni); 5823 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb); 5824 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 5825 5826 for (GLint i = 0; i < max_uni; ++i) 5827 { 5828 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Uniform, i); 5829 } 5830 5831 for (GLint i = 0; i < max_xfb; ++i) 5832 { 5833 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Transform_feedback, i); 5834 } 5835 } 5836 5837 /** Get template of shader for given stage 5838 * 5839 * @param stage Stage 5840 * 5841 * @return Template of shader source 5842 **/ 5843 std::string BufferTestBase::getShaderTemplate(Utils::Shader::STAGES stage) 5844 { 5845 static const GLchar* compute_shader_template = "#version 430 core\n" 5846 "#extension GL_ARB_enhanced_layouts : require\n" 5847 "\n" 5848 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 5849 "\n" 5850 "writeonly uniform uimage2D uni_image;\n" 5851 "\n" 5852 "INTERFACE" 5853 "\n" 5854 "void main()\n" 5855 "{\n" 5856 "CALCULATIONS" 5857 "\n" 5858 "ASSIGNMENTS" 5859 "}\n" 5860 "\n"; 5861 5862 static const GLchar* fragment_shader_template = "#version 430 core\n" 5863 "#extension GL_ARB_enhanced_layouts : require\n" 5864 "\n" 5865 "INTERFACE" 5866 "\n" 5867 "void main()\n" 5868 "{\n" 5869 "CALCULATIONS" 5870 "\n" 5871 "ASSIGNMENTS" 5872 "}\n" 5873 "\n"; 5874 5875 // max_vertices is set to 3 for the test case "xfb_vertex_streams" declares 3 streams in geometry shader, 5876 // according to spec, max_vertices should be no less than 3 if there are 3 streams in GS. 5877 static const GLchar* geometry_shader_template = "#version 430 core\n" 5878 "#extension GL_ARB_enhanced_layouts : require\n" 5879 "\n" 5880 "layout(points) in;\n" 5881 "layout(points, max_vertices = 3) out;\n" 5882 "\n" 5883 "INTERFACE" 5884 "\n" 5885 "void main()\n" 5886 "{\n" 5887 "CALCULATIONS" 5888 "\n" 5889 "\n" 5890 "ASSIGNMENTS" 5891 " gl_Position = vec4(0, 0, 0, 1);\n" 5892 " EmitVertex();\n" 5893 "}\n" 5894 "\n"; 5895 5896 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n" 5897 "#extension GL_ARB_enhanced_layouts : require\n" 5898 "\n" 5899 "layout(vertices = 1) out;\n" 5900 "\n" 5901 "INTERFACE" 5902 "\n" 5903 "void main()\n" 5904 "{\n" 5905 "CALCULATIONS" 5906 "\n" 5907 "ASSIGNMENTS" 5908 "\n" 5909 " gl_TessLevelOuter[0] = 1.0;\n" 5910 " gl_TessLevelOuter[1] = 1.0;\n" 5911 " gl_TessLevelOuter[2] = 1.0;\n" 5912 " gl_TessLevelOuter[3] = 1.0;\n" 5913 " gl_TessLevelInner[0] = 1.0;\n" 5914 " gl_TessLevelInner[1] = 1.0;\n" 5915 "}\n" 5916 "\n"; 5917 5918 static const GLchar* tess_eval_shader_template = "#version 430 core\n" 5919 "#extension GL_ARB_enhanced_layouts : require\n" 5920 "\n" 5921 "layout(isolines, point_mode) in;\n" 5922 "\n" 5923 "INTERFACE" 5924 "\n" 5925 "void main()\n" 5926 "{\n" 5927 "CALCULATIONS" 5928 "\n" 5929 "ASSIGNMENTS" 5930 "}\n" 5931 "\n"; 5932 5933 static const GLchar* vertex_shader_template = "#version 430 core\n" 5934 "#extension GL_ARB_enhanced_layouts : require\n" 5935 "\n" 5936 "INTERFACE" 5937 "\n" 5938 "void main()\n" 5939 "{\n" 5940 "CALCULATIONS" 5941 "\n" 5942 "ASSIGNMENTS" 5943 "}\n" 5944 "\n"; 5945 5946 const GLchar* result = 0; 5947 5948 switch (stage) 5949 { 5950 case Utils::Shader::COMPUTE: 5951 result = compute_shader_template; 5952 break; 5953 case Utils::Shader::FRAGMENT: 5954 result = fragment_shader_template; 5955 break; 5956 case Utils::Shader::GEOMETRY: 5957 result = geometry_shader_template; 5958 break; 5959 case Utils::Shader::TESS_CTRL: 5960 result = tess_ctrl_shader_template; 5961 break; 5962 case Utils::Shader::TESS_EVAL: 5963 result = tess_eval_shader_template; 5964 break; 5965 case Utils::Shader::VERTEX: 5966 result = vertex_shader_template; 5967 break; 5968 default: 5969 TCU_FAIL("Invalid enum"); 5970 } 5971 5972 return result; 5973 } 5974 5975 /** Prepare buffer according to descriptor 5976 * 5977 * @param buffer Buffer to prepare 5978 * @param desc Descriptor 5979 **/ 5980 void BufferTestBase::prepareBuffer(Utils::Buffer& buffer, bufferDescriptor& desc) 5981 { 5982 GLsizeiptr size = 0; 5983 GLvoid* data = 0; 5984 5985 if (false == desc.m_initial_data.empty()) 5986 { 5987 size = desc.m_initial_data.size(); 5988 data = &desc.m_initial_data[0]; 5989 } 5990 else if (false == desc.m_expected_data.empty()) 5991 { 5992 size = desc.m_expected_data.size(); 5993 } 5994 5995 buffer.Init(desc.m_target, Utils::Buffer::StaticDraw, size, data); 5996 5997 if (bufferDescriptor::m_non_indexed != desc.m_index) 5998 { 5999 buffer.BindBase(desc.m_index); 6000 } 6001 else 6002 { 6003 buffer.Bind(); 6004 } 6005 } 6006 6007 /** Prepare collection of buffer 6008 * 6009 * @param descriptors Collection of descriptors 6010 * @param out_buffers Collection of buffers 6011 **/ 6012 void BufferTestBase::prepareBuffers(bufferDescriptor::Vector& descriptors, bufferCollection& out_buffers) 6013 { 6014 for (bufferDescriptor::Vector::iterator it = descriptors.begin(), end = descriptors.end(); end != it; ++it) 6015 { 6016 bufferCollection::pair pair; 6017 6018 pair.m_buffer = new Utils::Buffer(m_context); 6019 if (0 == pair.m_buffer) 6020 { 6021 TCU_FAIL("Memory allocation failed"); 6022 } 6023 6024 pair.m_descriptor = &(*it); 6025 6026 prepareBuffer(*pair.m_buffer, *pair.m_descriptor); 6027 6028 out_buffers.m_vector.push_back(pair); 6029 } 6030 } 6031 6032 /** Destructor 6033 * 6034 **/ 6035 BufferTestBase::bufferCollection::~bufferCollection() 6036 { 6037 for (Vector::iterator it = m_vector.begin(), end = m_vector.end(); end != it; ++it) 6038 { 6039 if (0 != it->m_buffer) 6040 { 6041 delete it->m_buffer; 6042 it->m_buffer = 0; 6043 } 6044 } 6045 } 6046 6047 /** Constructor 6048 * 6049 * @param context Test context 6050 * @param test_name Name of test 6051 * @param test_description Description of test 6052 **/ 6053 NegativeTestBase::NegativeTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description) 6054 : TestBase(context, test_name, test_description) 6055 { 6056 } 6057 6058 /** Selects if "compute" stage is relevant for test 6059 * 6060 * @param ignored 6061 * 6062 * @return true 6063 **/ 6064 bool NegativeTestBase::isComputeRelevant(GLuint /* test_case_index */) 6065 { 6066 return true; 6067 } 6068 6069 /** Selects if compilation failure is expected result 6070 * 6071 * @param ignored 6072 * 6073 * @return true 6074 **/ 6075 bool NegativeTestBase::isFailureExpected(GLuint /* test_case_index */) 6076 { 6077 return true; 6078 } 6079 6080 /** Runs test case 6081 * 6082 * @param test_case_index Id of test case 6083 * 6084 * @return true if test case pass, false otherwise 6085 **/ 6086 bool NegativeTestBase::testCase(GLuint test_case_index) 6087 { 6088 bool test_case_result = true; 6089 6090 /* Compute */ 6091 if (true == isComputeRelevant(test_case_index)) 6092 { 6093 const std::string& cs_source = getShaderSource(test_case_index, Utils::Shader::COMPUTE); 6094 bool is_build_error = false; 6095 const bool is_failure_expected = isFailureExpected(test_case_index); 6096 Utils::Program program(m_context); 6097 6098 try 6099 { 6100 program.Init(cs_source, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */, 6101 false /* separable */); 6102 } 6103 catch (Utils::Shader::InvalidSourceException& exc) 6104 { 6105 if (false == is_failure_expected) 6106 { 6107 m_context.getTestContext().getLog() 6108 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage; 6109 exc.log(m_context); 6110 } 6111 6112 #if DEBUG_NEG_LOG_ERROR 6113 6114 else 6115 { 6116 m_context.getTestContext().getLog() 6117 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: " 6118 << tcu::TestLog::EndMessage; 6119 exc.log(m_context); 6120 } 6121 6122 #endif /* DEBUG_NEG_LOG_ERROR */ 6123 6124 is_build_error = true; 6125 } 6126 catch (Utils::Program::BuildException& exc) 6127 { 6128 if (false == is_failure_expected) 6129 { 6130 m_context.getTestContext().getLog() 6131 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage; 6132 exc.log(m_context); 6133 } 6134 6135 #if DEBUG_NEG_LOG_ERROR 6136 6137 else 6138 { 6139 m_context.getTestContext().getLog() 6140 << tcu::TestLog::Message 6141 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage; 6142 exc.log(m_context); 6143 } 6144 6145 #endif /* DEBUG_NEG_LOG_ERROR */ 6146 6147 is_build_error = true; 6148 } 6149 6150 if (is_build_error != is_failure_expected) 6151 { 6152 if (!is_build_error) 6153 { 6154 m_context.getTestContext().getLog() 6155 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage; 6156 Utils::Shader::LogSource(m_context, cs_source, Utils::Shader::COMPUTE); 6157 } 6158 test_case_result = false; 6159 } 6160 } 6161 else /* Draw */ 6162 { 6163 const std::string& fs_source = getShaderSource(test_case_index, Utils::Shader::FRAGMENT); 6164 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY); 6165 bool is_build_error = false; 6166 const bool is_failure_expected = isFailureExpected(test_case_index); 6167 Utils::Program program(m_context); 6168 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL); 6169 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL); 6170 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX); 6171 6172 try 6173 { 6174 program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source, false /* separable */); 6175 } 6176 catch (Utils::Shader::InvalidSourceException& exc) 6177 { 6178 if (false == is_failure_expected) 6179 { 6180 m_context.getTestContext().getLog() 6181 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage; 6182 exc.log(m_context); 6183 } 6184 6185 #if DEBUG_NEG_LOG_ERROR 6186 6187 else 6188 { 6189 m_context.getTestContext().getLog() 6190 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: " 6191 << tcu::TestLog::EndMessage; 6192 exc.log(m_context); 6193 } 6194 6195 #endif /* DEBUG_NEG_LOG_ERROR */ 6196 6197 is_build_error = true; 6198 } 6199 catch (Utils::Program::BuildException& exc) 6200 { 6201 if (false == is_failure_expected) 6202 { 6203 m_context.getTestContext().getLog() 6204 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage; 6205 exc.log(m_context); 6206 } 6207 6208 #if DEBUG_NEG_LOG_ERROR 6209 6210 else 6211 { 6212 m_context.getTestContext().getLog() 6213 << tcu::TestLog::Message 6214 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage; 6215 exc.log(m_context); 6216 } 6217 6218 #endif /* DEBUG_NEG_LOG_ERROR */ 6219 6220 is_build_error = true; 6221 } 6222 6223 if (is_build_error != is_failure_expected) 6224 { 6225 if (!is_build_error) 6226 { 6227 m_context.getTestContext().getLog() 6228 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage; 6229 Utils::Shader::LogSource(m_context, vs_source, Utils::Shader::VERTEX); 6230 Utils::Shader::LogSource(m_context, tcs_source, Utils::Shader::TESS_CTRL); 6231 Utils::Shader::LogSource(m_context, tes_source, Utils::Shader::TESS_EVAL); 6232 Utils::Shader::LogSource(m_context, gs_source, Utils::Shader::GEOMETRY); 6233 Utils::Shader::LogSource(m_context, fs_source, Utils::Shader::FRAGMENT); 6234 } 6235 test_case_result = false; 6236 } 6237 } 6238 6239 return test_case_result; 6240 } 6241 6242 /* Constants used by TextureTestBase */ 6243 const glw::GLuint TextureTestBase::m_width = 16; 6244 const glw::GLuint TextureTestBase::m_height = 16; 6245 6246 /** Constructor 6247 * 6248 * @param context Test context 6249 * @param test_name Name of test 6250 * @param test_description Description of test 6251 **/ 6252 TextureTestBase::TextureTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description) 6253 : TestBase(context, test_name, test_description) 6254 { 6255 } 6256 6257 /** Get locations for all inputs with automatic_location 6258 * 6259 * @param program Program object 6260 * @param program_interface Interface of program 6261 **/ 6262 void TextureTestBase::prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface) 6263 { 6264 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 6265 6266 Utils::Variable::PtrVector& inputs = si.m_inputs; 6267 6268 for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it) 6269 { 6270 /* Test does not specify location, query value and set */ 6271 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location) 6272 { 6273 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT); 6274 GLint location = 0; 6275 6276 program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location); 6277 6278 (*it)->m_descriptor.m_expected_location = location; 6279 } 6280 } 6281 } 6282 6283 /** Verifies contents of drawn image 6284 * 6285 * @param ignored 6286 * @param color_0 Verified image 6287 * 6288 * @return true if image is filled with 1, false otherwise 6289 **/ 6290 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& color_0) 6291 { 6292 static const GLuint size = m_width * m_height; 6293 static const GLuint expected_color = 1; 6294 6295 std::vector<GLuint> data; 6296 data.resize(size); 6297 6298 color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]); 6299 6300 for (GLuint i = 0; i < size; ++i) 6301 { 6302 const GLuint color = data[i]; 6303 6304 if (expected_color != color) 6305 { 6306 m_context.getTestContext().getLog() << tcu::TestLog::Message << "R32UI[" << i << "]:" << color 6307 << tcu::TestLog::EndMessage; 6308 return false; 6309 } 6310 } 6311 6312 return true; 6313 } 6314 6315 /** Execute dispatch compute for 16x16x1 6316 * 6317 * @param ignored 6318 **/ 6319 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */) 6320 { 6321 const Functions& gl = m_context.getRenderContext().getFunctions(); 6322 6323 gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */); 6324 GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute"); 6325 } 6326 6327 /** Execute drawArrays for single vertex 6328 * 6329 * @param ignored 6330 **/ 6331 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */) 6332 { 6333 const Functions& gl = m_context.getRenderContext().getFunctions(); 6334 6335 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 6336 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 6337 } 6338 6339 /** Prepare code snippet that will pass in variables to out variables 6340 * 6341 * @param ignored 6342 * @param varying_passthrough Collection of connections between in and out variables 6343 * @param stage Shader stage 6344 * 6345 * @return Code that pass in variables to next stage 6346 **/ 6347 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */, 6348 Utils::VaryingPassthrough& varying_passthrough, Utils::Shader::STAGES stage) 6349 { 6350 static const GLchar* separator = "\n "; 6351 6352 /* Skip for compute shader */ 6353 if (Utils::Shader::COMPUTE == stage) 6354 { 6355 return ""; 6356 } 6357 6358 Utils::VaryingConnection::Vector& vector = varying_passthrough.Get(stage); 6359 6360 std::string result = Utils::g_list; 6361 size_t position = 0; 6362 6363 for (GLuint i = 0; i < vector.size(); ++i) 6364 { 6365 6366 Utils::VaryingConnection& connection = vector[i]; 6367 6368 Utils::Variable* in = connection.m_in; 6369 Utils::Variable* out = connection.m_out; 6370 6371 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT); 6372 Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT); 6373 6374 const std::string passthrough = 6375 getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour); 6376 6377 Utils::insertElementOfList(passthrough.c_str(), separator, position, result); 6378 } 6379 6380 Utils::endList("", position, result); 6381 6382 return result; 6383 } 6384 6385 /** Basic implementation of method getProgramInterface 6386 * 6387 * @param ignored 6388 * @param ignored 6389 * @param ignored 6390 **/ 6391 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */, 6392 Utils::ProgramInterface& /* program_interface */, 6393 Utils::VaryingPassthrough& /* varying_passthrough */) 6394 { 6395 } 6396 6397 /** Prepare code snippet that will verify in and uniform variables 6398 * 6399 * @param ignored 6400 * @param program_interface Interface of program 6401 * @param stage Shader stage 6402 * 6403 * @return Code that verify variables 6404 **/ 6405 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */, 6406 Utils::ProgramInterface& program_interface, 6407 Utils::Shader::STAGES stage) 6408 { 6409 static const GLchar* separator = " ||\n "; 6410 6411 std::string verification = "if (LIST)\n" 6412 " {\n" 6413 " result = 0u;\n" 6414 " }\n"; 6415 6416 /* Get flavour of in and out variables */ 6417 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT); 6418 6419 /* Get interface for shader stage */ 6420 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage); 6421 6422 /* There are no varialbes to verify */ 6423 if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size())) 6424 { 6425 return ""; 6426 } 6427 6428 /* For each in variable insert verification code */ 6429 size_t position = 0; 6430 6431 for (GLuint i = 0; i < si.m_inputs.size(); ++i) 6432 { 6433 const Utils::Variable& var = *si.m_inputs[i]; 6434 const std::string& var_verification = getVariableVerification("", var.m_data, var.m_descriptor, in_flavour); 6435 6436 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification); 6437 } 6438 6439 /* For each unifrom variable insert verification code */ 6440 for (GLuint i = 0; i < si.m_uniforms.size(); ++i) 6441 { 6442 const Utils::Variable& var = *si.m_uniforms[i]; 6443 const std::string& var_verification = 6444 getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC); 6445 6446 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification); 6447 } 6448 6449 /* For each ssb variable insert verification code */ 6450 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i) 6451 { 6452 const Utils::Variable& var = *si.m_ssb_blocks[i]; 6453 const std::string& var_verification = 6454 getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC); 6455 6456 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification); 6457 } 6458 6459 Utils::endList("", position, verification); 6460 6461 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE 6462 6463 { 6464 GLchar buffer[16]; 6465 sprintf(buffer, "%d", stage + 10); 6466 Utils::replaceToken("0u", position, buffer, verification); 6467 } 6468 6469 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE 6470 6471 if (Utils::Shader::VERTEX == stage) 6472 { 6473 Utils::replaceToken("0u", position, "in_vs_first.x", verification); 6474 } 6475 else 6476 { 6477 Utils::replaceToken("0u", position, "31u", verification); 6478 } 6479 6480 #endif 6481 6482 /* Done */ 6483 return verification; 6484 } 6485 6486 /** Selects if "compute" stage is relevant for test 6487 * 6488 * @param ignored 6489 * 6490 * @return true 6491 **/ 6492 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */) 6493 { 6494 return true; 6495 } 6496 6497 /** Selects if "draw" stages are relevant for test 6498 * 6499 * @param ignored 6500 * 6501 * @return true 6502 **/ 6503 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */) 6504 { 6505 return true; 6506 } 6507 6508 /** Prepare code that will do assignment of single in to single out 6509 * 6510 * @param in_parent_name Name of parent in variable 6511 * @param in_variable Descriptor of in variable 6512 * @param in_flavour Flavoud of in variable 6513 * @param out_parent_name Name of parent out variable 6514 * @param out_variable Descriptor of out variable 6515 * @param out_flavour Flavoud of out variable 6516 * 6517 * @return Code that does OUT = IN 6518 **/ 6519 std::string TextureTestBase::getVariablePassthrough(const std::string& in_parent_name, 6520 const Utils::Variable::Descriptor& in_variable, 6521 Utils::Variable::FLAVOUR in_flavour, 6522 const std::string& out_parent_name, 6523 const Utils::Variable::Descriptor& out_variable, 6524 Utils::Variable::FLAVOUR out_flavour) 6525 { 6526 bool done = false; 6527 GLuint index = 0; 6528 GLuint member_index = 0; 6529 size_t position = 0; 6530 std::string result = Utils::g_list; 6531 static const GLchar* separator = ";\n "; 6532 6533 /* For each member of each array element */ 6534 do 6535 { 6536 const std::string in_name = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index); 6537 const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index); 6538 std::string passthrough; 6539 6540 /* Prepare verification */ 6541 if (Utils::Variable::BUILTIN == in_variable.m_type) 6542 { 6543 size_t pass_position = 0; 6544 6545 passthrough = "OUT = IN;"; 6546 6547 Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough); 6548 Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough); 6549 6550 /* Increment index */ 6551 ++index; 6552 } 6553 else 6554 { 6555 const Utils::Interface* in_interface = in_variable.m_interface; 6556 const Utils::Interface* out_interface = out_variable.m_interface; 6557 6558 if ((0 == in_interface) || (0 == out_interface)) 6559 { 6560 TCU_FAIL("Nullptr"); 6561 } 6562 6563 const Utils::Variable::Descriptor& in_member = in_interface->m_members[member_index]; 6564 const Utils::Variable::Descriptor& out_member = out_interface->m_members[member_index]; 6565 6566 passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member, 6567 Utils::Variable::BASIC); 6568 6569 /* Increment member_index */ 6570 ++member_index; 6571 6572 /* Increment index and reset member_index if all members were processed */ 6573 if (in_interface->m_members.size() == member_index) 6574 { 6575 ++index; 6576 member_index = 0; 6577 } 6578 } 6579 6580 /* Check if loop should end */ 6581 if ((index >= in_variable.m_n_array_elements) && (0 == member_index)) 6582 { 6583 done = true; 6584 } 6585 6586 Utils::insertElementOfList(passthrough.c_str(), separator, position, result); 6587 6588 } while (true != done); 6589 6590 Utils::endList("", position, result); 6591 6592 /* Done */ 6593 return result; 6594 } 6595 6596 /** Get verification of single variable 6597 * 6598 * @param parent_name Name of parent variable 6599 * @param data Data that should be used as EXPECTED 6600 * @param variable Descriptor of variable 6601 * @param flavour Flavour of variable 6602 * 6603 * @return Code that does (EXPECTED != VALUE) || 6604 **/ 6605 std::string TextureTestBase::getVariableVerification(const std::string& parent_name, const GLvoid* data, 6606 const Utils::Variable::Descriptor& variable, 6607 Utils::Variable::FLAVOUR flavour) 6608 { 6609 static const GLchar* logic_op = " ||\n "; 6610 const GLuint n_elements = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements; 6611 size_t position = 0; 6612 std::string result = Utils::g_list; 6613 GLint stride = variable.m_expected_stride_of_element; 6614 6615 /* For each each array element */ 6616 for (GLuint element = 0; element < n_elements; ++element) 6617 { 6618 const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element); 6619 6620 /* Calculate data pointer */ 6621 GLvoid* data_ptr = (GLvoid*)((GLubyte*)data + element * stride); 6622 6623 /* Prepare verification */ 6624 if (Utils::Variable::BUILTIN == variable.m_type) 6625 { 6626 const std::string& expected = variable.m_builtin.GetGLSLConstructor(data_ptr); 6627 std::string verification; 6628 size_t verification_position = 0; 6629 6630 verification = "(EXPECTED != NAME)"; 6631 6632 Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification); 6633 Utils::replaceToken("NAME", verification_position, name.c_str(), verification); 6634 6635 Utils::insertElementOfList(verification.c_str(), logic_op, position, result); 6636 } 6637 else 6638 { 6639 const Utils::Interface* interface = variable.m_interface; 6640 6641 if (0 == interface) 6642 { 6643 TCU_FAIL("Nullptr"); 6644 } 6645 6646 const GLuint n_members = static_cast<GLuint>(interface->m_members.size()); 6647 6648 /* for each member */ 6649 for (GLuint member_index = 0; member_index < n_members; ++member_index) 6650 { 6651 const Utils::Variable::Descriptor& member = interface->m_members[member_index]; 6652 6653 /* Get verification of member */ 6654 const std::string& verification = 6655 getVariableVerification(name, (GLubyte*)data_ptr + member.m_offset, member, Utils::Variable::BASIC); 6656 6657 Utils::insertElementOfList(verification.c_str(), logic_op, position, result); 6658 } 6659 } 6660 } 6661 6662 Utils::endList("", position, result); 6663 6664 return result; 6665 } 6666 6667 /** Prepare attributes, vertex array object and array buffer 6668 * 6669 * @param test_case_index Index of test case 6670 * @param program_interface Interface of program 6671 * @param buffer Array buffer 6672 * @param vao Vertex array object 6673 **/ 6674 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface& program_interface, 6675 Utils::Buffer& buffer, Utils::VertexArray& vao) 6676 { 6677 bool use_component_qualifier = useComponentQualifier(test_case_index); 6678 6679 /* Get shader interface */ 6680 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 6681 6682 /* Bind vao and buffer */ 6683 vao.Bind(); 6684 buffer.Bind(); 6685 6686 /* Skip if there are no input variables in vertex shader */ 6687 if (0 == si.m_inputs.size()) 6688 { 6689 return; 6690 } 6691 6692 /* Calculate vertex stride and check */ 6693 GLint vertex_stride = 0; 6694 6695 for (GLuint i = 0; i < si.m_inputs.size(); ++i) 6696 { 6697 Utils::Variable& variable = *si.m_inputs[i]; 6698 6699 GLint variable_size = static_cast<GLuint>(variable.m_data_size); 6700 6701 GLint ends_at = variable_size + variable.m_descriptor.m_offset; 6702 6703 vertex_stride = std::max(vertex_stride, ends_at); 6704 } 6705 6706 /* Prepare buffer data and set up vao */ 6707 std::vector<GLubyte> buffer_data; 6708 buffer_data.resize(vertex_stride); 6709 6710 GLubyte* ptr = &buffer_data[0]; 6711 6712 for (GLuint i = 0; i < si.m_inputs.size(); ++i) 6713 { 6714 Utils::Variable& variable = *si.m_inputs[i]; 6715 6716 memcpy(ptr + variable.m_descriptor.m_offset, variable.m_data, variable.m_data_size); 6717 6718 if (false == use_component_qualifier) 6719 { 6720 vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin, 6721 variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized, 6722 variable.GetStride(), (GLvoid*)(intptr_t)variable.m_descriptor.m_offset); 6723 } 6724 else if (0 == variable.m_descriptor.m_expected_component) 6725 { 6726 /* Components can only be applied to vectors. 6727 Assumption that test use all 4 components */ 6728 const Utils::Type& type = 6729 Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type, 1 /* n_columns */, 4 /* n_rows */); 6730 6731 vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements, 6732 variable.m_descriptor.m_normalized, variable.GetStride(), 6733 (GLvoid*)(intptr_t)variable.m_descriptor.m_offset); 6734 } 6735 } 6736 6737 /* Update buffer */ 6738 buffer.Data(Utils::Buffer::StaticDraw, vertex_stride, ptr); 6739 } 6740 6741 /** Get locations for all outputs with automatic_location 6742 * 6743 * @param program Program object 6744 * @param program_interface Interface of program 6745 **/ 6746 void TextureTestBase::prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface) 6747 { 6748 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT); 6749 Utils::Variable::PtrVector& outputs = si.m_outputs; 6750 6751 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it) 6752 { 6753 /* Test does not specify location, query value and set */ 6754 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location) 6755 { 6756 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT); 6757 GLint location = 0; 6758 6759 program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location); 6760 6761 (*it)->m_descriptor.m_expected_location = location; 6762 } 6763 } 6764 } 6765 6766 /** Prepare framebuffer with single texture as color attachment 6767 * 6768 * @param framebuffer Framebuffer 6769 * @param color_0_texture Texture that will used as color attachment 6770 **/ 6771 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture) 6772 { 6773 /* Prepare data */ 6774 std::vector<GLuint> texture_data; 6775 texture_data.resize(m_width * m_height); 6776 6777 for (GLuint i = 0; i < texture_data.size(); ++i) 6778 { 6779 texture_data[i] = 0x20406080; 6780 } 6781 6782 /* Prepare texture */ 6783 color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, 6784 &texture_data[0]); 6785 6786 /* Prepare framebuffer */ 6787 framebuffer.Init(); 6788 framebuffer.Bind(); 6789 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height); 6790 6791 framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); 6792 framebuffer.Clear(GL_COLOR_BUFFER_BIT); 6793 } 6794 6795 /** Prepare iamge unit for compute shader 6796 * 6797 * @param location Uniform location 6798 * @param image_texture Texture that will used as color attachment 6799 **/ 6800 void TextureTestBase::prepareImage(GLint location, Utils::Texture& image_texture) const 6801 { 6802 static const GLuint image_unit = 0; 6803 6804 std::vector<GLuint> texture_data; 6805 texture_data.resize(m_width * m_height); 6806 6807 for (GLuint i = 0; i < texture_data.size(); ++i) 6808 { 6809 texture_data[i] = 0x20406080; 6810 } 6811 6812 image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, 6813 &texture_data[0]); 6814 6815 const Functions& gl = m_context.getRenderContext().getFunctions(); 6816 6817 gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */, 6818 GL_WRITE_ONLY, GL_R32UI); 6819 GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture"); 6820 6821 Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit); 6822 } 6823 6824 /** Basic implementation 6825 * 6826 * @param ignored 6827 * @param si Shader interface 6828 * @param program Program 6829 * @param cs_buffer Buffer for ssb blocks 6830 **/ 6831 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program, 6832 Utils::Buffer& buffer) 6833 { 6834 /* Skip if there are no input variables in vertex shader */ 6835 if (0 == si.m_ssb_blocks.size()) 6836 { 6837 return; 6838 } 6839 6840 /* Calculate vertex stride */ 6841 GLint ssbs_stride = 0; 6842 6843 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i) 6844 { 6845 Utils::Variable& variable = *si.m_ssb_blocks[i]; 6846 6847 if (false == variable.IsBlock()) 6848 { 6849 continue; 6850 } 6851 6852 GLint variable_stride = variable.GetStride(); 6853 6854 GLint ends_at = variable_stride + variable.m_descriptor.m_offset; 6855 6856 ssbs_stride = std::max(ssbs_stride, ends_at); 6857 } 6858 6859 /* Set active program */ 6860 program.Use(); 6861 6862 /* Allocate */ 6863 buffer.Bind(); 6864 buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0); 6865 6866 /* Set up uniforms */ 6867 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i) 6868 { 6869 Utils::Variable& variable = *si.m_ssb_blocks[i]; 6870 6871 /* prepareUnifor should work fine for ssb blocks */ 6872 prepareUniform(program, variable, buffer); 6873 } 6874 } 6875 6876 /** Basic implementation 6877 * 6878 * @param test_case_index Test case index 6879 * @param program_interface Program interface 6880 * @param program Program 6881 * @param cs_buffer Buffer for compute shader stage 6882 **/ 6883 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface, 6884 Utils::Program& program, Utils::Buffer& cs_buffer) 6885 { 6886 cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0); 6887 6888 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE); 6889 6890 prepareSSBs(test_case_index, cs, program, cs_buffer); 6891 6892 cs_buffer.BindBase(Utils::Shader::COMPUTE); 6893 } 6894 6895 /** Basic implementation 6896 * 6897 * @param test_case_index Test case index 6898 * @param program_interface Program interface 6899 * @param program Program 6900 * @param fs_buffer Buffer for fragment shader stage 6901 * @param gs_buffer Buffer for geometry shader stage 6902 * @param tcs_buffer Buffer for tessellation control shader stage 6903 * @param tes_buffer Buffer for tessellation evaluation shader stage 6904 * @param vs_buffer Buffer for vertex shader stage 6905 **/ 6906 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface, 6907 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer, 6908 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer) 6909 { 6910 fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0); 6911 gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0); 6912 tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0); 6913 tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0); 6914 vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0); 6915 6916 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT); 6917 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY); 6918 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL); 6919 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL); 6920 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 6921 6922 prepareSSBs(test_case_index, fs, program, fs_buffer); 6923 prepareSSBs(test_case_index, gs, program, gs_buffer); 6924 prepareSSBs(test_case_index, tcs, program, tcs_buffer); 6925 prepareSSBs(test_case_index, tes, program, tes_buffer); 6926 prepareSSBs(test_case_index, vs, program, vs_buffer); 6927 6928 fs_buffer.BindBase(Utils::Shader::FRAGMENT); 6929 gs_buffer.BindBase(Utils::Shader::GEOMETRY); 6930 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL); 6931 tes_buffer.BindBase(Utils::Shader::TESS_EVAL); 6932 vs_buffer.BindBase(Utils::Shader::VERTEX); 6933 } 6934 6935 /** Updates buffer data with variable 6936 * 6937 * @param program Program object 6938 * @param variable Variable 6939 * @param buffer Buffer 6940 **/ 6941 void TextureTestBase::prepareUniform(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer) 6942 { 6943 const Functions& gl = m_context.getRenderContext().getFunctions(); 6944 6945 GLsizei count = variable.m_descriptor.m_n_array_elements; 6946 if (0 == count) 6947 { 6948 count = 1; 6949 } 6950 6951 if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type) 6952 { 6953 program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location, 6954 variable.m_data); 6955 } 6956 else 6957 { 6958 const bool is_block = variable.IsBlock(); 6959 6960 if (false == is_block) 6961 { 6962 TCU_FAIL("Not implemented"); 6963 } 6964 else 6965 { 6966 buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count, 6967 variable.m_data); 6968 } 6969 } 6970 } 6971 6972 /** Basic implementation 6973 * 6974 * @param ignored 6975 * @param si Shader interface 6976 * @param program Program 6977 * @param cs_buffer Buffer for uniform blocks 6978 **/ 6979 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program, 6980 Utils::Buffer& buffer) 6981 { 6982 /* Skip if there are no input variables in vertex shader */ 6983 if (0 == si.m_uniforms.size()) 6984 { 6985 return; 6986 } 6987 6988 /* Calculate vertex stride */ 6989 GLint uniforms_stride = 0; 6990 6991 for (GLuint i = 0; i < si.m_uniforms.size(); ++i) 6992 { 6993 Utils::Variable& variable = *si.m_uniforms[i]; 6994 6995 if (false == variable.IsBlock()) 6996 { 6997 continue; 6998 } 6999 7000 GLint variable_stride = variable.GetStride(); 7001 7002 GLint ends_at = variable_stride + variable.m_descriptor.m_offset; 7003 7004 uniforms_stride = std::max(uniforms_stride, ends_at); 7005 } 7006 7007 /* Set active program */ 7008 program.Use(); 7009 7010 /* Allocate */ 7011 buffer.Bind(); 7012 buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0); 7013 7014 /* Set up uniforms */ 7015 for (GLuint i = 0; i < si.m_uniforms.size(); ++i) 7016 { 7017 Utils::Variable& variable = *si.m_uniforms[i]; 7018 7019 prepareUniform(program, variable, buffer); 7020 } 7021 } 7022 7023 /** Basic implementation 7024 * 7025 * @param test_case_index Test case index 7026 * @param program_interface Program interface 7027 * @param program Program 7028 * @param cs_buffer Buffer for compute shader stage 7029 **/ 7030 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface, 7031 Utils::Program& program, Utils::Buffer& cs_buffer) 7032 { 7033 cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7034 7035 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE); 7036 7037 prepareUniforms(test_case_index, cs, program, cs_buffer); 7038 7039 cs_buffer.BindBase(Utils::Shader::COMPUTE); 7040 } 7041 7042 /** Basic implementation 7043 * 7044 * @param test_case_index Test case index 7045 * @param program_interface Program interface 7046 * @param program Program 7047 * @param fs_buffer Buffer for fragment shader stage 7048 * @param gs_buffer Buffer for geometry shader stage 7049 * @param tcs_buffer Buffer for tessellation control shader stage 7050 * @param tes_buffer Buffer for tessellation evaluation shader stage 7051 * @param vs_buffer Buffer for vertex shader stage 7052 **/ 7053 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface, 7054 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer, 7055 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer) 7056 { 7057 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7058 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7059 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7060 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7061 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7062 7063 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT); 7064 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY); 7065 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL); 7066 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL); 7067 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 7068 7069 prepareUniforms(test_case_index, fs, program, fs_buffer); 7070 prepareUniforms(test_case_index, gs, program, gs_buffer); 7071 prepareUniforms(test_case_index, tcs, program, tcs_buffer); 7072 prepareUniforms(test_case_index, tes, program, tes_buffer); 7073 prepareUniforms(test_case_index, vs, program, vs_buffer); 7074 7075 fs_buffer.BindBase(Utils::Shader::FRAGMENT); 7076 gs_buffer.BindBase(Utils::Shader::GEOMETRY); 7077 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL); 7078 tes_buffer.BindBase(Utils::Shader::TESS_EVAL); 7079 vs_buffer.BindBase(Utils::Shader::VERTEX); 7080 } 7081 7082 /** Basic implementation 7083 * 7084 * @param test_case_index Test case index 7085 * @param program_interface Program interface 7086 * @param program Program 7087 * @param fs_buffer Buffer for fragment shader stage 7088 * @param gs_buffer Buffer for geometry shader stage 7089 * @param tcs_buffer Buffer for tessellation control shader stage 7090 * @param tes_buffer Buffer for tessellation evaluation shader stage 7091 * @param vs_buffer Buffer for vertex shader stage 7092 **/ 7093 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface, 7094 Utils::Program& fs_program, Utils::Program& gs_program, 7095 Utils::Program& tcs_program, Utils::Program& tes_program, 7096 Utils::Program& vs_program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer, 7097 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer) 7098 { 7099 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7100 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7101 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7102 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7103 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0); 7104 7105 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT); 7106 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY); 7107 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL); 7108 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL); 7109 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 7110 7111 prepareUniforms(test_case_index, fs, fs_program, fs_buffer); 7112 fs_buffer.BindBase(Utils::Shader::FRAGMENT); 7113 7114 prepareUniforms(test_case_index, gs, gs_program, gs_buffer); 7115 gs_buffer.BindBase(Utils::Shader::GEOMETRY); 7116 7117 prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer); 7118 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL); 7119 7120 prepareUniforms(test_case_index, tes, tes_program, tes_buffer); 7121 tes_buffer.BindBase(Utils::Shader::TESS_EVAL); 7122 7123 prepareUniforms(test_case_index, vs, vs_program, vs_buffer); 7124 vs_buffer.BindBase(Utils::Shader::VERTEX); 7125 } 7126 7127 /** Prepare source for shader 7128 * 7129 * @param test_case_index Index of test case 7130 * @param program_interface Interface of program 7131 * @param varying_passthrough Collection of connection between in and out variables 7132 * @param stage Shader stage 7133 * 7134 * @return Source of shader 7135 **/ 7136 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface& program_interface, 7137 Utils::VaryingPassthrough& varying_passthrough, 7138 Utils::Shader::STAGES stage) 7139 { 7140 /* Get strings */ 7141 const GLchar* shader_template = getShaderTemplate(stage); 7142 const std::string& shader_interface = program_interface.GetInterfaceForStage(stage); 7143 7144 const std::string& verification = getVerificationSnippet(test_case_index, program_interface, stage); 7145 7146 const std::string& passthrough = getPassSnippet(test_case_index, varying_passthrough, stage); 7147 7148 const GLchar* per_vertex = ""; 7149 7150 std::string source = shader_template; 7151 size_t position = 0; 7152 7153 /* Replace tokens in template */ 7154 if (Utils::Shader::GEOMETRY == stage) 7155 { 7156 if (false == useMonolithicProgram(test_case_index)) 7157 { 7158 per_vertex = "out gl_PerVertex {\n" 7159 "vec4 gl_Position;\n" 7160 "};\n" 7161 "\n"; 7162 } 7163 7164 Utils::replaceToken("PERVERTEX", position, per_vertex, source); 7165 } 7166 7167 Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source); 7168 Utils::replaceToken("VERIFICATION", position, verification.c_str(), source); 7169 7170 if (false == verification.empty()) 7171 { 7172 Utils::replaceAllTokens("ELSE", " else ", source); 7173 } 7174 else 7175 { 7176 Utils::replaceAllTokens("ELSE", "", source); 7177 } 7178 7179 Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source); 7180 7181 /* Done */ 7182 return source; 7183 } 7184 7185 /** Returns template of shader for given stage 7186 * 7187 * @param stage Shade stage 7188 * 7189 * @return Proper template 7190 **/ 7191 const GLchar* TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage) 7192 { 7193 7194 static const GLchar* compute_shader_template = 7195 "#version 430 core\n" 7196 "#extension GL_ARB_enhanced_layouts : require\n" 7197 "\n" 7198 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 7199 "\n" 7200 "writeonly uniform uimage2D uni_image;\n" 7201 "\n" 7202 "INTERFACE" 7203 "\n" 7204 "void main()\n" 7205 "{\n" 7206 " uint result = 1u;\n" 7207 "\n" 7208 " VERIFICATION" 7209 "\n" 7210 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n" 7211 "}\n" 7212 "\n"; 7213 7214 static const GLchar* fragment_shader_template = "#version 430 core\n" 7215 "#extension GL_ARB_enhanced_layouts : require\n" 7216 "\n" 7217 "flat in uint gs_fs_result;\n" 7218 " out uint fs_out_result;\n" 7219 "\n" 7220 "INTERFACE" 7221 "\n" 7222 "void main()\n" 7223 "{\n" 7224 " uint result = 1u;\n" 7225 "\n" 7226 " if (1u != gs_fs_result)\n" 7227 " {\n" 7228 " result = gs_fs_result;\n" 7229 " }\n" 7230 "ELSEVERIFICATION" 7231 "\n" 7232 " fs_out_result = result;\n" 7233 " PASSTHROUGH\n" 7234 "}\n" 7235 "\n"; 7236 7237 static const GLchar* geometry_shader_template = 7238 "#version 430 core\n" 7239 "#extension GL_ARB_enhanced_layouts : require\n" 7240 "\n" 7241 "layout(points) in;\n" 7242 "layout(triangle_strip, max_vertices = 4) out;\n" 7243 "\n" 7244 " in uint tes_gs_result[];\n" 7245 "flat out uint gs_fs_result;\n" 7246 "\n" 7247 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */ 7248 "INTERFACE" 7249 "\n" 7250 "void main()\n" 7251 "{\n" 7252 " uint result = 1u;\n" 7253 "\n" 7254 " if (1u != tes_gs_result[0])\n" 7255 " {\n" 7256 " result = tes_gs_result[0];\n" 7257 " }\n" 7258 "ELSEVERIFICATION" 7259 "\n" 7260 " gs_fs_result = result;\n" 7261 " PASSTHROUGH\n" 7262 " gl_Position = vec4(-1, -1, 0, 1);\n" 7263 " EmitVertex();\n" 7264 " gs_fs_result = result;\n" 7265 " PASSTHROUGH\n" 7266 " gl_Position = vec4(-1, 1, 0, 1);\n" 7267 " EmitVertex();\n" 7268 " gs_fs_result = result;\n" 7269 " PASSTHROUGH\n" 7270 " gl_Position = vec4(1, -1, 0, 1);\n" 7271 " EmitVertex();\n" 7272 " gs_fs_result = result;\n" 7273 " PASSTHROUGH\n" 7274 " gl_Position = vec4(1, 1, 0, 1);\n" 7275 " EmitVertex();\n" 7276 "}\n" 7277 "\n"; 7278 7279 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n" 7280 "#extension GL_ARB_enhanced_layouts : require\n" 7281 "\n" 7282 "layout(vertices = 1) out;\n" 7283 "\n" 7284 "in uint vs_tcs_result[];\n" 7285 "out uint tcs_tes_result[];\n" 7286 "\n" 7287 "INTERFACE" 7288 "\n" 7289 "void main()\n" 7290 "{\n" 7291 " uint result = 1u;\n" 7292 "\n" 7293 " if (1u != vs_tcs_result[gl_InvocationID])\n" 7294 " {\n" 7295 " result = vs_tcs_result[gl_InvocationID];\n" 7296 " }\n" 7297 "ELSEVERIFICATION" 7298 "\n" 7299 " tcs_tes_result[gl_InvocationID] = result;\n" 7300 "\n" 7301 " PASSTHROUGH\n" 7302 "\n" 7303 " gl_TessLevelOuter[0] = 1.0;\n" 7304 " gl_TessLevelOuter[1] = 1.0;\n" 7305 " gl_TessLevelOuter[2] = 1.0;\n" 7306 " gl_TessLevelOuter[3] = 1.0;\n" 7307 " gl_TessLevelInner[0] = 1.0;\n" 7308 " gl_TessLevelInner[1] = 1.0;\n" 7309 "}\n" 7310 "\n"; 7311 7312 static const GLchar* tess_eval_shader_template = "#version 430 core\n" 7313 "#extension GL_ARB_enhanced_layouts : require\n" 7314 "\n" 7315 "layout(isolines, point_mode) in;\n" 7316 "\n" 7317 "in uint tcs_tes_result[];\n" 7318 "out uint tes_gs_result;\n" 7319 "\n" 7320 "INTERFACE" 7321 "\n" 7322 "void main()\n" 7323 "{\n" 7324 " uint result = 1u;\n" 7325 "\n" 7326 " if (1 != tcs_tes_result[0])\n" 7327 " {\n" 7328 " result = tcs_tes_result[0];\n" 7329 " }\n" 7330 "ELSEVERIFICATION" 7331 "\n" 7332 " tes_gs_result = result;\n" 7333 "\n" 7334 " PASSTHROUGH\n" 7335 "}\n" 7336 "\n"; 7337 7338 static const GLchar* vertex_shader_template = "#version 430 core\n" 7339 "#extension GL_ARB_enhanced_layouts : require\n" 7340 "\n" 7341 "out uint vs_tcs_result;\n" 7342 "\n" 7343 "INTERFACE" 7344 "\n" 7345 "void main()\n" 7346 "{\n" 7347 " uint result = 1u;\n" 7348 "\n" 7349 " VERIFICATION\n" 7350 "\n" 7351 " vs_tcs_result = result;\n" 7352 "\n" 7353 " PASSTHROUGH\n" 7354 "}\n" 7355 "\n"; 7356 7357 const GLchar* result = 0; 7358 7359 switch (stage) 7360 { 7361 case Utils::Shader::COMPUTE: 7362 result = compute_shader_template; 7363 break; 7364 case Utils::Shader::FRAGMENT: 7365 result = fragment_shader_template; 7366 break; 7367 case Utils::Shader::GEOMETRY: 7368 result = geometry_shader_template; 7369 break; 7370 case Utils::Shader::TESS_CTRL: 7371 result = tess_ctrl_shader_template; 7372 break; 7373 case Utils::Shader::TESS_EVAL: 7374 result = tess_eval_shader_template; 7375 break; 7376 case Utils::Shader::VERTEX: 7377 result = vertex_shader_template; 7378 break; 7379 default: 7380 TCU_FAIL("Invalid enum"); 7381 } 7382 7383 return result; 7384 } 7385 7386 /** Runs test case 7387 * 7388 * @param test_case_index Id of test case 7389 * 7390 * @return true if test case pass, false otherwise 7391 **/ 7392 bool TextureTestBase::testCase(GLuint test_case_index) 7393 { 7394 try 7395 { 7396 if (true == useMonolithicProgram(test_case_index)) 7397 { 7398 return testMonolithic(test_case_index); 7399 } 7400 else 7401 { 7402 return testSeparable(test_case_index); 7403 } 7404 } 7405 catch (Utils::Shader::InvalidSourceException& exc) 7406 { 7407 exc.log(m_context); 7408 TCU_FAIL(exc.what()); 7409 } 7410 catch (Utils::Program::BuildException& exc) 7411 { 7412 TCU_FAIL(exc.what()); 7413 } 7414 } 7415 7416 /** Runs "draw" test with monolithic program 7417 * 7418 * @param test_case_index Id of test case 7419 **/ 7420 bool TextureTestBase::testMonolithic(GLuint test_case_index) 7421 { 7422 Utils::ProgramInterface program_interface; 7423 Utils::VaryingPassthrough varying_passthrough; 7424 7425 /* */ 7426 const std::string& test_name = getTestCaseName(test_case_index); 7427 7428 /* */ 7429 getProgramInterface(test_case_index, program_interface, varying_passthrough); 7430 7431 bool result = true; 7432 /* Draw */ 7433 if (true == isDrawRelevant(test_case_index)) 7434 { 7435 Utils::Buffer buffer_attr(m_context); 7436 Utils::Buffer buffer_ssb_fs(m_context); 7437 Utils::Buffer buffer_ssb_gs(m_context); 7438 Utils::Buffer buffer_ssb_tcs(m_context); 7439 Utils::Buffer buffer_ssb_tes(m_context); 7440 Utils::Buffer buffer_ssb_vs(m_context); 7441 Utils::Buffer buffer_u_fs(m_context); 7442 Utils::Buffer buffer_u_gs(m_context); 7443 Utils::Buffer buffer_u_tcs(m_context); 7444 Utils::Buffer buffer_u_tes(m_context); 7445 Utils::Buffer buffer_u_vs(m_context); 7446 Utils::Framebuffer framebuffer(m_context); 7447 Utils::Program program(m_context); 7448 Utils::Texture texture_fb(m_context); 7449 Utils::VertexArray vao(m_context); 7450 7451 /* */ 7452 const std::string& fragment_shader = 7453 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT); 7454 const std::string& geometry_shader = 7455 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY); 7456 const std::string& tess_ctrl_shader = 7457 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL); 7458 const std::string& tess_eval_shader = 7459 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL); 7460 const std::string& vertex_shader = 7461 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX); 7462 7463 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader, 7464 vertex_shader, false /* is_separable */); 7465 7466 /* */ 7467 prepareAttribLocation(program, program_interface); 7468 prepareFragmentDataLoc(program, program_interface); 7469 7470 /* */ 7471 std::stringstream stream; 7472 if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream)) 7473 { 7474 m_context.getTestContext().getLog() 7475 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name 7476 << ". Inspection of draw program interface failed:\n" 7477 << stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader) 7478 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader) 7479 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader); 7480 7481 return false; 7482 } 7483 7484 /* */ 7485 program.Use(); 7486 7487 /* */ 7488 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0); 7489 vao.Init(); 7490 prepareAttributes(test_case_index, program_interface, buffer_attr, vao); 7491 7492 /* */ 7493 prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs, 7494 buffer_u_tes, buffer_u_vs); 7495 7496 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs, 7497 buffer_ssb_tes, buffer_ssb_vs); 7498 7499 /* */ 7500 prepareFramebuffer(framebuffer, texture_fb); 7501 7502 /* Draw */ 7503 executeDrawCall(test_case_index); 7504 7505 #if USE_NSIGHT 7506 m_context.getRenderContext().postIterate(); 7507 #endif 7508 7509 /* Check results */ 7510 if (false == checkResults(test_case_index, texture_fb)) 7511 { 7512 m_context.getTestContext().getLog() 7513 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results." 7514 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader) 7515 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader) 7516 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader); 7517 7518 result = false; 7519 } 7520 } 7521 7522 /* Compute */ 7523 if (true == isComputeRelevant(test_case_index)) 7524 { 7525 Utils::Buffer buffer_ssb_cs(m_context); 7526 Utils::Buffer buffer_u_cs(m_context); 7527 Utils::Program program(m_context); 7528 Utils::Texture texture_im(m_context); 7529 Utils::VertexArray vao(m_context); 7530 7531 /* */ 7532 const std::string& compute_shader = 7533 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE); 7534 7535 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */, 7536 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */); 7537 7538 /* */ 7539 { 7540 std::stringstream stream; 7541 7542 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream)) 7543 { 7544 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name 7545 << ". Inspection of compute program interface failed:\n" 7546 << stream.str() << tcu::TestLog::EndMessage; 7547 7548 return false; 7549 } 7550 } 7551 7552 /* */ 7553 program.Use(); 7554 7555 /* */ 7556 vao.Init(); 7557 vao.Bind(); 7558 7559 /* */ 7560 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs); 7561 7562 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs); 7563 7564 /* */ 7565 GLint image_location = program.GetUniformLocation("uni_image"); 7566 prepareImage(image_location, texture_im); 7567 7568 /* Draw */ 7569 executeDispatchCall(test_case_index); 7570 7571 #if USE_NSIGHT 7572 m_context.getRenderContext().postIterate(); 7573 #endif 7574 7575 /* Check results */ 7576 if (false == checkResults(test_case_index, texture_im)) 7577 { 7578 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name 7579 << ". Compute - invalid results." << tcu::TestLog::EndMessage 7580 << tcu::TestLog::KernelSource(compute_shader); 7581 7582 result = false; 7583 } 7584 } 7585 7586 return result; 7587 } 7588 7589 /** Runs "draw" test with separable program 7590 * 7591 * @param test_case_index Id of test case 7592 **/ 7593 bool TextureTestBase::testSeparable(GLuint test_case_index) 7594 { 7595 Utils::ProgramInterface program_interface; 7596 Utils::VaryingPassthrough varying_passthrough; 7597 7598 /* */ 7599 const std::string& test_name = getTestCaseName(test_case_index); 7600 7601 /* */ 7602 getProgramInterface(test_case_index, program_interface, varying_passthrough); 7603 7604 bool result = true; 7605 /* Draw */ 7606 if (true == isDrawRelevant(test_case_index)) 7607 { 7608 Utils::Buffer buffer_attr(m_context); 7609 Utils::Buffer buffer_u_fs(m_context); 7610 Utils::Buffer buffer_u_gs(m_context); 7611 Utils::Buffer buffer_u_tcs(m_context); 7612 Utils::Buffer buffer_u_tes(m_context); 7613 Utils::Buffer buffer_u_vs(m_context); 7614 Utils::Framebuffer framebuffer(m_context); 7615 Utils::Pipeline pipeline(m_context); 7616 Utils::Program program_fs(m_context); 7617 Utils::Program program_gs(m_context); 7618 Utils::Program program_tcs(m_context); 7619 Utils::Program program_tes(m_context); 7620 Utils::Program program_vs(m_context); 7621 Utils::Texture texture_fb(m_context); 7622 Utils::VertexArray vao(m_context); 7623 7624 /* */ 7625 const std::string& fs = 7626 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT); 7627 const std::string& gs = 7628 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY); 7629 const std::string& tcs = 7630 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL); 7631 const std::string& tes = 7632 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL); 7633 const std::string& vs = 7634 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX); 7635 7636 program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */); 7637 program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */); 7638 program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */); 7639 program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */); 7640 program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */); 7641 7642 /* */ 7643 prepareAttribLocation(program_vs, program_interface); 7644 prepareFragmentDataLoc(program_vs, program_interface); 7645 7646 /* */ 7647 std::stringstream stream; 7648 if ((false == 7649 Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) || 7650 (false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT, 7651 stream)) || 7652 (false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY, 7653 stream)) || 7654 (false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface, 7655 Utils::Shader::TESS_CTRL, stream)) || 7656 (false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface, 7657 Utils::Shader::TESS_EVAL, stream))) 7658 { 7659 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name 7660 << ". Inspection of separable draw program interface failed:\n" 7661 << stream.str() << tcu::TestLog::EndMessage 7662 << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs) 7663 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) 7664 << tcu::TestLog::KernelSource(fs); 7665 7666 return false; 7667 } 7668 7669 /* */ 7670 pipeline.Init(); 7671 pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT); 7672 pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT); 7673 pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT); 7674 pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT); 7675 pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT); 7676 pipeline.Bind(); 7677 7678 /* */ 7679 7680 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0); 7681 vao.Init(); 7682 prepareAttributes(test_case_index, program_interface, buffer_attr, vao); 7683 7684 /* */ 7685 prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes, 7686 program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs); 7687 7688 Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id); 7689 7690 /* */ 7691 prepareFramebuffer(framebuffer, texture_fb); 7692 7693 /* Draw */ 7694 executeDrawCall(test_case_index); 7695 7696 #if USE_NSIGHT 7697 m_context.getRenderContext().postIterate(); 7698 #endif 7699 7700 /* Check results */ 7701 if (false == checkResults(test_case_index, texture_fb)) 7702 { 7703 m_context.getTestContext().getLog() 7704 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results." 7705 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs) 7706 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs); 7707 7708 result = false; 7709 } 7710 } 7711 7712 /* Compute */ 7713 if (true == isComputeRelevant(test_case_index)) 7714 { 7715 Utils::Buffer buffer_u_cs(m_context); 7716 Utils::Program program(m_context); 7717 Utils::Texture texture_im(m_context); 7718 Utils::VertexArray vao(m_context); 7719 7720 /* */ 7721 const std::string& compute_shader = 7722 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE); 7723 7724 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */, 7725 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */); 7726 7727 /* */ 7728 { 7729 std::stringstream stream; 7730 7731 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream)) 7732 { 7733 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name 7734 << ". Inspection of compute program interface failed:\n" 7735 << stream.str() << tcu::TestLog::EndMessage; 7736 7737 return false; 7738 } 7739 } 7740 7741 /* */ 7742 program.Use(); 7743 7744 /* */ 7745 vao.Init(); 7746 vao.Bind(); 7747 7748 /* */ 7749 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs); 7750 7751 /* */ 7752 GLint image_location = program.GetUniformLocation("uni_image"); 7753 prepareImage(image_location, texture_im); 7754 7755 /* Draw */ 7756 executeDispatchCall(test_case_index); 7757 7758 #if USE_NSIGHT 7759 m_context.getRenderContext().postIterate(); 7760 #endif 7761 7762 /* Check results */ 7763 if (false == checkResults(test_case_index, texture_im)) 7764 { 7765 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name 7766 << ". Compute - invalid results." << tcu::TestLog::EndMessage 7767 << tcu::TestLog::KernelSource(compute_shader); 7768 7769 result = false; 7770 } 7771 } 7772 7773 return result; 7774 } 7775 7776 /** Basic implementation 7777 * 7778 * @param ignored 7779 * 7780 * @return false 7781 **/ 7782 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */) 7783 { 7784 return false; 7785 } 7786 7787 /** Basic implementation 7788 * 7789 * @param ignored 7790 * 7791 * @return true 7792 **/ 7793 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */) 7794 { 7795 return true; 7796 } 7797 7798 /** Constructor 7799 * 7800 * @param context Test framework context 7801 **/ 7802 APIConstantValuesTest::APIConstantValuesTest(deqp::Context& context) 7803 : TestCase(context, "api_constant_values", "Test verifies values of api constants") 7804 { 7805 /* Nothing to be done here */ 7806 } 7807 7808 /** Execute test 7809 * 7810 * @return tcu::TestNode::STOP otherwise 7811 **/ 7812 tcu::TestNode::IterateResult APIConstantValuesTest::iterate() 7813 { 7814 static const GLuint expected_comp = 64; 7815 static const GLuint expected_xfb = 4; 7816 static const GLuint expected_sep = 4; 7817 GLint max_comp = 0; 7818 GLint max_xfb = 0; 7819 GLint max_sep = 0; 7820 bool test_result = true; 7821 7822 const Functions& gl = m_context.getRenderContext().getFunctions(); 7823 7824 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb); 7825 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 7826 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp); 7827 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 7828 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep); 7829 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 7830 7831 if (expected_xfb > (GLuint)max_xfb) 7832 { 7833 m_context.getTestContext().getLog() << tcu::TestLog::Message 7834 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb 7835 << " Expected at least " << expected_xfb << tcu::TestLog::EndMessage; 7836 7837 test_result = false; 7838 } 7839 7840 if (expected_comp > (GLuint)max_comp) 7841 { 7842 m_context.getTestContext().getLog() 7843 << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp 7844 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage; 7845 7846 test_result = false; 7847 } 7848 7849 if (expected_sep > (GLuint)max_sep) 7850 { 7851 m_context.getTestContext().getLog() << tcu::TestLog::Message 7852 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp 7853 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage; 7854 7855 test_result = false; 7856 } 7857 7858 /* Set result */ 7859 if (true == test_result) 7860 { 7861 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 7862 } 7863 else 7864 { 7865 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 7866 } 7867 7868 /* Done */ 7869 return tcu::TestNode::STOP; 7870 } 7871 7872 /** Constructor 7873 * 7874 * @param context Test framework context 7875 **/ 7876 APIErrorsTest::APIErrorsTest(deqp::Context& context) 7877 : TestCase(context, "api_errors", "Test verifies errors reeturned by api") 7878 { 7879 /* Nothing to be done here */ 7880 } 7881 7882 /** Execute test 7883 * 7884 * @return tcu::TestNode::STOP otherwise 7885 **/ 7886 tcu::TestNode::IterateResult APIErrorsTest::iterate() 7887 { 7888 GLint length = 0; 7889 GLchar name[64]; 7890 GLint param = 0; 7891 Utils::Program program(m_context); 7892 bool test_result = true; 7893 7894 const Functions& gl = m_context.getRenderContext().getFunctions(); 7895 7896 try 7897 { 7898 program.Init("" /* cs */, "#version 430 core\n" 7899 "#extension GL_ARB_enhanced_layouts : require\n" 7900 "\n" 7901 "in vec4 vs_fs;\n" 7902 "out vec4 fs_out;\n" 7903 "\n" 7904 "void main()\n" 7905 "{\n" 7906 " fs_out = vs_fs;\n" 7907 "}\n" 7908 "\n" /* fs */, 7909 "" /* gs */, "" /* tcs */, "" /* tes */, "#version 430 core\n" 7910 "#extension GL_ARB_enhanced_layouts : require\n" 7911 "\n" 7912 "in vec4 in_vs;\n" 7913 "layout (xfb_offset = 16) out vec4 vs_fs;\n" 7914 "\n" 7915 "void main()\n" 7916 "{\n" 7917 " vs_fs = in_vs;\n" 7918 "}\n" 7919 "\n" /* vs */, 7920 false /* separable */); 7921 } 7922 catch (Utils::Shader::InvalidSourceException& exc) 7923 { 7924 exc.log(m_context); 7925 TCU_FAIL(exc.what()); 7926 } 7927 catch (Utils::Program::BuildException& exc) 7928 { 7929 TCU_FAIL(exc.what()); 7930 } 7931 7932 /* 7933 * - GetProgramInterfaceiv should generate INVALID_OPERATION when 7934 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the 7935 * following: 7936 * * MAX_NAME_LENGTH, 7937 * * MAX_NUM_ACTIVE_VARIABLES; 7938 */ 7939 gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, ¶m); 7940 checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)", 7941 test_result); 7942 7943 /* 7944 * - GetProgramResourceIndex should generate INVALID_ENUM when 7945 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER; 7946 */ 7947 gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0"); 7948 checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result); 7949 /* 7950 * - GetProgramResourceName should generate INVALID_ENUM when 7951 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER; 7952 */ 7953 gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length, 7954 name); 7955 checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result); 7956 7957 /* Set result */ 7958 if (true == test_result) 7959 { 7960 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 7961 } 7962 else 7963 { 7964 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 7965 } 7966 7967 /* Done */ 7968 return tcu::TestNode::STOP; 7969 } 7970 7971 /** Check if error is the expected one. 7972 * 7973 * @param expected_error Expected error 7974 * @param message Message to log in case of error 7975 * @param test_result Test result, set to false in case of invalid error 7976 **/ 7977 void APIErrorsTest::checkError(GLenum expected_error, const GLchar* message, bool& test_result) 7978 { 7979 const Functions& gl = m_context.getRenderContext().getFunctions(); 7980 7981 GLenum error = gl.getError(); 7982 7983 if (error != expected_error) 7984 { 7985 m_context.getTestContext().getLog() 7986 << tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected " 7987 << glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage; 7988 7989 test_result = false; 7990 } 7991 } 7992 7993 /** Constructor 7994 * 7995 * @param context Test framework context 7996 **/ 7997 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context& context) 7998 : NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified") 7999 { 8000 /* Nothing to be done here */ 8001 } 8002 8003 /** Source for given test case and stage 8004 * 8005 * @param test_case_index Index of test case 8006 * @param stage Shader stage 8007 * 8008 * @return Shader source 8009 **/ 8010 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 8011 { 8012 static const GLchar* cs = "#version 430 core\n" 8013 "#extension GL_ARB_enhanced_layouts : require\n" 8014 "\n" 8015 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 8016 "\n" 8017 "writeonly uniform uimage2D uni_image;\n" 8018 "\n" 8019 "void main()\n" 8020 "{\n" 8021 " uint result = 1u;\n" 8022 " CONSTANT = 3;\n" 8023 "\n" 8024 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n" 8025 "}\n" 8026 "\n"; 8027 static const GLchar* fs = "#version 430 core\n" 8028 "#extension GL_ARB_enhanced_layouts : require\n" 8029 "\n" 8030 "in vec4 gs_fs;\n" 8031 "out vec4 fs_out;\n" 8032 "\n" 8033 "void main()\n" 8034 "{\n" 8035 "ASSIGNMENT" 8036 " fs_out = gs_fs;\n" 8037 "}\n" 8038 "\n"; 8039 static const GLchar* gs = "#version 430 core\n" 8040 "#extension GL_ARB_enhanced_layouts : require\n" 8041 "\n" 8042 "layout(points) in;\n" 8043 "layout(triangle_strip, max_vertices = 4) out;\n" 8044 "\n" 8045 "in vec4 tes_gs[];\n" 8046 "out vec4 gs_fs;\n" 8047 "\n" 8048 "void main()\n" 8049 "{\n" 8050 "ASSIGNMENT" 8051 " gs_fs = tes_gs[0];\n" 8052 " gl_Position = vec4(-1, -1, 0, 1);\n" 8053 " EmitVertex();\n" 8054 " gs_fs = tes_gs[0];\n" 8055 " gl_Position = vec4(-1, 1, 0, 1);\n" 8056 " EmitVertex();\n" 8057 " gs_fs = tes_gs[0];\n" 8058 " gl_Position = vec4(1, -1, 0, 1);\n" 8059 " EmitVertex();\n" 8060 " gs_fs = tes_gs[0];\n" 8061 " gl_Position = vec4(1, 1, 0, 1);\n" 8062 " EmitVertex();\n" 8063 "}\n" 8064 "\n"; 8065 static const GLchar* tcs = "#version 430 core\n" 8066 "#extension GL_ARB_enhanced_layouts : require\n" 8067 "\n" 8068 "layout(vertices = 1) out;\n" 8069 "\n" 8070 "in vec4 vs_tcs[];\n" 8071 "out vec4 tcs_tes[];\n" 8072 "\n" 8073 "void main()\n" 8074 "{\n" 8075 "\n" 8076 "ASSIGNMENT" 8077 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 8078 "\n" 8079 " gl_TessLevelOuter[0] = 1.0;\n" 8080 " gl_TessLevelOuter[1] = 1.0;\n" 8081 " gl_TessLevelOuter[2] = 1.0;\n" 8082 " gl_TessLevelOuter[3] = 1.0;\n" 8083 " gl_TessLevelInner[0] = 1.0;\n" 8084 " gl_TessLevelInner[1] = 1.0;\n" 8085 "}\n" 8086 "\n"; 8087 static const GLchar* tes = "#version 430 core\n" 8088 "#extension GL_ARB_enhanced_layouts : require\n" 8089 "\n" 8090 "layout(isolines, point_mode) in;\n" 8091 "\n" 8092 "in vec4 tcs_tes[];\n" 8093 "out vec4 tes_gs;\n" 8094 "\n" 8095 "void main()\n" 8096 "{\n" 8097 "ASSIGNMENT" 8098 " tes_gs = tcs_tes[0];\n" 8099 "}\n" 8100 "\n"; 8101 static const GLchar* vs = "#version 430 core\n" 8102 "#extension GL_ARB_enhanced_layouts : require\n" 8103 "\n" 8104 "in vec4 in_vs;\n" 8105 "out vec4 vs_tcs;\n" 8106 "\n" 8107 "void main()\n" 8108 "{\n" 8109 "ASSIGNMENT" 8110 " vs_tcs = in_vs;\n" 8111 "}\n" 8112 "\n"; 8113 8114 std::string source; 8115 testCase& test_case = m_test_cases[test_case_index]; 8116 8117 if (Utils::Shader::COMPUTE == test_case.m_stage) 8118 { 8119 size_t position = 0; 8120 8121 source = cs; 8122 8123 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source); 8124 } 8125 else 8126 { 8127 std::string assignment = " CONSTANT = 3;\n"; 8128 size_t position = 0; 8129 8130 switch (stage) 8131 { 8132 case Utils::Shader::FRAGMENT: 8133 source = fs; 8134 break; 8135 case Utils::Shader::GEOMETRY: 8136 source = gs; 8137 break; 8138 case Utils::Shader::TESS_CTRL: 8139 source = tcs; 8140 break; 8141 case Utils::Shader::TESS_EVAL: 8142 source = tes; 8143 break; 8144 case Utils::Shader::VERTEX: 8145 source = vs; 8146 break; 8147 default: 8148 TCU_FAIL("Invalid enum"); 8149 } 8150 8151 if (test_case.m_stage == stage) 8152 { 8153 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment); 8154 } 8155 else 8156 { 8157 assignment = ""; 8158 } 8159 8160 position = 0; 8161 Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source); 8162 } 8163 8164 return source; 8165 } 8166 8167 /** Get description of test case 8168 * 8169 * @param test_case_index Index of test case 8170 * 8171 * @return Constant name 8172 **/ 8173 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index) 8174 { 8175 std::string result = getConstantName(m_test_cases[test_case_index].m_constant); 8176 8177 return result; 8178 } 8179 8180 /** Get number of test cases 8181 * 8182 * @return Number of test cases 8183 **/ 8184 GLuint GLSLContantImmutablityTest::getTestCaseNumber() 8185 { 8186 return static_cast<GLuint>(m_test_cases.size()); 8187 } 8188 8189 /** Selects if "compute" stage is relevant for test 8190 * 8191 * @param test_case_index Index of test case 8192 * 8193 * @return true when tested stage is compute 8194 **/ 8195 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index) 8196 { 8197 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage); 8198 } 8199 8200 /** Prepare all test cases 8201 * 8202 **/ 8203 void GLSLContantImmutablityTest::testInit() 8204 { 8205 for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant) 8206 { 8207 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 8208 { 8209 testCase test_case = { (CONSTANTS)constant, (Utils::Shader::STAGES)stage }; 8210 8211 m_test_cases.push_back(test_case); 8212 } 8213 } 8214 } 8215 8216 /** Get name of glsl constant 8217 * 8218 * @param Constant id 8219 * 8220 * @return Name of constant used in GLSL 8221 **/ 8222 const GLchar* GLSLContantImmutablityTest::getConstantName(CONSTANTS constant) 8223 { 8224 const GLchar* name = ""; 8225 8226 switch (constant) 8227 { 8228 case GL_ARB_ENHANCED_LAYOUTS: 8229 name = "GL_ARB_enhanced_layouts"; 8230 break; 8231 case GL_MAX_XFB: 8232 name = "gl_MaxTransformFeedbackBuffers"; 8233 break; 8234 case GL_MAX_XFB_INT_COMP: 8235 name = "gl_MaxTransformFeedbackInterleavedComponents"; 8236 break; 8237 default: 8238 TCU_FAIL("Invalid enum"); 8239 } 8240 8241 return name; 8242 } 8243 8244 /** Constructor 8245 * 8246 * @param context Test framework context 8247 **/ 8248 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context& context) 8249 : TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols") 8250 { 8251 } 8252 8253 /** Selects if "compute" stage is relevant for test 8254 * 8255 * @param ignored 8256 * 8257 * @return false 8258 **/ 8259 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */) 8260 { 8261 return false; 8262 } 8263 8264 /** Prepare code snippet that will verify in and uniform variables 8265 * 8266 * @param ignored 8267 * @param ignored 8268 * @param stage Shader stage 8269 * 8270 * @return Code that verify variables 8271 **/ 8272 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */, 8273 Utils::ProgramInterface& /* program_interface */, 8274 Utils::Shader::STAGES stage) 8275 { 8276 /* Get constants */ 8277 const Functions& gl = m_context.getRenderContext().getFunctions(); 8278 8279 GLint max_transform_feedback_buffers = 0; 8280 GLint max_transform_feedback_interleaved_components = 0; 8281 8282 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers); 8283 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 8284 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components); 8285 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 8286 8287 std::string verification; 8288 8289 if (Utils::Shader::VERTEX == stage) 8290 { 8291 verification = "if (1 != GL_ARB_enhanced_layouts)\n" 8292 " {\n" 8293 " result = 0;\n" 8294 " }\n" 8295 " else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n" 8296 " != gl_MaxTransformFeedbackBuffers)\n" 8297 " {\n" 8298 " result = 0;\n" 8299 " }\n" 8300 " else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n" 8301 " != gl_MaxTransformFeedbackInterleavedComponents)\n" 8302 " {\n" 8303 " result = 0;\n" 8304 " }\n"; 8305 8306 size_t position = 0; 8307 GLchar buffer[16]; 8308 8309 sprintf(buffer, "%d", max_transform_feedback_buffers); 8310 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification); 8311 8312 sprintf(buffer, "%d", max_transform_feedback_interleaved_components); 8313 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification); 8314 } 8315 else 8316 { 8317 verification = ""; 8318 } 8319 8320 return verification; 8321 } 8322 8323 /** Constructor 8324 * 8325 * @param context Test framework context 8326 **/ 8327 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context& context) 8328 : TextureTestBase(context, "glsl_constant_integral_expression", 8329 "Test verifies that symbols can be used as constant integral expressions") 8330 { 8331 } 8332 8333 /** Get interface of program 8334 * 8335 * @param ignored 8336 * @param program_interface Interface of program 8337 * @param ignored 8338 **/ 8339 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */, 8340 Utils::ProgramInterface& program_interface, 8341 Utils::VaryingPassthrough& /* varying_passthrough */) 8342 { 8343 /* Get constants */ 8344 const Functions& gl = m_context.getRenderContext().getFunctions(); 8345 8346 GLint max_transform_feedback_buffers = 0; 8347 GLint max_transform_feedback_interleaved_components = 0; 8348 8349 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers); 8350 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 8351 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components); 8352 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 8353 8354 GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16); 8355 GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16); 8356 8357 m_gohan_length = max_transform_feedback_buffers / gohan_div; 8358 m_goten_length = max_transform_feedback_interleaved_components / goten_div; 8359 8360 /* Globals */ 8361 std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n" 8362 "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n" 8363 "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n"; 8364 8365 size_t position = 0; 8366 GLchar buffer[16]; 8367 8368 sprintf(buffer, "%d", gohan_div); 8369 Utils::replaceToken("GOHAN_DIV", position, buffer, globals); 8370 8371 sprintf(buffer, "%d", goten_div); 8372 Utils::replaceToken("GOTEN_DIV", position, buffer, globals); 8373 8374 program_interface.m_vertex.m_globals = globals; 8375 program_interface.m_tess_ctrl.m_globals = globals; 8376 program_interface.m_tess_eval.m_globals = globals; 8377 program_interface.m_geometry.m_globals = globals; 8378 program_interface.m_fragment.m_globals = globals; 8379 program_interface.m_compute.m_globals = globals; 8380 } 8381 8382 /** Prepare code snippet that will verify in and uniform variables 8383 * 8384 * @param ignored 8385 * @param ignored 8386 * @param ignored 8387 * 8388 * @return Code that verify variables 8389 **/ 8390 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(GLuint /* test_case_index */, 8391 Utils::ProgramInterface& /* program_interface */, 8392 Utils::Shader::STAGES /* stage */) 8393 { 8394 std::string verification = "{\n" 8395 " uint goku_sum = 0;\n" 8396 " uint gohan_sum = 0;\n" 8397 " uint goten_sum = 0;\n" 8398 "\n" 8399 " for (uint i = 0u; i < goku.length(); ++i)\n" 8400 " {\n" 8401 " goku_sum += goku[i];\n" 8402 " }\n" 8403 "\n" 8404 " for (uint i = 0u; i < gohan.length(); ++i)\n" 8405 " {\n" 8406 " gohan_sum += gohan[i];\n" 8407 " }\n" 8408 "\n" 8409 " for (uint i = 0u; i < goten.length(); ++i)\n" 8410 " {\n" 8411 " goten_sum += goten[i];\n" 8412 " }\n" 8413 "\n" 8414 " if ( (1u != goku_sum) &&\n" 8415 " (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n" 8416 " (EXPECTED_GOTEN_SUMu != goten_sum) )\n" 8417 " {\n" 8418 " result = 0u;\n" 8419 " }\n" 8420 " }\n"; 8421 8422 size_t position = 0; 8423 GLchar buffer[16]; 8424 8425 sprintf(buffer, "%d", m_gohan_length); 8426 Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification); 8427 8428 sprintf(buffer, "%d", m_goten_length); 8429 Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification); 8430 8431 return verification; 8432 } 8433 8434 /** Prepare unifroms 8435 * 8436 * @param ignored 8437 * @param ignored 8438 * @param program Program object 8439 * @param ignored 8440 **/ 8441 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */, 8442 Utils::ProgramInterface& /* program_interface */, 8443 Utils::Program& program, Utils::Buffer& /* cs_buffer */) 8444 { 8445 static const GLuint uniform_data[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; 8446 8447 const Functions& gl = m_context.getRenderContext().getFunctions(); 8448 8449 GLint goku_location = program.GetUniformLocation("goku"); 8450 GLint gohan_location = program.GetUniformLocation("gohan"); 8451 GLint goten_location = program.GetUniformLocation("goten"); 8452 8453 program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data); 8454 program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data); 8455 program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data); 8456 } 8457 8458 /** Prepare unifroms 8459 * 8460 * @param test_case_index Pass as param to first implemetnation 8461 * @param program_interface Pass as param to first implemetnation 8462 * @param program Pass as param to first implemetnation 8463 * @param ignored 8464 * @param ignored 8465 * @param ignored 8466 * @param ignored 8467 * @param vs_buffer Pass as param to first implemetnation 8468 **/ 8469 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint test_case_index, 8470 Utils::ProgramInterface& program_interface, 8471 Utils::Program& program, Utils::Buffer& /* fs_buffer */, 8472 Utils::Buffer& /* gs_buffer */, 8473 Utils::Buffer& /* tcs_buffer */, 8474 Utils::Buffer& /* tes_buffer */, Utils::Buffer& vs_buffer) 8475 { 8476 /* Call first implementation */ 8477 prepareUniforms(test_case_index, program_interface, program, vs_buffer); 8478 } 8479 8480 /** Constructor 8481 * 8482 * @param context Test framework context 8483 **/ 8484 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context& context) 8485 : TextureTestBase(context, "uniform_block_member_offset_and_align", 8486 "Test verifies offsets and alignment of uniform buffer members") 8487 { 8488 } 8489 8490 /** Get interface of program 8491 * 8492 * @param test_case_index Test case index 8493 * @param program_interface Interface of program 8494 * @param varying_passthrough Collection of connections between in and out variables 8495 **/ 8496 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index, 8497 Utils::ProgramInterface& program_interface, 8498 Utils::VaryingPassthrough& varying_passthrough) 8499 { 8500 std::string globals = "const int basic_size = BASIC_SIZE;\n" 8501 "const int type_align = TYPE_ALIGN;\n" 8502 "const int type_size = TYPE_SIZE;\n"; 8503 8504 Utils::Type type = getType(test_case_index); 8505 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type); 8506 const GLuint base_align = type.GetBaseAlignment(false); 8507 const GLuint array_align = type.GetBaseAlignment(true); 8508 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0); 8509 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride); 8510 8511 /* Calculate offsets */ 8512 const GLuint first_offset = 0; 8513 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2); 8514 8515 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST 8516 8517 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align); 8518 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align); 8519 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align); 8520 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align); 8521 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align); 8522 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align); 8523 8524 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */ 8525 8526 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align); 8527 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align); 8528 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align); 8529 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align); 8530 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align); 8531 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size); 8532 8533 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */ 8534 8535 /* Prepare data */ 8536 const std::vector<GLubyte>& first = type.GenerateData(); 8537 const std::vector<GLubyte>& second = type.GenerateData(); 8538 const std::vector<GLubyte>& third = type.GenerateData(); 8539 const std::vector<GLubyte>& fourth = type.GenerateData(); 8540 8541 m_data.resize(eigth_offset + base_stride); 8542 GLubyte* ptr = &m_data[0]; 8543 memcpy(ptr + first_offset, &first[0], first.size()); 8544 memcpy(ptr + second_offset, &second[0], second.size()); 8545 memcpy(ptr + third_offset, &third[0], third.size()); 8546 memcpy(ptr + fourth_offset, &fourth[0], fourth.size()); 8547 memcpy(ptr + fifth_offset, &fourth[0], fourth.size()); 8548 memcpy(ptr + sixth_offset, &third[0], third.size()); 8549 memcpy(ptr + seventh_offset, &second[0], second.size()); 8550 memcpy(ptr + eigth_offset, &first[0], first.size()); 8551 8552 /* Prepare globals */ 8553 size_t position = 0; 8554 GLchar buffer[16]; 8555 8556 sprintf(buffer, "%d", basic_size); 8557 Utils::replaceToken("BASIC_SIZE", position, buffer, globals); 8558 8559 sprintf(buffer, "%d", type_align); 8560 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals); 8561 8562 sprintf(buffer, "%d", base_stride); 8563 Utils::replaceToken("TYPE_SIZE", position, buffer, globals); 8564 8565 /* Prepare Block */ 8566 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block"); 8567 8568 vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */, 8569 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 8570 first_offset); 8571 8572 vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)", 8573 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */, 8574 0 /* n_array_elements */, base_stride, second_offset); 8575 8576 vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */, 8577 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 8578 third_offset); 8579 8580 vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */, 8581 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 8582 fourth_offset); 8583 8584 vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type, 8585 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset); 8586 8587 vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type, 8588 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset); 8589 8590 vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */, 8591 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 8592 eigth_offset); 8593 8594 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 8595 8596 /* Add globals */ 8597 vs_si.m_globals = globals; 8598 8599 /* Add uniform BLOCK */ 8600 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0, 8601 static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size()); 8602 8603 /* */ 8604 program_interface.CloneVertexInterface(varying_passthrough); 8605 } 8606 8607 /** Get type name 8608 * 8609 * @param test_case_index Index of test case 8610 * 8611 * @return Name of type test in test_case_index 8612 **/ 8613 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index) 8614 { 8615 return getTypeName(test_case_index); 8616 } 8617 8618 /** Returns number of types to test 8619 * 8620 * @return Number of types, 34 8621 **/ 8622 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber() 8623 { 8624 return getTypesNumber(); 8625 } 8626 8627 /** Prepare code snippet that will verify in and uniform variables 8628 * 8629 * @param ignored 8630 * @param ignored 8631 * @param stage Shader stage 8632 * 8633 * @return Code that verify variables 8634 **/ 8635 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet( 8636 GLuint /* test_case_index */, Utils::ProgramInterface& /* program_interface */, Utils::Shader::STAGES stage) 8637 { 8638 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n" 8639 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n" 8640 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n" 8641 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n" 8642 " {\n" 8643 " result = 0;\n" 8644 " }"; 8645 8646 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM); 8647 8648 Utils::replaceAllTokens("PREFIX", prefix, verification); 8649 8650 return verification; 8651 } 8652 8653 /** Constructor 8654 * 8655 * @param context Test framework context 8656 **/ 8657 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context& context) 8658 : NegativeTestBase( 8659 context, "uniform_block_layout_qualifier_conflict", 8660 "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block") 8661 { 8662 /* Nothing to be done here */ 8663 } 8664 8665 /** Source for given test case and stage 8666 * 8667 * @param test_case_index Index of test case 8668 * @param stage Shader stage 8669 * 8670 * @return Shader source 8671 **/ 8672 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, 8673 Utils::Shader::STAGES stage) 8674 { 8675 static const GLchar* cs = "#version 430 core\n" 8676 "#extension GL_ARB_enhanced_layouts : require\n" 8677 "\n" 8678 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 8679 "\n" 8680 "LAYOUTuniform Block {\n" 8681 " layout(offset = 16) vec4 boy;\n" 8682 " layout(align = 64) vec4 man;\n" 8683 "} uni_block;\n" 8684 "\n" 8685 "writeonly uniform image2D uni_image;\n" 8686 "\n" 8687 "void main()\n" 8688 "{\n" 8689 " vec4 result = uni_block.boy + uni_block.man;\n" 8690 "\n" 8691 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 8692 "}\n" 8693 "\n"; 8694 static const GLchar* fs = "#version 430 core\n" 8695 "#extension GL_ARB_enhanced_layouts : require\n" 8696 "\n" 8697 "LAYOUTuniform Block {\n" 8698 " layout(offset = 16) vec4 boy;\n" 8699 " layout(align = 64) vec4 man;\n" 8700 "} uni_block;\n" 8701 "\n" 8702 "in vec4 gs_fs;\n" 8703 "out vec4 fs_out;\n" 8704 "\n" 8705 "void main()\n" 8706 "{\n" 8707 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n" 8708 "}\n" 8709 "\n"; 8710 static const GLchar* gs = "#version 430 core\n" 8711 "#extension GL_ARB_enhanced_layouts : require\n" 8712 "\n" 8713 "layout(points) in;\n" 8714 "layout(triangle_strip, max_vertices = 4) out;\n" 8715 "\n" 8716 "LAYOUTuniform Block {\n" 8717 " layout(offset = 16) vec4 boy;\n" 8718 " layout(align = 64) vec4 man;\n" 8719 "} uni_block;\n" 8720 "\n" 8721 "in vec4 tes_gs[];\n" 8722 "out vec4 gs_fs;\n" 8723 "\n" 8724 "void main()\n" 8725 "{\n" 8726 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 8727 " gl_Position = vec4(-1, -1, 0, 1);\n" 8728 " EmitVertex();\n" 8729 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 8730 " gl_Position = vec4(-1, 1, 0, 1);\n" 8731 " EmitVertex();\n" 8732 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 8733 " gl_Position = vec4(1, -1, 0, 1);\n" 8734 " EmitVertex();\n" 8735 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 8736 " gl_Position = vec4(1, 1, 0, 1);\n" 8737 " EmitVertex();\n" 8738 "}\n" 8739 "\n"; 8740 static const GLchar* tcs = 8741 "#version 430 core\n" 8742 "#extension GL_ARB_enhanced_layouts : require\n" 8743 "\n" 8744 "layout(vertices = 1) out;\n" 8745 "\n" 8746 "LAYOUTuniform Block {\n" 8747 " layout(offset = 16) vec4 boy;\n" 8748 " layout(align = 64) vec4 man;\n" 8749 "} uni_block;\n" 8750 "\n" 8751 "in vec4 vs_tcs[];\n" 8752 "out vec4 tcs_tes[];\n" 8753 "\n" 8754 "void main()\n" 8755 "{\n" 8756 "\n" 8757 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n" 8758 "\n" 8759 " gl_TessLevelOuter[0] = 1.0;\n" 8760 " gl_TessLevelOuter[1] = 1.0;\n" 8761 " gl_TessLevelOuter[2] = 1.0;\n" 8762 " gl_TessLevelOuter[3] = 1.0;\n" 8763 " gl_TessLevelInner[0] = 1.0;\n" 8764 " gl_TessLevelInner[1] = 1.0;\n" 8765 "}\n" 8766 "\n"; 8767 static const GLchar* tes = "#version 430 core\n" 8768 "#extension GL_ARB_enhanced_layouts : require\n" 8769 "\n" 8770 "layout(isolines, point_mode) in;\n" 8771 "\n" 8772 "LAYOUTuniform Block {\n" 8773 " layout(offset = 16) vec4 boy;\n" 8774 " layout(align = 64) vec4 man;\n" 8775 "} uni_block;\n" 8776 "\n" 8777 "in vec4 tcs_tes[];\n" 8778 "out vec4 tes_gs;\n" 8779 "\n" 8780 "void main()\n" 8781 "{\n" 8782 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n" 8783 "}\n" 8784 "\n"; 8785 static const GLchar* vs = "#version 430 core\n" 8786 "#extension GL_ARB_enhanced_layouts : require\n" 8787 "\n" 8788 "LAYOUTuniform Block {\n" 8789 " layout(offset = 16) vec4 boy;\n" 8790 " layout(align = 64) vec4 man;\n" 8791 "} uni_block;\n" 8792 "\n" 8793 "in vec4 in_vs;\n" 8794 "out vec4 vs_tcs;\n" 8795 "\n" 8796 "void main()\n" 8797 "{\n" 8798 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n" 8799 "}\n" 8800 "\n"; 8801 8802 std::string layout = ""; 8803 size_t position = 0; 8804 testCase& test_case = m_test_cases[test_case_index]; 8805 const GLchar* qualifier = getQualifierName(test_case.m_qualifier); 8806 std::string source; 8807 8808 if (0 != qualifier[0]) 8809 { 8810 size_t layout_position = 0; 8811 8812 layout = "layout (QUALIFIER) "; 8813 8814 Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout); 8815 } 8816 8817 switch (stage) 8818 { 8819 case Utils::Shader::COMPUTE: 8820 source = cs; 8821 break; 8822 case Utils::Shader::FRAGMENT: 8823 source = fs; 8824 break; 8825 case Utils::Shader::GEOMETRY: 8826 source = gs; 8827 break; 8828 case Utils::Shader::TESS_CTRL: 8829 source = tcs; 8830 break; 8831 case Utils::Shader::TESS_EVAL: 8832 source = tes; 8833 break; 8834 case Utils::Shader::VERTEX: 8835 source = vs; 8836 break; 8837 default: 8838 TCU_FAIL("Invalid enum"); 8839 } 8840 8841 if (test_case.m_stage == stage) 8842 { 8843 Utils::replaceToken("LAYOUT", position, layout.c_str(), source); 8844 } 8845 else 8846 { 8847 Utils::replaceToken("LAYOUT", position, "layout (std140) ", source); 8848 } 8849 8850 return source; 8851 } 8852 8853 /** Get description of test case 8854 * 8855 * @param test_case_index Index of test case 8856 * 8857 * @return Qualifier name 8858 **/ 8859 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index) 8860 { 8861 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier); 8862 8863 return result; 8864 } 8865 8866 /** Get number of test cases 8867 * 8868 * @return Number of test cases 8869 **/ 8870 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber() 8871 { 8872 return static_cast<GLuint>(m_test_cases.size()); 8873 } 8874 8875 /** Selects if "compute" stage is relevant for test 8876 * 8877 * @param test_case_index Index of test case 8878 * 8879 * @return true when tested stage is compute 8880 **/ 8881 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index) 8882 { 8883 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage); 8884 } 8885 8886 /** Selects if compilation failure is expected result 8887 * 8888 * @param test_case_index Index of test case 8889 * 8890 * @return false for STD140 cases, true otherwise 8891 **/ 8892 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index) 8893 { 8894 return (STD140 != m_test_cases[test_case_index].m_qualifier); 8895 } 8896 8897 /** Prepare all test cases 8898 * 8899 **/ 8900 void UniformBlockLayoutQualifierConflictTest::testInit() 8901 { 8902 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier) 8903 { 8904 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 8905 { 8906 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage }; 8907 8908 m_test_cases.push_back(test_case); 8909 } 8910 } 8911 } 8912 8913 /** Get name of glsl constant 8914 * 8915 * @param Constant id 8916 * 8917 * @return Name of constant used in GLSL 8918 **/ 8919 const GLchar* UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier) 8920 { 8921 const GLchar* name = ""; 8922 8923 switch (qualifier) 8924 { 8925 case DEFAULT: 8926 name = ""; 8927 break; 8928 case STD140: 8929 name = "std140"; 8930 break; 8931 case SHARED: 8932 name = "shared"; 8933 break; 8934 case PACKED: 8935 name = "packed"; 8936 break; 8937 default: 8938 TCU_FAIL("Invalid enum"); 8939 } 8940 8941 return name; 8942 } 8943 8944 /** Constructor 8945 * 8946 * @param context Test framework context 8947 **/ 8948 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context) 8949 : NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment", 8950 "Test verifies that invalid alignment of offset qualifiers cause compilation failure") 8951 { 8952 /* Nothing to be done here */ 8953 } 8954 8955 /** Constructor 8956 * 8957 * @param context Test framework context 8958 * @param name Test name 8959 * @param description Test description 8960 **/ 8961 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest( 8962 deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description) 8963 : NegativeTestBase(context, name, description) 8964 { 8965 /* Nothing to be done here */ 8966 } 8967 8968 /** Source for given test case and stage 8969 * 8970 * @param test_case_index Index of test case 8971 * @param stage Shader stage 8972 * 8973 * @return Shader source 8974 **/ 8975 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, 8976 Utils::Shader::STAGES stage) 8977 { 8978 static const GLchar* cs = "#version 430 core\n" 8979 "#extension GL_ARB_enhanced_layouts : require\n" 8980 "\n" 8981 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 8982 "\n" 8983 "layout (std140) uniform Block {\n" 8984 " layout (offset = OFFSET) TYPE member;\n" 8985 "} block;\n" 8986 "\n" 8987 "writeonly uniform image2D uni_image;\n" 8988 "\n" 8989 "void main()\n" 8990 "{\n" 8991 " vec4 result = vec4(1, 0, 0.5, 1);\n" 8992 "\n" 8993 " if (TYPE(1) == block.member)\n" 8994 " {\n" 8995 " result = vec4(1, 1, 1, 1);\n" 8996 " }\n" 8997 "\n" 8998 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 8999 "}\n" 9000 "\n"; 9001 static const GLchar* fs = "#version 430 core\n" 9002 "#extension GL_ARB_enhanced_layouts : require\n" 9003 "\n" 9004 "in vec4 gs_fs;\n" 9005 "out vec4 fs_out;\n" 9006 "\n" 9007 "void main()\n" 9008 "{\n" 9009 " fs_out = gs_fs;\n" 9010 "}\n" 9011 "\n"; 9012 static const GLchar* fs_tested = "#version 430 core\n" 9013 "#extension GL_ARB_enhanced_layouts : require\n" 9014 "\n" 9015 "layout (std140) uniform Block {\n" 9016 " layout (offset = OFFSET) TYPE member;\n" 9017 "} block;\n" 9018 "\n" 9019 "in vec4 gs_fs;\n" 9020 "out vec4 fs_out;\n" 9021 "\n" 9022 "void main()\n" 9023 "{\n" 9024 " if (TYPE(1) == block.member)\n" 9025 " {\n" 9026 " fs_out = vec4(1, 1, 1, 1);\n" 9027 " }\n" 9028 "\n" 9029 " fs_out += gs_fs;\n" 9030 "}\n" 9031 "\n"; 9032 static const GLchar* gs = "#version 430 core\n" 9033 "#extension GL_ARB_enhanced_layouts : require\n" 9034 "\n" 9035 "layout(points) in;\n" 9036 "layout(triangle_strip, max_vertices = 4) out;\n" 9037 "\n" 9038 "in vec4 tes_gs[];\n" 9039 "out vec4 gs_fs;\n" 9040 "\n" 9041 "void main()\n" 9042 "{\n" 9043 " gs_fs = tes_gs[0];\n" 9044 " gl_Position = vec4(-1, -1, 0, 1);\n" 9045 " EmitVertex();\n" 9046 " gs_fs = tes_gs[0];\n" 9047 " gl_Position = vec4(-1, 1, 0, 1);\n" 9048 " EmitVertex();\n" 9049 " gs_fs = tes_gs[0];\n" 9050 " gl_Position = vec4(1, -1, 0, 1);\n" 9051 " EmitVertex();\n" 9052 " gs_fs = tes_gs[0];\n" 9053 " gl_Position = vec4(1, 1, 0, 1);\n" 9054 " EmitVertex();\n" 9055 "}\n" 9056 "\n"; 9057 static const GLchar* gs_tested = "#version 430 core\n" 9058 "#extension GL_ARB_enhanced_layouts : require\n" 9059 "\n" 9060 "layout(points) in;\n" 9061 "layout(triangle_strip, max_vertices = 4) out;\n" 9062 "\n" 9063 "layout (std140) uniform Block {\n" 9064 " layout (offset = OFFSET) TYPE member;\n" 9065 "} block;\n" 9066 "\n" 9067 "in vec4 tes_gs[];\n" 9068 "out vec4 gs_fs;\n" 9069 "\n" 9070 "void main()\n" 9071 "{\n" 9072 " if (TYPE(1) == block.member)\n" 9073 " {\n" 9074 " gs_fs = vec4(1, 1, 1, 1);\n" 9075 " }\n" 9076 "\n" 9077 " gs_fs += tes_gs[0];\n" 9078 " gl_Position = vec4(-1, -1, 0, 1);\n" 9079 " EmitVertex();\n" 9080 " gs_fs += tes_gs[0];\n" 9081 " gl_Position = vec4(-1, 1, 0, 1);\n" 9082 " EmitVertex();\n" 9083 " gs_fs += tes_gs[0];\n" 9084 " gl_Position = vec4(1, -1, 0, 1);\n" 9085 " EmitVertex();\n" 9086 " gs_fs += tes_gs[0];\n" 9087 " gl_Position = vec4(1, 1, 0, 1);\n" 9088 " EmitVertex();\n" 9089 "}\n" 9090 "\n"; 9091 static const GLchar* tcs = "#version 430 core\n" 9092 "#extension GL_ARB_enhanced_layouts : require\n" 9093 "\n" 9094 "layout(vertices = 1) out;\n" 9095 "\n" 9096 "in vec4 vs_tcs[];\n" 9097 "out vec4 tcs_tes[];\n" 9098 "\n" 9099 "void main()\n" 9100 "{\n" 9101 "\n" 9102 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 9103 "\n" 9104 " gl_TessLevelOuter[0] = 1.0;\n" 9105 " gl_TessLevelOuter[1] = 1.0;\n" 9106 " gl_TessLevelOuter[2] = 1.0;\n" 9107 " gl_TessLevelOuter[3] = 1.0;\n" 9108 " gl_TessLevelInner[0] = 1.0;\n" 9109 " gl_TessLevelInner[1] = 1.0;\n" 9110 "}\n" 9111 "\n"; 9112 static const GLchar* tcs_tested = "#version 430 core\n" 9113 "#extension GL_ARB_enhanced_layouts : require\n" 9114 "\n" 9115 "layout(vertices = 1) out;\n" 9116 "\n" 9117 "layout (std140) uniform Block {\n" 9118 " layout (offset = OFFSET) TYPE member;\n" 9119 "} block;\n" 9120 "\n" 9121 "in vec4 vs_tcs[];\n" 9122 "out vec4 tcs_tes[];\n" 9123 "\n" 9124 "void main()\n" 9125 "{\n" 9126 " if (TYPE(1) == block.member)\n" 9127 " {\n" 9128 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n" 9129 " }\n" 9130 "\n" 9131 "\n" 9132 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n" 9133 "\n" 9134 " gl_TessLevelOuter[0] = 1.0;\n" 9135 " gl_TessLevelOuter[1] = 1.0;\n" 9136 " gl_TessLevelOuter[2] = 1.0;\n" 9137 " gl_TessLevelOuter[3] = 1.0;\n" 9138 " gl_TessLevelInner[0] = 1.0;\n" 9139 " gl_TessLevelInner[1] = 1.0;\n" 9140 "}\n" 9141 "\n"; 9142 static const GLchar* tes = "#version 430 core\n" 9143 "#extension GL_ARB_enhanced_layouts : require\n" 9144 "\n" 9145 "layout(isolines, point_mode) in;\n" 9146 "\n" 9147 "in vec4 tcs_tes[];\n" 9148 "out vec4 tes_gs;\n" 9149 "\n" 9150 "void main()\n" 9151 "{\n" 9152 " tes_gs = tcs_tes[0];\n" 9153 "}\n" 9154 "\n"; 9155 static const GLchar* tes_tested = "#version 430 core\n" 9156 "#extension GL_ARB_enhanced_layouts : require\n" 9157 "\n" 9158 "layout(isolines, point_mode) in;\n" 9159 "\n" 9160 "layout (std140) uniform Block {\n" 9161 " layout (offset = OFFSET) TYPE member;\n" 9162 "} block;\n" 9163 "\n" 9164 "in vec4 tcs_tes[];\n" 9165 "out vec4 tes_gs;\n" 9166 "\n" 9167 "void main()\n" 9168 "{\n" 9169 " if (TYPE(1) == block.member)\n" 9170 " {\n" 9171 " tes_gs = vec4(1, 1, 1, 1);\n" 9172 " }\n" 9173 "\n" 9174 " tes_gs += tcs_tes[0];\n" 9175 "}\n" 9176 "\n"; 9177 static const GLchar* vs = "#version 430 core\n" 9178 "#extension GL_ARB_enhanced_layouts : require\n" 9179 "\n" 9180 "in vec4 in_vs;\n" 9181 "out vec4 vs_tcs;\n" 9182 "\n" 9183 "void main()\n" 9184 "{\n" 9185 " vs_tcs = in_vs;\n" 9186 "}\n" 9187 "\n"; 9188 static const GLchar* vs_tested = "#version 430 core\n" 9189 "#extension GL_ARB_enhanced_layouts : require\n" 9190 "\n" 9191 "layout (std140) uniform Block {\n" 9192 " layout (offset = OFFSET) TYPE member;\n" 9193 "} block;\n" 9194 "\n" 9195 "in vec4 in_vs;\n" 9196 "out vec4 vs_tcs;\n" 9197 "\n" 9198 "void main()\n" 9199 "{\n" 9200 " if (TYPE(1) == block.member)\n" 9201 " {\n" 9202 " vs_tcs = vec4(1, 1, 1, 1);\n" 9203 " }\n" 9204 "\n" 9205 " vs_tcs += in_vs;\n" 9206 "}\n" 9207 "\n"; 9208 9209 std::string source; 9210 testCase& test_case = m_test_cases[test_case_index]; 9211 9212 if (test_case.m_stage == stage) 9213 { 9214 GLchar buffer[16]; 9215 const GLuint offset = test_case.m_offset; 9216 size_t position = 0; 9217 const Utils::Type& type = test_case.m_type; 9218 const GLchar* type_name = type.GetGLSLTypeName(); 9219 9220 sprintf(buffer, "%d", offset); 9221 9222 switch (stage) 9223 { 9224 case Utils::Shader::COMPUTE: 9225 source = cs; 9226 break; 9227 case Utils::Shader::FRAGMENT: 9228 source = fs_tested; 9229 break; 9230 case Utils::Shader::GEOMETRY: 9231 source = gs_tested; 9232 break; 9233 case Utils::Shader::TESS_CTRL: 9234 source = tcs_tested; 9235 break; 9236 case Utils::Shader::TESS_EVAL: 9237 source = tes_tested; 9238 break; 9239 case Utils::Shader::VERTEX: 9240 source = vs_tested; 9241 break; 9242 default: 9243 TCU_FAIL("Invalid enum"); 9244 } 9245 9246 Utils::replaceToken("OFFSET", position, buffer, source); 9247 Utils::replaceToken("TYPE", position, type_name, source); 9248 Utils::replaceToken("TYPE", position, type_name, source); 9249 } 9250 else 9251 { 9252 switch (stage) 9253 { 9254 case Utils::Shader::FRAGMENT: 9255 source = fs; 9256 break; 9257 case Utils::Shader::GEOMETRY: 9258 source = gs; 9259 break; 9260 case Utils::Shader::TESS_CTRL: 9261 source = tcs; 9262 break; 9263 case Utils::Shader::TESS_EVAL: 9264 source = tes; 9265 break; 9266 case Utils::Shader::VERTEX: 9267 source = vs; 9268 break; 9269 default: 9270 TCU_FAIL("Invalid enum"); 9271 } 9272 } 9273 9274 return source; 9275 } 9276 9277 /** Get description of test case 9278 * 9279 * @param test_case_index Index of test case 9280 * 9281 * @return Type name and offset 9282 **/ 9283 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index) 9284 { 9285 std::stringstream stream; 9286 testCase& test_case = m_test_cases[test_case_index]; 9287 9288 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset; 9289 9290 return stream.str(); 9291 } 9292 9293 /** Get number of test cases 9294 * 9295 * @return Number of test cases 9296 **/ 9297 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber() 9298 { 9299 return static_cast<GLuint>(m_test_cases.size()); 9300 } 9301 9302 /** Get the maximum size for an uniform block 9303 * 9304 * @return The maximum size in basic machine units of a uniform block. 9305 **/ 9306 GLint UniformBlockMemberInvalidOffsetAlignmentTest::getMaxBlockSize() 9307 { 9308 const Functions& gl = m_context.getRenderContext().getFunctions(); 9309 GLint max_size = 0; 9310 9311 gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size); 9312 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 9313 9314 return max_size; 9315 } 9316 9317 /** Selects if "compute" stage is relevant for test 9318 * 9319 * @param test_case_index Index of test case 9320 * 9321 * @return true when tested stage is compute 9322 **/ 9323 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index) 9324 { 9325 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage); 9326 } 9327 9328 /** Selects if compilation failure is expected result 9329 * 9330 * @param test_case_index Index of test case 9331 * 9332 * @return should_fail field from testCase 9333 **/ 9334 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index) 9335 { 9336 return m_test_cases[test_case_index].m_should_fail; 9337 } 9338 9339 /** Checks if stage is supported 9340 * 9341 * @param stage ignored 9342 * 9343 * @return true 9344 **/ 9345 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */) 9346 { 9347 return true; 9348 } 9349 9350 /** Prepare all test cases 9351 * 9352 **/ 9353 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit() 9354 { 9355 const GLuint n_types = getTypesNumber(); 9356 bool stage_support[Utils::Shader::STAGE_MAX]; 9357 9358 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 9359 { 9360 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage); 9361 } 9362 9363 for (GLuint i = 0; i < n_types; ++i) 9364 { 9365 const Utils::Type& type = getType(i); 9366 const GLuint alignment = type.GetBaseAlignment(false); 9367 const GLuint type_size = type.GetSize(true); 9368 const GLuint sec_to_end = getMaxBlockSize() - 2 * type_size; 9369 9370 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 9371 { 9372 if (false == stage_support[stage]) 9373 { 9374 continue; 9375 } 9376 9377 for (GLuint offset = 0; offset <= type_size; ++offset) 9378 { 9379 const GLuint modulo = offset % alignment; 9380 const bool is_aligned = (0 == modulo) ? true : false; 9381 const bool should_fail = !is_aligned; 9382 9383 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type }; 9384 9385 m_test_cases.push_back(test_case); 9386 } 9387 9388 for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset) 9389 { 9390 const GLuint modulo = offset % alignment; 9391 const bool is_aligned = (0 == modulo) ? true : false; 9392 const bool should_fail = !is_aligned; 9393 9394 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type }; 9395 9396 m_test_cases.push_back(test_case); 9397 } 9398 } 9399 } 9400 } 9401 9402 /** Constructor 9403 * 9404 * @param context Test framework context 9405 **/ 9406 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context) 9407 : NegativeTestBase(context, "uniform_block_member_overlapping_offsets", 9408 "Test verifies that overlapping offsets qualifiers cause compilation failure") 9409 { 9410 /* Nothing to be done here */ 9411 } 9412 9413 /** Constructor 9414 * 9415 * @param context Test framework context 9416 * @param name Test name 9417 * @param description Test description 9418 **/ 9419 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context, 9420 const glw::GLchar* name, 9421 const glw::GLchar* description) 9422 : NegativeTestBase(context, name, description) 9423 { 9424 /* Nothing to be done here */ 9425 } 9426 9427 /** Source for given test case and stage 9428 * 9429 * @param test_case_index Index of test case 9430 * @param stage Shader stage 9431 * 9432 * @return Shader source 9433 **/ 9434 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, 9435 Utils::Shader::STAGES stage) 9436 { 9437 static const GLchar* cs = "#version 430 core\n" 9438 "#extension GL_ARB_enhanced_layouts : require\n" 9439 "\n" 9440 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 9441 "\n" 9442 "layout (std140) uniform Block {\n" 9443 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 9444 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 9445 "} block;\n" 9446 "\n" 9447 "writeonly uniform image2D uni_image;\n" 9448 "\n" 9449 "void main()\n" 9450 "{\n" 9451 " vec4 result = vec4(1, 0, 0.5, 1);\n" 9452 "\n" 9453 " if ((BOY_TYPE(1) == block.boy) ||\n" 9454 " (MAN_TYPE(0) == block.man) )\n" 9455 " {\n" 9456 " result = vec4(1, 1, 1, 1);\n" 9457 " }\n" 9458 "\n" 9459 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 9460 "}\n" 9461 "\n"; 9462 static const GLchar* fs = "#version 430 core\n" 9463 "#extension GL_ARB_enhanced_layouts : require\n" 9464 "\n" 9465 "in vec4 gs_fs;\n" 9466 "out vec4 fs_out;\n" 9467 "\n" 9468 "void main()\n" 9469 "{\n" 9470 " fs_out = gs_fs;\n" 9471 "}\n" 9472 "\n"; 9473 static const GLchar* fs_tested = "#version 430 core\n" 9474 "#extension GL_ARB_enhanced_layouts : require\n" 9475 "\n" 9476 "layout (std140) uniform Block {\n" 9477 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 9478 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 9479 "} block;\n" 9480 "\n" 9481 "in vec4 gs_fs;\n" 9482 "out vec4 fs_out;\n" 9483 "\n" 9484 "void main()\n" 9485 "{\n" 9486 " if ((BOY_TYPE(1) == block.boy) ||\n" 9487 " (MAN_TYPE(0) == block.man) )\n" 9488 " {\n" 9489 " fs_out = vec4(1, 1, 1, 1);\n" 9490 " }\n" 9491 "\n" 9492 " fs_out += gs_fs;\n" 9493 "}\n" 9494 "\n"; 9495 static const GLchar* gs = "#version 430 core\n" 9496 "#extension GL_ARB_enhanced_layouts : require\n" 9497 "\n" 9498 "layout(points) in;\n" 9499 "layout(triangle_strip, max_vertices = 4) out;\n" 9500 "\n" 9501 "in vec4 tes_gs[];\n" 9502 "out vec4 gs_fs;\n" 9503 "\n" 9504 "void main()\n" 9505 "{\n" 9506 " gs_fs = tes_gs[0];\n" 9507 " gl_Position = vec4(-1, -1, 0, 1);\n" 9508 " EmitVertex();\n" 9509 " gs_fs = tes_gs[0];\n" 9510 " gl_Position = vec4(-1, 1, 0, 1);\n" 9511 " EmitVertex();\n" 9512 " gs_fs = tes_gs[0];\n" 9513 " gl_Position = vec4(1, -1, 0, 1);\n" 9514 " EmitVertex();\n" 9515 " gs_fs = tes_gs[0];\n" 9516 " gl_Position = vec4(1, 1, 0, 1);\n" 9517 " EmitVertex();\n" 9518 "}\n" 9519 "\n"; 9520 static const GLchar* gs_tested = "#version 430 core\n" 9521 "#extension GL_ARB_enhanced_layouts : require\n" 9522 "\n" 9523 "layout(points) in;\n" 9524 "layout(triangle_strip, max_vertices = 4) out;\n" 9525 "\n" 9526 "layout (std140) uniform Block {\n" 9527 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 9528 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 9529 "} block;\n" 9530 "\n" 9531 "in vec4 tes_gs[];\n" 9532 "out vec4 gs_fs;\n" 9533 "\n" 9534 "void main()\n" 9535 "{\n" 9536 " if ((BOY_TYPE(1) == block.boy) ||\n" 9537 " (MAN_TYPE(0) == block.man) )\n" 9538 " {\n" 9539 " gs_fs = vec4(1, 1, 1, 1);\n" 9540 " }\n" 9541 "\n" 9542 " gs_fs += tes_gs[0];\n" 9543 " gl_Position = vec4(-1, -1, 0, 1);\n" 9544 " EmitVertex();\n" 9545 " gs_fs += tes_gs[0];\n" 9546 " gl_Position = vec4(-1, 1, 0, 1);\n" 9547 " EmitVertex();\n" 9548 " gs_fs += tes_gs[0];\n" 9549 " gl_Position = vec4(1, -1, 0, 1);\n" 9550 " EmitVertex();\n" 9551 " gs_fs += tes_gs[0];\n" 9552 " gl_Position = vec4(1, 1, 0, 1);\n" 9553 " EmitVertex();\n" 9554 "}\n" 9555 "\n"; 9556 static const GLchar* tcs = "#version 430 core\n" 9557 "#extension GL_ARB_enhanced_layouts : require\n" 9558 "\n" 9559 "layout(vertices = 1) out;\n" 9560 "\n" 9561 "in vec4 vs_tcs[];\n" 9562 "out vec4 tcs_tes[];\n" 9563 "\n" 9564 "void main()\n" 9565 "{\n" 9566 "\n" 9567 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 9568 "\n" 9569 " gl_TessLevelOuter[0] = 1.0;\n" 9570 " gl_TessLevelOuter[1] = 1.0;\n" 9571 " gl_TessLevelOuter[2] = 1.0;\n" 9572 " gl_TessLevelOuter[3] = 1.0;\n" 9573 " gl_TessLevelInner[0] = 1.0;\n" 9574 " gl_TessLevelInner[1] = 1.0;\n" 9575 "}\n" 9576 "\n"; 9577 static const GLchar* tcs_tested = "#version 430 core\n" 9578 "#extension GL_ARB_enhanced_layouts : require\n" 9579 "\n" 9580 "layout(vertices = 1) out;\n" 9581 "\n" 9582 "layout (std140) uniform Block {\n" 9583 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 9584 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 9585 "} block;\n" 9586 "\n" 9587 "in vec4 vs_tcs[];\n" 9588 "out vec4 tcs_tes[];\n" 9589 "\n" 9590 "void main()\n" 9591 "{\n" 9592 " if ((BOY_TYPE(1) == block.boy) ||\n" 9593 " (MAN_TYPE(0) == block.man) )\n" 9594 " {\n" 9595 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n" 9596 " }\n" 9597 "\n" 9598 "\n" 9599 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n" 9600 "\n" 9601 " gl_TessLevelOuter[0] = 1.0;\n" 9602 " gl_TessLevelOuter[1] = 1.0;\n" 9603 " gl_TessLevelOuter[2] = 1.0;\n" 9604 " gl_TessLevelOuter[3] = 1.0;\n" 9605 " gl_TessLevelInner[0] = 1.0;\n" 9606 " gl_TessLevelInner[1] = 1.0;\n" 9607 "}\n" 9608 "\n"; 9609 static const GLchar* tes = "#version 430 core\n" 9610 "#extension GL_ARB_enhanced_layouts : require\n" 9611 "\n" 9612 "layout(isolines, point_mode) in;\n" 9613 "\n" 9614 "in vec4 tcs_tes[];\n" 9615 "out vec4 tes_gs;\n" 9616 "\n" 9617 "void main()\n" 9618 "{\n" 9619 " tes_gs = tcs_tes[0];\n" 9620 "}\n" 9621 "\n"; 9622 static const GLchar* tes_tested = "#version 430 core\n" 9623 "#extension GL_ARB_enhanced_layouts : require\n" 9624 "\n" 9625 "layout(isolines, point_mode) in;\n" 9626 "\n" 9627 "layout (std140) uniform Block {\n" 9628 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 9629 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 9630 "} block;\n" 9631 "\n" 9632 "in vec4 tcs_tes[];\n" 9633 "out vec4 tes_gs;\n" 9634 "\n" 9635 "void main()\n" 9636 "{\n" 9637 " if ((BOY_TYPE(1) == block.boy) ||\n" 9638 " (MAN_TYPE(0) == block.man) )\n" 9639 " {\n" 9640 " tes_gs = vec4(1, 1, 1, 1);\n" 9641 " }\n" 9642 "\n" 9643 " tes_gs += tcs_tes[0];\n" 9644 "}\n" 9645 "\n"; 9646 static const GLchar* vs = "#version 430 core\n" 9647 "#extension GL_ARB_enhanced_layouts : require\n" 9648 "\n" 9649 "in vec4 in_vs;\n" 9650 "out vec4 vs_tcs;\n" 9651 "\n" 9652 "void main()\n" 9653 "{\n" 9654 " vs_tcs = in_vs;\n" 9655 "}\n" 9656 "\n"; 9657 static const GLchar* vs_tested = "#version 430 core\n" 9658 "#extension GL_ARB_enhanced_layouts : require\n" 9659 "\n" 9660 "layout (std140) uniform Block {\n" 9661 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 9662 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 9663 "} block;\n" 9664 "\n" 9665 "in vec4 in_vs;\n" 9666 "out vec4 vs_tcs;\n" 9667 "\n" 9668 "void main()\n" 9669 "{\n" 9670 " if ((BOY_TYPE(1) == block.boy) ||\n" 9671 " (MAN_TYPE(0) == block.man) )\n" 9672 " {\n" 9673 " vs_tcs = vec4(1, 1, 1, 1);\n" 9674 " }\n" 9675 "\n" 9676 " vs_tcs += in_vs;\n" 9677 "}\n" 9678 "\n"; 9679 9680 std::string source; 9681 testCase& test_case = m_test_cases[test_case_index]; 9682 9683 if (test_case.m_stage == stage) 9684 { 9685 GLchar buffer[16]; 9686 const GLuint boy_offset = test_case.m_boy_offset; 9687 const Utils::Type& boy_type = test_case.m_boy_type; 9688 const GLchar* boy_type_name = boy_type.GetGLSLTypeName(); 9689 const GLuint man_offset = test_case.m_man_offset; 9690 const Utils::Type& man_type = test_case.m_man_type; 9691 const GLchar* man_type_name = man_type.GetGLSLTypeName(); 9692 size_t position = 0; 9693 9694 switch (stage) 9695 { 9696 case Utils::Shader::COMPUTE: 9697 source = cs; 9698 break; 9699 case Utils::Shader::FRAGMENT: 9700 source = fs_tested; 9701 break; 9702 case Utils::Shader::GEOMETRY: 9703 source = gs_tested; 9704 break; 9705 case Utils::Shader::TESS_CTRL: 9706 source = tcs_tested; 9707 break; 9708 case Utils::Shader::TESS_EVAL: 9709 source = tes_tested; 9710 break; 9711 case Utils::Shader::VERTEX: 9712 source = vs_tested; 9713 break; 9714 default: 9715 TCU_FAIL("Invalid enum"); 9716 } 9717 9718 sprintf(buffer, "%d", boy_offset); 9719 Utils::replaceToken("BOY_OFFSET", position, buffer, source); 9720 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source); 9721 sprintf(buffer, "%d", man_offset); 9722 Utils::replaceToken("MAN_OFFSET", position, buffer, source); 9723 Utils::replaceToken("MAN_TYPE", position, man_type_name, source); 9724 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source); 9725 Utils::replaceToken("MAN_TYPE", position, man_type_name, source); 9726 } 9727 else 9728 { 9729 switch (stage) 9730 { 9731 case Utils::Shader::FRAGMENT: 9732 source = fs; 9733 break; 9734 case Utils::Shader::GEOMETRY: 9735 source = gs; 9736 break; 9737 case Utils::Shader::TESS_CTRL: 9738 source = tcs; 9739 break; 9740 case Utils::Shader::TESS_EVAL: 9741 source = tes; 9742 break; 9743 case Utils::Shader::VERTEX: 9744 source = vs; 9745 break; 9746 default: 9747 TCU_FAIL("Invalid enum"); 9748 } 9749 } 9750 9751 return source; 9752 } 9753 9754 /** Get description of test case 9755 * 9756 * @param test_case_index Index of test case 9757 * 9758 * @return Type name and offset 9759 **/ 9760 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index) 9761 { 9762 std::stringstream stream; 9763 testCase& test_case = m_test_cases[test_case_index]; 9764 9765 stream << "Type: " << test_case.m_boy_type.GetGLSLTypeName() << ", offset: " << test_case.m_boy_offset 9766 << ". Type: " << test_case.m_man_type.GetGLSLTypeName() << ", offset: " << test_case.m_man_offset; 9767 9768 return stream.str(); 9769 } 9770 9771 /** Get number of test cases 9772 * 9773 * @return Number of test cases 9774 **/ 9775 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber() 9776 { 9777 return static_cast<GLuint>(m_test_cases.size()); 9778 } 9779 9780 /** Selects if "compute" stage is relevant for test 9781 * 9782 * @param test_case_index Index of test case 9783 * 9784 * @return true when tested stage is compute 9785 **/ 9786 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index) 9787 { 9788 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage); 9789 } 9790 9791 /** Checks if stage is supported 9792 * 9793 * @param stage ignored 9794 * 9795 * @return true 9796 **/ 9797 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */) 9798 { 9799 return true; 9800 } 9801 9802 /** Prepare all test cases 9803 * 9804 **/ 9805 void UniformBlockMemberOverlappingOffsetsTest::testInit() 9806 { 9807 const GLuint n_types = getTypesNumber(); 9808 bool stage_support[Utils::Shader::STAGE_MAX]; 9809 9810 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 9811 { 9812 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage); 9813 } 9814 9815 for (GLuint i = 0; i < n_types; ++i) 9816 { 9817 const Utils::Type& boy_type = getType(i); 9818 const GLuint boy_size = boy_type.GetActualAlignment(1 /* align */, false /* is_array*/); 9819 9820 for (GLuint j = 0; j < n_types; ++j) 9821 { 9822 const Utils::Type& man_type = getType(j); 9823 const GLuint man_align = man_type.GetBaseAlignment(false); 9824 const GLuint man_size = man_type.GetActualAlignment(1 /* align */, false /* is_array*/); 9825 9826 const GLuint boy_offset = lcm(boy_size, man_size); 9827 const GLuint man_after_start = boy_offset + 1; 9828 const GLuint man_after_off = man_type.GetActualOffset(man_after_start, man_size); 9829 const GLuint man_before_start = boy_offset - man_align; 9830 const GLuint man_before_off = man_type.GetActualOffset(man_before_start, man_size); 9831 9832 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 9833 { 9834 if (false == stage_support[stage]) 9835 { 9836 continue; 9837 } 9838 9839 if ((boy_offset > man_before_off) && (boy_offset < man_before_off + man_size)) 9840 { 9841 testCase test_case = { boy_offset, boy_type, man_before_off, man_type, 9842 (Utils::Shader::STAGES)stage }; 9843 9844 m_test_cases.push_back(test_case); 9845 } 9846 9847 if ((boy_offset < man_after_off) && (boy_offset + boy_size > man_after_off)) 9848 { 9849 testCase test_case = { boy_offset, boy_type, man_after_off, man_type, 9850 (Utils::Shader::STAGES)stage }; 9851 9852 m_test_cases.push_back(test_case); 9853 } 9854 9855 /* Boy offset, should be fine for both types */ 9856 testCase test_case = { boy_offset, boy_type, boy_offset, man_type, (Utils::Shader::STAGES)stage }; 9857 9858 m_test_cases.push_back(test_case); 9859 } 9860 } 9861 } 9862 } 9863 9864 /** Find greatest common divisor for a and b 9865 * 9866 * @param a A argument 9867 * @param b B argument 9868 * 9869 * @return Found gcd value 9870 **/ 9871 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b) 9872 { 9873 if ((0 != a) && (0 == b)) 9874 { 9875 return a; 9876 } 9877 else 9878 { 9879 GLuint greater = std::max(a, b); 9880 GLuint lesser = std::min(a, b); 9881 9882 return gcd(lesser, greater % lesser); 9883 } 9884 } 9885 9886 /** Find lowest common multiple for a and b 9887 * 9888 * @param a A argument 9889 * @param b B argument 9890 * 9891 * @return Found gcd value 9892 **/ 9893 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b) 9894 { 9895 return (a * b) / gcd(a, b); 9896 } 9897 9898 /** Constructor 9899 * 9900 * @param context Test framework context 9901 **/ 9902 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context) 9903 : NegativeTestBase(context, "uniform_block_member_align_non_power_of_2", 9904 "Test verifies that align qualifier requires value that is a power of 2") 9905 { 9906 /* Nothing to be done here */ 9907 } 9908 9909 /** Constructor 9910 * 9911 * @param context Test framework context 9912 * @param name Test name 9913 * @param description Test description 9914 **/ 9915 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context, 9916 const glw::GLchar* name, 9917 const glw::GLchar* description) 9918 : NegativeTestBase(context, name, description) 9919 { 9920 /* Nothing to be done here */ 9921 } 9922 9923 /** Source for given test case and stage 9924 * 9925 * @param test_case_index Index of test case 9926 * @param stage Shader stage 9927 * 9928 * @return Shader source 9929 **/ 9930 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 9931 { 9932 static const GLchar* cs = "#version 430 core\n" 9933 "#extension GL_ARB_enhanced_layouts : require\n" 9934 "\n" 9935 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 9936 "\n" 9937 "layout (std140) uniform Block {\n" 9938 " vec4 boy;\n" 9939 " layout (align = ALIGN) TYPE man;\n" 9940 "} block;\n" 9941 "\n" 9942 "writeonly uniform image2D uni_image;\n" 9943 "\n" 9944 "void main()\n" 9945 "{\n" 9946 " vec4 result = vec4(1, 0, 0.5, 1);\n" 9947 "\n" 9948 " if (TYPE(0) == block.man)\n" 9949 " {\n" 9950 " result = vec4(1, 1, 1, 1) - block.boy;\n" 9951 " }\n" 9952 "\n" 9953 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 9954 "}\n" 9955 "\n"; 9956 static const GLchar* fs = "#version 430 core\n" 9957 "#extension GL_ARB_enhanced_layouts : require\n" 9958 "\n" 9959 "in vec4 gs_fs;\n" 9960 "out vec4 fs_out;\n" 9961 "\n" 9962 "void main()\n" 9963 "{\n" 9964 " fs_out = gs_fs;\n" 9965 "}\n" 9966 "\n"; 9967 static const GLchar* fs_tested = "#version 430 core\n" 9968 "#extension GL_ARB_enhanced_layouts : require\n" 9969 "\n" 9970 "layout (std140) uniform Block {\n" 9971 " vec4 boy;\n" 9972 " layout (align = ALIGN) TYPE man;\n" 9973 "} block;\n" 9974 "\n" 9975 "in vec4 gs_fs;\n" 9976 "out vec4 fs_out;\n" 9977 "\n" 9978 "void main()\n" 9979 "{\n" 9980 " if (TYPE(0) == block.man)\n" 9981 " {\n" 9982 " fs_out = block.boy;\n" 9983 " }\n" 9984 "\n" 9985 " fs_out += gs_fs;\n" 9986 "}\n" 9987 "\n"; 9988 static const GLchar* gs = "#version 430 core\n" 9989 "#extension GL_ARB_enhanced_layouts : require\n" 9990 "\n" 9991 "layout(points) in;\n" 9992 "layout(triangle_strip, max_vertices = 4) out;\n" 9993 "\n" 9994 "in vec4 tes_gs[];\n" 9995 "out vec4 gs_fs;\n" 9996 "\n" 9997 "void main()\n" 9998 "{\n" 9999 " gs_fs = tes_gs[0];\n" 10000 " gl_Position = vec4(-1, -1, 0, 1);\n" 10001 " EmitVertex();\n" 10002 " gs_fs = tes_gs[0];\n" 10003 " gl_Position = vec4(-1, 1, 0, 1);\n" 10004 " EmitVertex();\n" 10005 " gs_fs = tes_gs[0];\n" 10006 " gl_Position = vec4(1, -1, 0, 1);\n" 10007 " EmitVertex();\n" 10008 " gs_fs = tes_gs[0];\n" 10009 " gl_Position = vec4(1, 1, 0, 1);\n" 10010 " EmitVertex();\n" 10011 "}\n" 10012 "\n"; 10013 static const GLchar* gs_tested = "#version 430 core\n" 10014 "#extension GL_ARB_enhanced_layouts : require\n" 10015 "\n" 10016 "layout(points) in;\n" 10017 "layout(triangle_strip, max_vertices = 4) out;\n" 10018 "\n" 10019 "layout (std140) uniform Block {\n" 10020 " vec4 boy;\n" 10021 " layout (align = ALIGN) TYPE man;\n" 10022 "} block;\n" 10023 "\n" 10024 "in vec4 tes_gs[];\n" 10025 "out vec4 gs_fs;\n" 10026 "\n" 10027 "void main()\n" 10028 "{\n" 10029 " if (TYPE(0) == block.man)\n" 10030 " {\n" 10031 " gs_fs = block.boy;\n" 10032 " }\n" 10033 "\n" 10034 " gs_fs += tes_gs[0];\n" 10035 " gl_Position = vec4(-1, -1, 0, 1);\n" 10036 " EmitVertex();\n" 10037 " gs_fs += tes_gs[0];\n" 10038 " gl_Position = vec4(-1, 1, 0, 1);\n" 10039 " EmitVertex();\n" 10040 " gs_fs += tes_gs[0];\n" 10041 " gl_Position = vec4(1, -1, 0, 1);\n" 10042 " EmitVertex();\n" 10043 " gs_fs += tes_gs[0];\n" 10044 " gl_Position = vec4(1, 1, 0, 1);\n" 10045 " EmitVertex();\n" 10046 "}\n" 10047 "\n"; 10048 static const GLchar* tcs = "#version 430 core\n" 10049 "#extension GL_ARB_enhanced_layouts : require\n" 10050 "\n" 10051 "layout(vertices = 1) out;\n" 10052 "\n" 10053 "in vec4 vs_tcs[];\n" 10054 "out vec4 tcs_tes[];\n" 10055 "\n" 10056 "void main()\n" 10057 "{\n" 10058 "\n" 10059 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 10060 "\n" 10061 " gl_TessLevelOuter[0] = 1.0;\n" 10062 " gl_TessLevelOuter[1] = 1.0;\n" 10063 " gl_TessLevelOuter[2] = 1.0;\n" 10064 " gl_TessLevelOuter[3] = 1.0;\n" 10065 " gl_TessLevelInner[0] = 1.0;\n" 10066 " gl_TessLevelInner[1] = 1.0;\n" 10067 "}\n" 10068 "\n"; 10069 static const GLchar* tcs_tested = "#version 430 core\n" 10070 "#extension GL_ARB_enhanced_layouts : require\n" 10071 "\n" 10072 "layout(vertices = 1) out;\n" 10073 "\n" 10074 "layout (std140) uniform Block {\n" 10075 " vec4 boy;\n" 10076 " layout (align = ALIGN) TYPE man;\n" 10077 "} block;\n" 10078 "\n" 10079 "in vec4 vs_tcs[];\n" 10080 "out vec4 tcs_tes[];\n" 10081 "\n" 10082 "void main()\n" 10083 "{\n" 10084 " if (TYPE(0) == block.man)\n" 10085 " {\n" 10086 " tcs_tes[gl_InvocationID] = block.boy;\n" 10087 " }\n" 10088 "\n" 10089 "\n" 10090 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n" 10091 "\n" 10092 " gl_TessLevelOuter[0] = 1.0;\n" 10093 " gl_TessLevelOuter[1] = 1.0;\n" 10094 " gl_TessLevelOuter[2] = 1.0;\n" 10095 " gl_TessLevelOuter[3] = 1.0;\n" 10096 " gl_TessLevelInner[0] = 1.0;\n" 10097 " gl_TessLevelInner[1] = 1.0;\n" 10098 "}\n" 10099 "\n"; 10100 static const GLchar* tes = "#version 430 core\n" 10101 "#extension GL_ARB_enhanced_layouts : require\n" 10102 "\n" 10103 "layout(isolines, point_mode) in;\n" 10104 "\n" 10105 "in vec4 tcs_tes[];\n" 10106 "out vec4 tes_gs;\n" 10107 "\n" 10108 "void main()\n" 10109 "{\n" 10110 " tes_gs = tcs_tes[0];\n" 10111 "}\n" 10112 "\n"; 10113 static const GLchar* tes_tested = "#version 430 core\n" 10114 "#extension GL_ARB_enhanced_layouts : require\n" 10115 "\n" 10116 "layout(isolines, point_mode) in;\n" 10117 "\n" 10118 "layout (std140) uniform Block {\n" 10119 " vec4 boy;\n" 10120 " layout (align = ALIGN) TYPE man;\n" 10121 "} block;\n" 10122 "\n" 10123 "in vec4 tcs_tes[];\n" 10124 "out vec4 tes_gs;\n" 10125 "\n" 10126 "void main()\n" 10127 "{\n" 10128 " if (TYPE(0) == block.man)\n" 10129 " {\n" 10130 " tes_gs = block.boy;\n" 10131 " }\n" 10132 "\n" 10133 " tes_gs += tcs_tes[0];\n" 10134 "}\n" 10135 "\n"; 10136 static const GLchar* vs = "#version 430 core\n" 10137 "#extension GL_ARB_enhanced_layouts : require\n" 10138 "\n" 10139 "in vec4 in_vs;\n" 10140 "out vec4 vs_tcs;\n" 10141 "\n" 10142 "void main()\n" 10143 "{\n" 10144 " vs_tcs = in_vs;\n" 10145 "}\n" 10146 "\n"; 10147 static const GLchar* vs_tested = "#version 430 core\n" 10148 "#extension GL_ARB_enhanced_layouts : require\n" 10149 "\n" 10150 "layout (std140) uniform Block {\n" 10151 " vec4 boy;\n" 10152 " layout (align = ALIGN) TYPE man;\n" 10153 "} block;\n" 10154 "\n" 10155 "in vec4 in_vs;\n" 10156 "out vec4 vs_tcs;\n" 10157 "\n" 10158 "void main()\n" 10159 "{\n" 10160 " if (TYPE(0) == block.man)\n" 10161 " {\n" 10162 " vs_tcs = block.boy;\n" 10163 " }\n" 10164 "\n" 10165 " vs_tcs += in_vs;\n" 10166 "}\n" 10167 "\n"; 10168 10169 std::string source; 10170 testCase& test_case = m_test_cases[test_case_index]; 10171 10172 if (test_case.m_stage == stage) 10173 { 10174 GLchar buffer[16]; 10175 const GLuint alignment = test_case.m_alignment; 10176 const Utils::Type& type = test_case.m_type; 10177 const GLchar* type_name = type.GetGLSLTypeName(); 10178 size_t position = 0; 10179 10180 switch (stage) 10181 { 10182 case Utils::Shader::COMPUTE: 10183 source = cs; 10184 break; 10185 case Utils::Shader::FRAGMENT: 10186 source = fs_tested; 10187 break; 10188 case Utils::Shader::GEOMETRY: 10189 source = gs_tested; 10190 break; 10191 case Utils::Shader::TESS_CTRL: 10192 source = tcs_tested; 10193 break; 10194 case Utils::Shader::TESS_EVAL: 10195 source = tes_tested; 10196 break; 10197 case Utils::Shader::VERTEX: 10198 source = vs_tested; 10199 break; 10200 default: 10201 TCU_FAIL("Invalid enum"); 10202 } 10203 10204 sprintf(buffer, "%d", alignment); 10205 Utils::replaceToken("ALIGN", position, buffer, source); 10206 Utils::replaceToken("TYPE", position, type_name, source); 10207 Utils::replaceToken("TYPE", position, type_name, source); 10208 } 10209 else 10210 { 10211 switch (stage) 10212 { 10213 case Utils::Shader::FRAGMENT: 10214 source = fs; 10215 break; 10216 case Utils::Shader::GEOMETRY: 10217 source = gs; 10218 break; 10219 case Utils::Shader::TESS_CTRL: 10220 source = tcs; 10221 break; 10222 case Utils::Shader::TESS_EVAL: 10223 source = tes; 10224 break; 10225 case Utils::Shader::VERTEX: 10226 source = vs; 10227 break; 10228 default: 10229 TCU_FAIL("Invalid enum"); 10230 } 10231 } 10232 10233 return source; 10234 } 10235 10236 /** Get description of test case 10237 * 10238 * @param test_case_index Index of test case 10239 * 10240 * @return Type name and offset 10241 **/ 10242 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index) 10243 { 10244 std::stringstream stream; 10245 testCase& test_case = m_test_cases[test_case_index]; 10246 10247 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment; 10248 10249 return stream.str(); 10250 } 10251 10252 /** Get number of test cases 10253 * 10254 * @return Number of test cases 10255 **/ 10256 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber() 10257 { 10258 return static_cast<GLuint>(m_test_cases.size()); 10259 } 10260 10261 /** Selects if "compute" stage is relevant for test 10262 * 10263 * @param test_case_index Index of test case 10264 * 10265 * @return true when tested stage is compute 10266 **/ 10267 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index) 10268 { 10269 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage); 10270 } 10271 10272 /** Checks if stage is supported 10273 * 10274 * @param ignored 10275 * 10276 * @return true 10277 **/ 10278 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */) 10279 { 10280 return true; 10281 } 10282 10283 /** Selects if compilation failure is expected result 10284 * 10285 * @param test_case_index Index of test case 10286 * 10287 * @return should_fail field from testCase 10288 **/ 10289 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index) 10290 { 10291 return m_test_cases[test_case_index].m_should_fail; 10292 } 10293 10294 /** Prepare all test cases 10295 * 10296 **/ 10297 void UniformBlockMemberAlignNonPowerOf2Test::testInit() 10298 { 10299 static const GLuint dmat4_size = 128; 10300 const GLuint n_types = getTypesNumber(); 10301 bool stage_support[Utils::Shader::STAGE_MAX]; 10302 10303 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 10304 { 10305 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage); 10306 } 10307 10308 for (GLuint j = 0; j < n_types; ++j) 10309 { 10310 const Utils::Type& type = getType(j); 10311 10312 for (GLuint align = 0; align <= dmat4_size; ++align) 10313 { 10314 10315 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST 10316 10317 const bool should_fail = (0 == align) ? false : !isPowerOf2(align); 10318 10319 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */ 10320 10321 const bool should_fail = !isPowerOf2(align); 10322 10323 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */ 10324 10325 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 10326 { 10327 if (false == stage_support[stage]) 10328 { 10329 continue; 10330 } 10331 10332 testCase test_case = { align, type, should_fail, (Utils::Shader::STAGES)stage }; 10333 10334 m_test_cases.push_back(test_case); 10335 } 10336 } 10337 } 10338 } 10339 10340 /** Check if value is power of 2 10341 * 10342 * @param val Tested value 10343 * 10344 * @return true if val is power of 2, false otherwise 10345 **/ 10346 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val) 10347 { 10348 if (0 == val) 10349 { 10350 return false; 10351 } 10352 10353 return (0 == (val & (val - 1))); 10354 } 10355 10356 /** Constructor 10357 * 10358 * @param context Test framework context 10359 **/ 10360 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context& context) 10361 : TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer") 10362 { 10363 } 10364 10365 /** Get interface of program 10366 * 10367 * @param ignored 10368 * @param program_interface Interface of program 10369 * @param varying_passthrough Collection of connections between in and out variables 10370 **/ 10371 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */, 10372 Utils::ProgramInterface& program_interface, 10373 Utils::VaryingPassthrough& varying_passthrough) 10374 { 10375 static const Utils::Type vec4 = Utils::Type::vec4; 10376 10377 #if WRKARD_UNIFORMBLOCKALIGNMENT 10378 10379 static const GLuint block_align = 16; 10380 10381 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */ 10382 10383 static const GLuint block_align = 64; 10384 10385 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */ 10386 10387 static const GLuint vec4_stride = 16; 10388 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */ 10389 10390 /*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual 10391 alignment of a member will be the greater of the specified alignment and the base aligment for the member type 10392 */ 10393 const GLuint first_offset = 0; /* vec4 at 0 */ 10394 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */ 10395 const GLuint third_offset = 10396 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */ 10397 const GLuint fourth_offset = 10398 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */ 10399 const GLuint fifth_offset = 10400 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */ 10401 const GLuint sixth_offset = 10402 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */ 10403 10404 Utils::Interface* structure = program_interface.Structure("Data"); 10405 10406 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4, 10407 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */); 10408 10409 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float, 10410 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(), 10411 Utils::Type::vec4.GetSize() /* offset */); 10412 10413 /* Prepare Block */ 10414 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block"); 10415 10416 vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4, 10417 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */); 10418 10419 vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure, 10420 0 /* n_array_elements */, data_stride, second_offset); 10421 10422 vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure, 10423 2 /* n_array_elements */, data_stride, third_offset); 10424 10425 vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4, 10426 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset); 10427 10428 vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4, 10429 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset); 10430 10431 vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure, 10432 0 /* n_array_elements */, data_stride, sixth_offset); 10433 10434 const GLuint stride = calculateStride(*vs_uni_block); 10435 m_data.resize(stride); 10436 generateData(*vs_uni_block, 0, m_data); 10437 10438 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 10439 10440 /* Add uniform BLOCK */ 10441 #if WRKARD_UNIFORMBLOCKALIGNMENT 10442 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0, 10443 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size()); 10444 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */ 10445 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0, 10446 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size()); 10447 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */ 10448 10449 program_interface.CloneVertexInterface(varying_passthrough); 10450 } 10451 10452 /** Constructor 10453 * 10454 * @param context Test framework context 10455 **/ 10456 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context& context) 10457 : TextureTestBase(context, "ssb_member_offset_and_align", 10458 "Test verifies offsets and alignment of storage buffer members") 10459 { 10460 } 10461 10462 /** Get interface of program 10463 * 10464 * @param test_case_index Test case index 10465 * @param program_interface Interface of program 10466 * @param varying_passthrough Collection of connections between in and out variables 10467 **/ 10468 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index, 10469 Utils::ProgramInterface& program_interface, 10470 Utils::VaryingPassthrough& varying_passthrough) 10471 { 10472 std::string globals = "const int basic_size = BASIC_SIZE;\n" 10473 "const int type_align = TYPE_ALIGN;\n" 10474 "const int type_size = TYPE_SIZE;\n"; 10475 10476 Utils::Type type = getType(test_case_index); 10477 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type); 10478 const GLuint base_align = type.GetBaseAlignment(false); 10479 const GLuint array_align = type.GetBaseAlignment(true); 10480 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0); 10481 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride); 10482 10483 /* Calculate offsets */ 10484 const GLuint first_offset = 0; 10485 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2); 10486 10487 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST 10488 10489 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align); 10490 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align); 10491 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align); 10492 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align); 10493 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align); 10494 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align); 10495 10496 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */ 10497 10498 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align); 10499 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align); 10500 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align); 10501 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align); 10502 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align); 10503 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size); 10504 10505 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */ 10506 10507 /* Prepare data */ 10508 const std::vector<GLubyte>& first = type.GenerateData(); 10509 const std::vector<GLubyte>& second = type.GenerateData(); 10510 const std::vector<GLubyte>& third = type.GenerateData(); 10511 const std::vector<GLubyte>& fourth = type.GenerateData(); 10512 10513 m_data.resize(eigth_offset + base_stride); 10514 GLubyte* ptr = &m_data[0]; 10515 memcpy(ptr + first_offset, &first[0], first.size()); 10516 memcpy(ptr + second_offset, &second[0], second.size()); 10517 memcpy(ptr + third_offset, &third[0], third.size()); 10518 memcpy(ptr + fourth_offset, &fourth[0], fourth.size()); 10519 memcpy(ptr + fifth_offset, &fourth[0], fourth.size()); 10520 memcpy(ptr + sixth_offset, &third[0], third.size()); 10521 memcpy(ptr + seventh_offset, &second[0], second.size()); 10522 memcpy(ptr + eigth_offset, &first[0], first.size()); 10523 10524 /* Prepare globals */ 10525 size_t position = 0; 10526 GLchar buffer[16]; 10527 10528 sprintf(buffer, "%d", basic_size); 10529 Utils::replaceToken("BASIC_SIZE", position, buffer, globals); 10530 10531 sprintf(buffer, "%d", type_align); 10532 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals); 10533 10534 sprintf(buffer, "%d", base_stride); 10535 Utils::replaceToken("TYPE_SIZE", position, buffer, globals); 10536 10537 /* Prepare Block */ 10538 Utils::Interface* vs_buf_block = program_interface.Block("vs_buf_Block"); 10539 10540 vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */, 10541 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 10542 first_offset); 10543 10544 vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)", 10545 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */, 10546 0 /* n_array_elements */, base_stride, second_offset); 10547 10548 vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */, 10549 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 10550 third_offset); 10551 10552 vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */, 10553 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 10554 fourth_offset); 10555 10556 vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type, 10557 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset); 10558 10559 vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type, 10560 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset); 10561 10562 vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */, 10563 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride, 10564 eigth_offset); 10565 10566 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 10567 10568 /* Add globals */ 10569 vs_si.m_globals = globals; 10570 10571 /* Add uniform BLOCK */ 10572 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0, 10573 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size()); 10574 10575 /* */ 10576 program_interface.CloneVertexInterface(varying_passthrough); 10577 } 10578 10579 /** Get type name 10580 * 10581 * @param test_case_index Index of test case 10582 * 10583 * @return Name of type test in test_case_index 10584 **/ 10585 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index) 10586 { 10587 return getTypeName(test_case_index); 10588 } 10589 10590 /** Returns number of types to test 10591 * 10592 * @return Number of types, 34 10593 **/ 10594 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber() 10595 { 10596 return getTypesNumber(); 10597 } 10598 10599 /** Prepare code snippet that will verify in and uniform variables 10600 * 10601 * @param ignored 10602 * @param ignored 10603 * @param stage Shader stage 10604 * 10605 * @return Code that verify variables 10606 **/ 10607 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */, 10608 Utils::ProgramInterface& /* program_interface */, 10609 Utils::Shader::STAGES stage) 10610 { 10611 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n" 10612 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n" 10613 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n" 10614 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n" 10615 " {\n" 10616 " result = 0;\n" 10617 " }"; 10618 10619 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB); 10620 10621 Utils::replaceAllTokens("PREFIX", prefix, verification); 10622 10623 return verification; 10624 } 10625 10626 /** Selects if "draw" stages are relevant for test 10627 * 10628 * @param ignored 10629 * 10630 * @return true if all stages support shader storage buffers, false otherwise 10631 **/ 10632 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */) 10633 { 10634 const Functions& gl = m_context.getRenderContext().getFunctions(); 10635 GLint gs_supported_buffers = 0; 10636 GLint tcs_supported_buffers = 0; 10637 GLint tes_supported_buffers = 0; 10638 GLint vs_supported_buffers = 0; 10639 10640 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers); 10641 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers); 10642 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers); 10643 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers); 10644 10645 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 10646 10647 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) && 10648 (1 <= vs_supported_buffers)); 10649 } 10650 10651 /** Constructor 10652 * 10653 * @param context Test framework context 10654 **/ 10655 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context& context) 10656 : NegativeTestBase(context, "ssb_layout_qualifier_conflict", "Test verifies that std140 or std430 is required when " 10657 "offset and/or align qualifiers are used with storage " 10658 "block") 10659 { 10660 /* Nothing to be done here */ 10661 } 10662 10663 /** Source for given test case and stage 10664 * 10665 * @param test_case_index Index of test case 10666 * @param stage Shader stage 10667 * 10668 * @return Shader source 10669 **/ 10670 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 10671 { 10672 static const GLchar* cs = "#version 430 core\n" 10673 "#extension GL_ARB_enhanced_layouts : require\n" 10674 "\n" 10675 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 10676 "\n" 10677 "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n" 10678 " layout(offset = 16) vec4 boy;\n" 10679 " layout(align = 64) vec4 man;\n" 10680 "} uni_block;\n" 10681 "\n" 10682 "writeonly uniform image2D uni_image;\n" 10683 "\n" 10684 "void main()\n" 10685 "{\n" 10686 " vec4 result = uni_block.boy + uni_block.man;\n" 10687 "\n" 10688 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 10689 "}\n" 10690 "\n"; 10691 static const GLchar* fs = "#version 430 core\n" 10692 "#extension GL_ARB_enhanced_layouts : require\n" 10693 "\n" 10694 "layout (QUALIFIERbinding = BINDING) buffer Block {\n" 10695 " layout(offset = 16) vec4 boy;\n" 10696 " layout(align = 64) vec4 man;\n" 10697 "} uni_block;\n" 10698 "\n" 10699 "in vec4 gs_fs;\n" 10700 "out vec4 fs_out;\n" 10701 "\n" 10702 "void main()\n" 10703 "{\n" 10704 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n" 10705 "}\n" 10706 "\n"; 10707 static const GLchar* gs = "#version 430 core\n" 10708 "#extension GL_ARB_enhanced_layouts : require\n" 10709 "\n" 10710 "layout(points) in;\n" 10711 "layout(triangle_strip, max_vertices = 4) out;\n" 10712 "\n" 10713 "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n" 10714 " layout(offset = 16) vec4 boy;\n" 10715 " layout(align = 64) vec4 man;\n" 10716 "} uni_block;\n" 10717 "\n" 10718 "in vec4 tes_gs[];\n" 10719 "out vec4 gs_fs;\n" 10720 "\n" 10721 "void main()\n" 10722 "{\n" 10723 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 10724 " gl_Position = vec4(-1, -1, 0, 1);\n" 10725 " EmitVertex();\n" 10726 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 10727 " gl_Position = vec4(-1, 1, 0, 1);\n" 10728 " EmitVertex();\n" 10729 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 10730 " gl_Position = vec4(1, -1, 0, 1);\n" 10731 " EmitVertex();\n" 10732 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n" 10733 " gl_Position = vec4(1, 1, 0, 1);\n" 10734 " EmitVertex();\n" 10735 "}\n" 10736 "\n"; 10737 static const GLchar* tcs = 10738 "#version 430 core\n" 10739 "#extension GL_ARB_enhanced_layouts : require\n" 10740 "\n" 10741 "layout(vertices = 1) out;\n" 10742 "\n" 10743 "layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n" 10744 " layout(offset = 16) vec4 boy;\n" 10745 " layout(align = 64) vec4 man;\n" 10746 "} uni_block;\n" 10747 "\n" 10748 "in vec4 vs_tcs[];\n" 10749 "out vec4 tcs_tes[];\n" 10750 "\n" 10751 "void main()\n" 10752 "{\n" 10753 "\n" 10754 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n" 10755 "\n" 10756 " gl_TessLevelOuter[0] = 1.0;\n" 10757 " gl_TessLevelOuter[1] = 1.0;\n" 10758 " gl_TessLevelOuter[2] = 1.0;\n" 10759 " gl_TessLevelOuter[3] = 1.0;\n" 10760 " gl_TessLevelInner[0] = 1.0;\n" 10761 " gl_TessLevelInner[1] = 1.0;\n" 10762 "}\n" 10763 "\n"; 10764 static const GLchar* tes = "#version 430 core\n" 10765 "#extension GL_ARB_enhanced_layouts : require\n" 10766 "\n" 10767 "layout(isolines, point_mode) in;\n" 10768 "\n" 10769 "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n" 10770 " layout(offset = 16) vec4 boy;\n" 10771 " layout(align = 64) vec4 man;\n" 10772 "} uni_block;\n" 10773 "\n" 10774 "in vec4 tcs_tes[];\n" 10775 "out vec4 tes_gs;\n" 10776 "\n" 10777 "void main()\n" 10778 "{\n" 10779 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n" 10780 "}\n" 10781 "\n"; 10782 static const GLchar* vs = "#version 430 core\n" 10783 "#extension GL_ARB_enhanced_layouts : require\n" 10784 "\n" 10785 "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n" 10786 " layout(offset = 16) vec4 boy;\n" 10787 " layout(align = 64) vec4 man;\n" 10788 "} uni_block;\n" 10789 "\n" 10790 "in vec4 in_vs;\n" 10791 "out vec4 vs_tcs;\n" 10792 "\n" 10793 "void main()\n" 10794 "{\n" 10795 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n" 10796 "}\n" 10797 "\n"; 10798 10799 GLchar buffer[16]; 10800 size_t position = 0; 10801 std::string source; 10802 testCase& test_case = m_test_cases[test_case_index]; 10803 std::string qualifier = getQualifierName(test_case.m_qualifier); 10804 10805 if (false == qualifier.empty()) 10806 { 10807 qualifier.append(", "); 10808 } 10809 10810 sprintf(buffer, "%d", stage); 10811 10812 switch (stage) 10813 { 10814 case Utils::Shader::COMPUTE: 10815 source = cs; 10816 break; 10817 case Utils::Shader::FRAGMENT: 10818 source = fs; 10819 break; 10820 case Utils::Shader::GEOMETRY: 10821 source = gs; 10822 break; 10823 case Utils::Shader::TESS_CTRL: 10824 source = tcs; 10825 break; 10826 case Utils::Shader::TESS_EVAL: 10827 source = tes; 10828 break; 10829 case Utils::Shader::VERTEX: 10830 source = vs; 10831 break; 10832 default: 10833 TCU_FAIL("Invalid enum"); 10834 } 10835 10836 if (test_case.m_stage == stage) 10837 { 10838 Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source); 10839 } 10840 else 10841 { 10842 Utils::replaceToken("QUALIFIER", position, "std140, ", source); 10843 } 10844 10845 Utils::replaceToken("BINDING", position, buffer, source); 10846 10847 return source; 10848 } 10849 10850 /** Get description of test case 10851 * 10852 * @param test_case_index Index of test case 10853 * 10854 * @return Qualifier name 10855 **/ 10856 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index) 10857 { 10858 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier); 10859 10860 return result; 10861 } 10862 10863 /** Get number of test cases 10864 * 10865 * @return Number of test cases 10866 **/ 10867 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber() 10868 { 10869 return static_cast<GLuint>(m_test_cases.size()); 10870 } 10871 10872 /** Selects if "compute" stage is relevant for test 10873 * 10874 * @param test_case_index Index of test case 10875 * 10876 * @return true when tested stage is compute 10877 **/ 10878 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index) 10879 { 10880 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage); 10881 } 10882 10883 /** Selects if compilation failure is expected result 10884 * 10885 * @param test_case_index Index of test case 10886 * 10887 * @return false for STD140 and STD430 cases, true otherwise 10888 **/ 10889 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index) 10890 { 10891 const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier; 10892 10893 return !((STD140 == qualifier) || (STD430 == qualifier)); 10894 } 10895 10896 /** Checks if stage is supported 10897 * 10898 * @param stage Shader stage 10899 * 10900 * @return true if supported, false otherwise 10901 **/ 10902 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage) 10903 { 10904 const Functions& gl = m_context.getRenderContext().getFunctions(); 10905 GLint max_supported_buffers = 0; 10906 GLenum pname = 0; 10907 10908 switch (stage) 10909 { 10910 case Utils::Shader::COMPUTE: 10911 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS; 10912 break; 10913 case Utils::Shader::FRAGMENT: 10914 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS; 10915 break; 10916 case Utils::Shader::GEOMETRY: 10917 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS; 10918 break; 10919 case Utils::Shader::TESS_CTRL: 10920 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS; 10921 break; 10922 case Utils::Shader::TESS_EVAL: 10923 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS; 10924 break; 10925 case Utils::Shader::VERTEX: 10926 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS; 10927 break; 10928 default: 10929 TCU_FAIL("Invalid enum"); 10930 } 10931 10932 gl.getIntegerv(pname, &max_supported_buffers); 10933 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 10934 10935 return 1 <= max_supported_buffers; 10936 } 10937 10938 /** Prepare all test cases 10939 * 10940 **/ 10941 void SSBLayoutQualifierConflictTest::testInit() 10942 { 10943 bool stage_support[Utils::Shader::STAGE_MAX]; 10944 10945 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 10946 { 10947 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage); 10948 } 10949 10950 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier) 10951 { 10952 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 10953 { 10954 if (false == stage_support[stage]) 10955 { 10956 continue; 10957 } 10958 10959 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage }; 10960 10961 m_test_cases.push_back(test_case); 10962 } 10963 } 10964 } 10965 10966 /** Get name of glsl constant 10967 * 10968 * @param Constant id 10969 * 10970 * @return Name of constant used in GLSL 10971 **/ 10972 const GLchar* SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier) 10973 { 10974 const GLchar* name = ""; 10975 10976 switch (qualifier) 10977 { 10978 case DEFAULT: 10979 name = ""; 10980 break; 10981 case STD140: 10982 name = "std140"; 10983 break; 10984 case STD430: 10985 name = "std430"; 10986 break; 10987 case SHARED: 10988 name = "shared"; 10989 break; 10990 case PACKED: 10991 name = "packed"; 10992 break; 10993 default: 10994 TCU_FAIL("Invalid enum"); 10995 } 10996 10997 return name; 10998 } 10999 11000 /** Constructor 11001 * 11002 * @param context Test framework context 11003 **/ 11004 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context& context) 11005 : UniformBlockMemberInvalidOffsetAlignmentTest( 11006 context, "ssb_member_invalid_offset_alignment", 11007 "Test verifies that invalid alignment of offset qualifiers cause compilation failure") 11008 { 11009 /* Nothing to be done here */ 11010 } 11011 11012 /** Get the maximum size for a shader storage block 11013 * 11014 * @return The maximum size in basic machine units of a shader storage block. 11015 **/ 11016 GLint SSBMemberInvalidOffsetAlignmentTest::getMaxBlockSize() 11017 { 11018 const Functions& gl = m_context.getRenderContext().getFunctions(); 11019 GLint max_size = 0; 11020 11021 gl.getIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_size); 11022 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 11023 11024 return max_size; 11025 } 11026 11027 /** Source for given test case and stage 11028 * 11029 * @param test_case_index Index of test case 11030 * @param stage Shader stage 11031 * 11032 * @return Shader source 11033 **/ 11034 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 11035 { 11036 static const GLchar* cs = "#version 430 core\n" 11037 "#extension GL_ARB_enhanced_layouts : require\n" 11038 "\n" 11039 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 11040 "\n" 11041 "layout (std140) buffer Block {\n" 11042 " layout (offset = OFFSET) TYPE member;\n" 11043 "} block;\n" 11044 "\n" 11045 "writeonly uniform image2D uni_image;\n" 11046 "\n" 11047 "void main()\n" 11048 "{\n" 11049 " vec4 result = vec4(1, 0, 0.5, 1);\n" 11050 "\n" 11051 " if (TYPE(1) == block.member)\n" 11052 " {\n" 11053 " result = vec4(1, 1, 1, 1);\n" 11054 " }\n" 11055 "\n" 11056 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 11057 "}\n" 11058 "\n"; 11059 static const GLchar* fs = "#version 430 core\n" 11060 "#extension GL_ARB_enhanced_layouts : require\n" 11061 "\n" 11062 "in vec4 gs_fs;\n" 11063 "out vec4 fs_out;\n" 11064 "\n" 11065 "void main()\n" 11066 "{\n" 11067 " fs_out = gs_fs;\n" 11068 "}\n" 11069 "\n"; 11070 static const GLchar* fs_tested = "#version 430 core\n" 11071 "#extension GL_ARB_enhanced_layouts : require\n" 11072 "\n" 11073 "layout (std140) buffer Block {\n" 11074 " layout (offset = OFFSET) TYPE member;\n" 11075 "} block;\n" 11076 "\n" 11077 "in vec4 gs_fs;\n" 11078 "out vec4 fs_out;\n" 11079 "\n" 11080 "void main()\n" 11081 "{\n" 11082 " if (TYPE(1) == block.member)\n" 11083 " {\n" 11084 " fs_out = vec4(1, 1, 1, 1);\n" 11085 " }\n" 11086 "\n" 11087 " fs_out += gs_fs;\n" 11088 "}\n" 11089 "\n"; 11090 static const GLchar* gs = "#version 430 core\n" 11091 "#extension GL_ARB_enhanced_layouts : require\n" 11092 "\n" 11093 "layout(points) in;\n" 11094 "layout(triangle_strip, max_vertices = 4) out;\n" 11095 "\n" 11096 "in vec4 tes_gs[];\n" 11097 "out vec4 gs_fs;\n" 11098 "\n" 11099 "void main()\n" 11100 "{\n" 11101 " gs_fs = tes_gs[0];\n" 11102 " gl_Position = vec4(-1, -1, 0, 1);\n" 11103 " EmitVertex();\n" 11104 " gs_fs = tes_gs[0];\n" 11105 " gl_Position = vec4(-1, 1, 0, 1);\n" 11106 " EmitVertex();\n" 11107 " gs_fs = tes_gs[0];\n" 11108 " gl_Position = vec4(1, -1, 0, 1);\n" 11109 " EmitVertex();\n" 11110 " gs_fs = tes_gs[0];\n" 11111 " gl_Position = vec4(1, 1, 0, 1);\n" 11112 " EmitVertex();\n" 11113 "}\n" 11114 "\n"; 11115 static const GLchar* gs_tested = "#version 430 core\n" 11116 "#extension GL_ARB_enhanced_layouts : require\n" 11117 "\n" 11118 "layout(points) in;\n" 11119 "layout(triangle_strip, max_vertices = 4) out;\n" 11120 "\n" 11121 "layout (std140) buffer Block {\n" 11122 " layout (offset = OFFSET) TYPE member;\n" 11123 "} block;\n" 11124 "\n" 11125 "in vec4 tes_gs[];\n" 11126 "out vec4 gs_fs;\n" 11127 "\n" 11128 "void main()\n" 11129 "{\n" 11130 " if (TYPE(1) == block.member)\n" 11131 " {\n" 11132 " gs_fs = vec4(1, 1, 1, 1);\n" 11133 " }\n" 11134 "\n" 11135 " gs_fs += tes_gs[0];\n" 11136 " gl_Position = vec4(-1, -1, 0, 1);\n" 11137 " EmitVertex();\n" 11138 " gs_fs += tes_gs[0];\n" 11139 " gl_Position = vec4(-1, 1, 0, 1);\n" 11140 " EmitVertex();\n" 11141 " gs_fs += tes_gs[0];\n" 11142 " gl_Position = vec4(1, -1, 0, 1);\n" 11143 " EmitVertex();\n" 11144 " gs_fs += tes_gs[0];\n" 11145 " gl_Position = vec4(1, 1, 0, 1);\n" 11146 " EmitVertex();\n" 11147 "}\n" 11148 "\n"; 11149 static const GLchar* tcs = "#version 430 core\n" 11150 "#extension GL_ARB_enhanced_layouts : require\n" 11151 "\n" 11152 "layout(vertices = 1) out;\n" 11153 "\n" 11154 "in vec4 vs_tcs[];\n" 11155 "out vec4 tcs_tes[];\n" 11156 "\n" 11157 "void main()\n" 11158 "{\n" 11159 "\n" 11160 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 11161 "\n" 11162 " gl_TessLevelOuter[0] = 1.0;\n" 11163 " gl_TessLevelOuter[1] = 1.0;\n" 11164 " gl_TessLevelOuter[2] = 1.0;\n" 11165 " gl_TessLevelOuter[3] = 1.0;\n" 11166 " gl_TessLevelInner[0] = 1.0;\n" 11167 " gl_TessLevelInner[1] = 1.0;\n" 11168 "}\n" 11169 "\n"; 11170 static const GLchar* tcs_tested = "#version 430 core\n" 11171 "#extension GL_ARB_enhanced_layouts : require\n" 11172 "\n" 11173 "layout(vertices = 1) out;\n" 11174 "\n" 11175 "layout (std140) buffer Block {\n" 11176 " layout (offset = OFFSET) TYPE member;\n" 11177 "} block;\n" 11178 "\n" 11179 "in vec4 vs_tcs[];\n" 11180 "out vec4 tcs_tes[];\n" 11181 "\n" 11182 "void main()\n" 11183 "{\n" 11184 " if (TYPE(1) == block.member)\n" 11185 " {\n" 11186 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n" 11187 " }\n" 11188 "\n" 11189 "\n" 11190 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n" 11191 "\n" 11192 " gl_TessLevelOuter[0] = 1.0;\n" 11193 " gl_TessLevelOuter[1] = 1.0;\n" 11194 " gl_TessLevelOuter[2] = 1.0;\n" 11195 " gl_TessLevelOuter[3] = 1.0;\n" 11196 " gl_TessLevelInner[0] = 1.0;\n" 11197 " gl_TessLevelInner[1] = 1.0;\n" 11198 "}\n" 11199 "\n"; 11200 static const GLchar* tes = "#version 430 core\n" 11201 "#extension GL_ARB_enhanced_layouts : require\n" 11202 "\n" 11203 "layout(isolines, point_mode) in;\n" 11204 "\n" 11205 "in vec4 tcs_tes[];\n" 11206 "out vec4 tes_gs;\n" 11207 "\n" 11208 "void main()\n" 11209 "{\n" 11210 " tes_gs = tcs_tes[0];\n" 11211 "}\n" 11212 "\n"; 11213 static const GLchar* tes_tested = "#version 430 core\n" 11214 "#extension GL_ARB_enhanced_layouts : require\n" 11215 "\n" 11216 "layout(isolines, point_mode) in;\n" 11217 "\n" 11218 "layout (std140) buffer Block {\n" 11219 " layout (offset = OFFSET) TYPE member;\n" 11220 "} block;\n" 11221 "\n" 11222 "in vec4 tcs_tes[];\n" 11223 "out vec4 tes_gs;\n" 11224 "\n" 11225 "void main()\n" 11226 "{\n" 11227 " if (TYPE(1) == block.member)\n" 11228 " {\n" 11229 " tes_gs = vec4(1, 1, 1, 1);\n" 11230 " }\n" 11231 "\n" 11232 " tes_gs += tcs_tes[0];\n" 11233 "}\n" 11234 "\n"; 11235 static const GLchar* vs = "#version 430 core\n" 11236 "#extension GL_ARB_enhanced_layouts : require\n" 11237 "\n" 11238 "in vec4 in_vs;\n" 11239 "out vec4 vs_tcs;\n" 11240 "\n" 11241 "void main()\n" 11242 "{\n" 11243 " vs_tcs = in_vs;\n" 11244 "}\n" 11245 "\n"; 11246 static const GLchar* vs_tested = "#version 430 core\n" 11247 "#extension GL_ARB_enhanced_layouts : require\n" 11248 "\n" 11249 "layout (std140) buffer Block {\n" 11250 " layout (offset = OFFSET) TYPE member;\n" 11251 "} block;\n" 11252 "\n" 11253 "in vec4 in_vs;\n" 11254 "out vec4 vs_tcs;\n" 11255 "\n" 11256 "void main()\n" 11257 "{\n" 11258 " if (TYPE(1) == block.member)\n" 11259 " {\n" 11260 " vs_tcs = vec4(1, 1, 1, 1);\n" 11261 " }\n" 11262 "\n" 11263 " vs_tcs += in_vs;\n" 11264 "}\n" 11265 "\n"; 11266 11267 std::string source; 11268 testCase& test_case = m_test_cases[test_case_index]; 11269 11270 if (test_case.m_stage == stage) 11271 { 11272 GLchar buffer[16]; 11273 const GLuint offset = test_case.m_offset; 11274 size_t position = 0; 11275 const Utils::Type& type = test_case.m_type; 11276 const GLchar* type_name = type.GetGLSLTypeName(); 11277 11278 sprintf(buffer, "%d", offset); 11279 11280 switch (stage) 11281 { 11282 case Utils::Shader::COMPUTE: 11283 source = cs; 11284 break; 11285 case Utils::Shader::FRAGMENT: 11286 source = fs_tested; 11287 break; 11288 case Utils::Shader::GEOMETRY: 11289 source = gs_tested; 11290 break; 11291 case Utils::Shader::TESS_CTRL: 11292 source = tcs_tested; 11293 break; 11294 case Utils::Shader::TESS_EVAL: 11295 source = tes_tested; 11296 break; 11297 case Utils::Shader::VERTEX: 11298 source = vs_tested; 11299 break; 11300 default: 11301 TCU_FAIL("Invalid enum"); 11302 } 11303 11304 Utils::replaceToken("OFFSET", position, buffer, source); 11305 Utils::replaceToken("TYPE", position, type_name, source); 11306 Utils::replaceToken("TYPE", position, type_name, source); 11307 } 11308 else 11309 { 11310 switch (stage) 11311 { 11312 case Utils::Shader::FRAGMENT: 11313 source = fs; 11314 break; 11315 case Utils::Shader::GEOMETRY: 11316 source = gs; 11317 break; 11318 case Utils::Shader::TESS_CTRL: 11319 source = tcs; 11320 break; 11321 case Utils::Shader::TESS_EVAL: 11322 source = tes; 11323 break; 11324 case Utils::Shader::VERTEX: 11325 source = vs; 11326 break; 11327 default: 11328 TCU_FAIL("Invalid enum"); 11329 } 11330 } 11331 11332 return source; 11333 } 11334 11335 /** Checks if stage is supported 11336 * 11337 * @param stage Shader stage 11338 * 11339 * @return true if supported, false otherwise 11340 **/ 11341 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage) 11342 { 11343 const Functions& gl = m_context.getRenderContext().getFunctions(); 11344 GLint max_supported_buffers = 0; 11345 GLenum pname = 0; 11346 11347 switch (stage) 11348 { 11349 case Utils::Shader::COMPUTE: 11350 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS; 11351 break; 11352 case Utils::Shader::FRAGMENT: 11353 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS; 11354 break; 11355 case Utils::Shader::GEOMETRY: 11356 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS; 11357 break; 11358 case Utils::Shader::TESS_CTRL: 11359 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS; 11360 break; 11361 case Utils::Shader::TESS_EVAL: 11362 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS; 11363 break; 11364 case Utils::Shader::VERTEX: 11365 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS; 11366 break; 11367 default: 11368 TCU_FAIL("Invalid enum"); 11369 } 11370 11371 gl.getIntegerv(pname, &max_supported_buffers); 11372 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 11373 11374 return 1 <= max_supported_buffers; 11375 } 11376 11377 /** Constructor 11378 * 11379 * @param context Test framework context 11380 **/ 11381 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context& context) 11382 : UniformBlockMemberOverlappingOffsetsTest( 11383 context, "ssb_member_overlapping_offsets", 11384 "Test verifies that overlapping offsets qualifiers cause compilation failure") 11385 { 11386 /* Nothing to be done here */ 11387 } 11388 11389 /** Source for given test case and stage 11390 * 11391 * @param test_case_index Index of test case 11392 * @param stage Shader stage 11393 * 11394 * @return Shader source 11395 **/ 11396 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 11397 { 11398 static const GLchar* cs = "#version 430 core\n" 11399 "#extension GL_ARB_enhanced_layouts : require\n" 11400 "\n" 11401 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 11402 "\n" 11403 "layout (std140) buffer Block {\n" 11404 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 11405 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 11406 "} block;\n" 11407 "\n" 11408 "writeonly uniform image2D uni_image;\n" 11409 "\n" 11410 "void main()\n" 11411 "{\n" 11412 " vec4 result = vec4(1, 0, 0.5, 1);\n" 11413 "\n" 11414 " if ((BOY_TYPE(1) == block.boy) ||\n" 11415 " (MAN_TYPE(0) == block.man) )\n" 11416 " {\n" 11417 " result = vec4(1, 1, 1, 1);\n" 11418 " }\n" 11419 "\n" 11420 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 11421 "}\n" 11422 "\n"; 11423 static const GLchar* fs = "#version 430 core\n" 11424 "#extension GL_ARB_enhanced_layouts : require\n" 11425 "\n" 11426 "in vec4 gs_fs;\n" 11427 "out vec4 fs_out;\n" 11428 "\n" 11429 "void main()\n" 11430 "{\n" 11431 " fs_out = gs_fs;\n" 11432 "}\n" 11433 "\n"; 11434 static const GLchar* fs_tested = "#version 430 core\n" 11435 "#extension GL_ARB_enhanced_layouts : require\n" 11436 "\n" 11437 "layout (std140) buffer Block {\n" 11438 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 11439 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 11440 "} block;\n" 11441 "\n" 11442 "in vec4 gs_fs;\n" 11443 "out vec4 fs_out;\n" 11444 "\n" 11445 "void main()\n" 11446 "{\n" 11447 " if ((BOY_TYPE(1) == block.boy) ||\n" 11448 " (MAN_TYPE(0) == block.man) )\n" 11449 " {\n" 11450 " fs_out = vec4(1, 1, 1, 1);\n" 11451 " }\n" 11452 "\n" 11453 " fs_out += gs_fs;\n" 11454 "}\n" 11455 "\n"; 11456 static const GLchar* gs = "#version 430 core\n" 11457 "#extension GL_ARB_enhanced_layouts : require\n" 11458 "\n" 11459 "layout(points) in;\n" 11460 "layout(triangle_strip, max_vertices = 4) out;\n" 11461 "\n" 11462 "in vec4 tes_gs[];\n" 11463 "out vec4 gs_fs;\n" 11464 "\n" 11465 "void main()\n" 11466 "{\n" 11467 " gs_fs = tes_gs[0];\n" 11468 " gl_Position = vec4(-1, -1, 0, 1);\n" 11469 " EmitVertex();\n" 11470 " gs_fs = tes_gs[0];\n" 11471 " gl_Position = vec4(-1, 1, 0, 1);\n" 11472 " EmitVertex();\n" 11473 " gs_fs = tes_gs[0];\n" 11474 " gl_Position = vec4(1, -1, 0, 1);\n" 11475 " EmitVertex();\n" 11476 " gs_fs = tes_gs[0];\n" 11477 " gl_Position = vec4(1, 1, 0, 1);\n" 11478 " EmitVertex();\n" 11479 "}\n" 11480 "\n"; 11481 static const GLchar* gs_tested = "#version 430 core\n" 11482 "#extension GL_ARB_enhanced_layouts : require\n" 11483 "\n" 11484 "layout(points) in;\n" 11485 "layout(triangle_strip, max_vertices = 4) out;\n" 11486 "\n" 11487 "layout (std140) buffer Block {\n" 11488 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 11489 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 11490 "} block;\n" 11491 "\n" 11492 "in vec4 tes_gs[];\n" 11493 "out vec4 gs_fs;\n" 11494 "\n" 11495 "void main()\n" 11496 "{\n" 11497 " if ((BOY_TYPE(1) == block.boy) ||\n" 11498 " (MAN_TYPE(0) == block.man) )\n" 11499 " {\n" 11500 " gs_fs = vec4(1, 1, 1, 1);\n" 11501 " }\n" 11502 "\n" 11503 " gs_fs += tes_gs[0];\n" 11504 " gl_Position = vec4(-1, -1, 0, 1);\n" 11505 " EmitVertex();\n" 11506 " gs_fs += tes_gs[0];\n" 11507 " gl_Position = vec4(-1, 1, 0, 1);\n" 11508 " EmitVertex();\n" 11509 " gs_fs += tes_gs[0];\n" 11510 " gl_Position = vec4(1, -1, 0, 1);\n" 11511 " EmitVertex();\n" 11512 " gs_fs += tes_gs[0];\n" 11513 " gl_Position = vec4(1, 1, 0, 1);\n" 11514 " EmitVertex();\n" 11515 "}\n" 11516 "\n"; 11517 static const GLchar* tcs = "#version 430 core\n" 11518 "#extension GL_ARB_enhanced_layouts : require\n" 11519 "\n" 11520 "layout(vertices = 1) out;\n" 11521 "\n" 11522 "in vec4 vs_tcs[];\n" 11523 "out vec4 tcs_tes[];\n" 11524 "\n" 11525 "void main()\n" 11526 "{\n" 11527 "\n" 11528 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 11529 "\n" 11530 " gl_TessLevelOuter[0] = 1.0;\n" 11531 " gl_TessLevelOuter[1] = 1.0;\n" 11532 " gl_TessLevelOuter[2] = 1.0;\n" 11533 " gl_TessLevelOuter[3] = 1.0;\n" 11534 " gl_TessLevelInner[0] = 1.0;\n" 11535 " gl_TessLevelInner[1] = 1.0;\n" 11536 "}\n" 11537 "\n"; 11538 static const GLchar* tcs_tested = "#version 430 core\n" 11539 "#extension GL_ARB_enhanced_layouts : require\n" 11540 "\n" 11541 "layout(vertices = 1) out;\n" 11542 "\n" 11543 "layout (std140) buffer Block {\n" 11544 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 11545 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 11546 "} block;\n" 11547 "\n" 11548 "in vec4 vs_tcs[];\n" 11549 "out vec4 tcs_tes[];\n" 11550 "\n" 11551 "void main()\n" 11552 "{\n" 11553 " if ((BOY_TYPE(1) == block.boy) ||\n" 11554 " (MAN_TYPE(0) == block.man) )\n" 11555 " {\n" 11556 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n" 11557 " }\n" 11558 "\n" 11559 "\n" 11560 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n" 11561 "\n" 11562 " gl_TessLevelOuter[0] = 1.0;\n" 11563 " gl_TessLevelOuter[1] = 1.0;\n" 11564 " gl_TessLevelOuter[2] = 1.0;\n" 11565 " gl_TessLevelOuter[3] = 1.0;\n" 11566 " gl_TessLevelInner[0] = 1.0;\n" 11567 " gl_TessLevelInner[1] = 1.0;\n" 11568 "}\n" 11569 "\n"; 11570 static const GLchar* tes = "#version 430 core\n" 11571 "#extension GL_ARB_enhanced_layouts : require\n" 11572 "\n" 11573 "layout(isolines, point_mode) in;\n" 11574 "\n" 11575 "in vec4 tcs_tes[];\n" 11576 "out vec4 tes_gs;\n" 11577 "\n" 11578 "void main()\n" 11579 "{\n" 11580 " tes_gs = tcs_tes[0];\n" 11581 "}\n" 11582 "\n"; 11583 static const GLchar* tes_tested = "#version 430 core\n" 11584 "#extension GL_ARB_enhanced_layouts : require\n" 11585 "\n" 11586 "layout(isolines, point_mode) in;\n" 11587 "\n" 11588 "layout (std140) buffer Block {\n" 11589 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 11590 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 11591 "} block;\n" 11592 "\n" 11593 "in vec4 tcs_tes[];\n" 11594 "out vec4 tes_gs;\n" 11595 "\n" 11596 "void main()\n" 11597 "{\n" 11598 " if ((BOY_TYPE(1) == block.boy) ||\n" 11599 " (MAN_TYPE(0) == block.man) )\n" 11600 " {\n" 11601 " tes_gs = vec4(1, 1, 1, 1);\n" 11602 " }\n" 11603 "\n" 11604 " tes_gs += tcs_tes[0];\n" 11605 "}\n" 11606 "\n"; 11607 static const GLchar* vs = "#version 430 core\n" 11608 "#extension GL_ARB_enhanced_layouts : require\n" 11609 "\n" 11610 "in vec4 in_vs;\n" 11611 "out vec4 vs_tcs;\n" 11612 "\n" 11613 "void main()\n" 11614 "{\n" 11615 " vs_tcs = in_vs;\n" 11616 "}\n" 11617 "\n"; 11618 static const GLchar* vs_tested = "#version 430 core\n" 11619 "#extension GL_ARB_enhanced_layouts : require\n" 11620 "\n" 11621 "layout (std140) buffer Block {\n" 11622 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n" 11623 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n" 11624 "} block;\n" 11625 "\n" 11626 "in vec4 in_vs;\n" 11627 "out vec4 vs_tcs;\n" 11628 "\n" 11629 "void main()\n" 11630 "{\n" 11631 " if ((BOY_TYPE(1) == block.boy) ||\n" 11632 " (MAN_TYPE(0) == block.man) )\n" 11633 " {\n" 11634 " vs_tcs = vec4(1, 1, 1, 1);\n" 11635 " }\n" 11636 "\n" 11637 " vs_tcs += in_vs;\n" 11638 "}\n" 11639 "\n"; 11640 11641 std::string source; 11642 testCase& test_case = m_test_cases[test_case_index]; 11643 11644 if (test_case.m_stage == stage) 11645 { 11646 GLchar buffer[16]; 11647 const GLuint boy_offset = test_case.m_boy_offset; 11648 const Utils::Type& boy_type = test_case.m_boy_type; 11649 const GLchar* boy_type_name = boy_type.GetGLSLTypeName(); 11650 const GLuint man_offset = test_case.m_man_offset; 11651 const Utils::Type& man_type = test_case.m_man_type; 11652 const GLchar* man_type_name = man_type.GetGLSLTypeName(); 11653 size_t position = 0; 11654 11655 switch (stage) 11656 { 11657 case Utils::Shader::COMPUTE: 11658 source = cs; 11659 break; 11660 case Utils::Shader::FRAGMENT: 11661 source = fs_tested; 11662 break; 11663 case Utils::Shader::GEOMETRY: 11664 source = gs_tested; 11665 break; 11666 case Utils::Shader::TESS_CTRL: 11667 source = tcs_tested; 11668 break; 11669 case Utils::Shader::TESS_EVAL: 11670 source = tes_tested; 11671 break; 11672 case Utils::Shader::VERTEX: 11673 source = vs_tested; 11674 break; 11675 default: 11676 TCU_FAIL("Invalid enum"); 11677 } 11678 11679 sprintf(buffer, "%d", boy_offset); 11680 Utils::replaceToken("BOY_OFFSET", position, buffer, source); 11681 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source); 11682 sprintf(buffer, "%d", man_offset); 11683 Utils::replaceToken("MAN_OFFSET", position, buffer, source); 11684 Utils::replaceToken("MAN_TYPE", position, man_type_name, source); 11685 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source); 11686 Utils::replaceToken("MAN_TYPE", position, man_type_name, source); 11687 } 11688 else 11689 { 11690 switch (stage) 11691 { 11692 case Utils::Shader::FRAGMENT: 11693 source = fs; 11694 break; 11695 case Utils::Shader::GEOMETRY: 11696 source = gs; 11697 break; 11698 case Utils::Shader::TESS_CTRL: 11699 source = tcs; 11700 break; 11701 case Utils::Shader::TESS_EVAL: 11702 source = tes; 11703 break; 11704 case Utils::Shader::VERTEX: 11705 source = vs; 11706 break; 11707 default: 11708 TCU_FAIL("Invalid enum"); 11709 } 11710 } 11711 11712 return source; 11713 } 11714 11715 /** Checks if stage is supported 11716 * 11717 * @param stage Shader stage 11718 * 11719 * @return true if supported, false otherwise 11720 **/ 11721 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage) 11722 { 11723 const Functions& gl = m_context.getRenderContext().getFunctions(); 11724 GLint max_supported_buffers = 0; 11725 GLenum pname = 0; 11726 11727 switch (stage) 11728 { 11729 case Utils::Shader::COMPUTE: 11730 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS; 11731 break; 11732 case Utils::Shader::FRAGMENT: 11733 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS; 11734 break; 11735 case Utils::Shader::GEOMETRY: 11736 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS; 11737 break; 11738 case Utils::Shader::TESS_CTRL: 11739 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS; 11740 break; 11741 case Utils::Shader::TESS_EVAL: 11742 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS; 11743 break; 11744 case Utils::Shader::VERTEX: 11745 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS; 11746 break; 11747 default: 11748 TCU_FAIL("Invalid enum"); 11749 } 11750 11751 gl.getIntegerv(pname, &max_supported_buffers); 11752 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 11753 11754 return 1 <= max_supported_buffers; 11755 } 11756 11757 /** Constructor 11758 * 11759 * @param context Test framework context 11760 **/ 11761 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context& context) 11762 : UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2", 11763 "Test verifies that align qualifier requires value that is a power of 2") 11764 { 11765 /* Nothing to be done here */ 11766 } 11767 11768 /** Source for given test case and stage 11769 * 11770 * @param test_case_index Index of test case 11771 * @param stage Shader stage 11772 * 11773 * @return Shader source 11774 **/ 11775 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 11776 { 11777 static const GLchar* cs = "#version 430 core\n" 11778 "#extension GL_ARB_enhanced_layouts : require\n" 11779 "\n" 11780 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 11781 "\n" 11782 "layout (std140) buffer Block {\n" 11783 " vec4 boy;\n" 11784 " layout (align = ALIGN) TYPE man;\n" 11785 "} block;\n" 11786 "\n" 11787 "writeonly uniform image2D uni_image;\n" 11788 "\n" 11789 "void main()\n" 11790 "{\n" 11791 " vec4 result = vec4(1, 0, 0.5, 1);\n" 11792 "\n" 11793 " if (TYPE(0) == block.man)\n" 11794 " {\n" 11795 " result = vec4(1, 1, 1, 1) - block.boy;\n" 11796 " }\n" 11797 "\n" 11798 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n" 11799 "}\n" 11800 "\n"; 11801 static const GLchar* fs = "#version 430 core\n" 11802 "#extension GL_ARB_enhanced_layouts : require\n" 11803 "\n" 11804 "in vec4 gs_fs;\n" 11805 "out vec4 fs_out;\n" 11806 "\n" 11807 "void main()\n" 11808 "{\n" 11809 " fs_out = gs_fs;\n" 11810 "}\n" 11811 "\n"; 11812 static const GLchar* fs_tested = "#version 430 core\n" 11813 "#extension GL_ARB_enhanced_layouts : require\n" 11814 "\n" 11815 "layout (std140) buffer Block {\n" 11816 " vec4 boy;\n" 11817 " layout (align = ALIGN) TYPE man;\n" 11818 "} block;\n" 11819 "\n" 11820 "in vec4 gs_fs;\n" 11821 "out vec4 fs_out;\n" 11822 "\n" 11823 "void main()\n" 11824 "{\n" 11825 " if (TYPE(0) == block.man)\n" 11826 " {\n" 11827 " fs_out = block.boy;\n" 11828 " }\n" 11829 "\n" 11830 " fs_out += gs_fs;\n" 11831 "}\n" 11832 "\n"; 11833 static const GLchar* gs = "#version 430 core\n" 11834 "#extension GL_ARB_enhanced_layouts : require\n" 11835 "\n" 11836 "layout(points) in;\n" 11837 "layout(triangle_strip, max_vertices = 4) out;\n" 11838 "\n" 11839 "in vec4 tes_gs[];\n" 11840 "out vec4 gs_fs;\n" 11841 "\n" 11842 "void main()\n" 11843 "{\n" 11844 " gs_fs = tes_gs[0];\n" 11845 " gl_Position = vec4(-1, -1, 0, 1);\n" 11846 " EmitVertex();\n" 11847 " gs_fs = tes_gs[0];\n" 11848 " gl_Position = vec4(-1, 1, 0, 1);\n" 11849 " EmitVertex();\n" 11850 " gs_fs = tes_gs[0];\n" 11851 " gl_Position = vec4(1, -1, 0, 1);\n" 11852 " EmitVertex();\n" 11853 " gs_fs = tes_gs[0];\n" 11854 " gl_Position = vec4(1, 1, 0, 1);\n" 11855 " EmitVertex();\n" 11856 "}\n" 11857 "\n"; 11858 static const GLchar* gs_tested = "#version 430 core\n" 11859 "#extension GL_ARB_enhanced_layouts : require\n" 11860 "\n" 11861 "layout(points) in;\n" 11862 "layout(triangle_strip, max_vertices = 4) out;\n" 11863 "\n" 11864 "layout (std140) buffer Block {\n" 11865 " vec4 boy;\n" 11866 " layout (align = ALIGN) TYPE man;\n" 11867 "} block;\n" 11868 "\n" 11869 "in vec4 tes_gs[];\n" 11870 "out vec4 gs_fs;\n" 11871 "\n" 11872 "void main()\n" 11873 "{\n" 11874 " if (TYPE(0) == block.man)\n" 11875 " {\n" 11876 " gs_fs = block.boy;\n" 11877 " }\n" 11878 "\n" 11879 " gs_fs += tes_gs[0];\n" 11880 " gl_Position = vec4(-1, -1, 0, 1);\n" 11881 " EmitVertex();\n" 11882 " gs_fs += tes_gs[0];\n" 11883 " gl_Position = vec4(-1, 1, 0, 1);\n" 11884 " EmitVertex();\n" 11885 " gs_fs += tes_gs[0];\n" 11886 " gl_Position = vec4(1, -1, 0, 1);\n" 11887 " EmitVertex();\n" 11888 " gs_fs += tes_gs[0];\n" 11889 " gl_Position = vec4(1, 1, 0, 1);\n" 11890 " EmitVertex();\n" 11891 "}\n" 11892 "\n"; 11893 static const GLchar* tcs = "#version 430 core\n" 11894 "#extension GL_ARB_enhanced_layouts : require\n" 11895 "\n" 11896 "layout(vertices = 1) out;\n" 11897 "\n" 11898 "in vec4 vs_tcs[];\n" 11899 "out vec4 tcs_tes[];\n" 11900 "\n" 11901 "void main()\n" 11902 "{\n" 11903 "\n" 11904 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 11905 "\n" 11906 " gl_TessLevelOuter[0] = 1.0;\n" 11907 " gl_TessLevelOuter[1] = 1.0;\n" 11908 " gl_TessLevelOuter[2] = 1.0;\n" 11909 " gl_TessLevelOuter[3] = 1.0;\n" 11910 " gl_TessLevelInner[0] = 1.0;\n" 11911 " gl_TessLevelInner[1] = 1.0;\n" 11912 "}\n" 11913 "\n"; 11914 static const GLchar* tcs_tested = "#version 430 core\n" 11915 "#extension GL_ARB_enhanced_layouts : require\n" 11916 "\n" 11917 "layout(vertices = 1) out;\n" 11918 "\n" 11919 "layout (std140) buffer Block {\n" 11920 " vec4 boy;\n" 11921 " layout (align = ALIGN) TYPE man;\n" 11922 "} block;\n" 11923 "\n" 11924 "in vec4 vs_tcs[];\n" 11925 "out vec4 tcs_tes[];\n" 11926 "\n" 11927 "void main()\n" 11928 "{\n" 11929 " if (TYPE(0) == block.man)\n" 11930 " {\n" 11931 " tcs_tes[gl_InvocationID] = block.boy;\n" 11932 " }\n" 11933 "\n" 11934 "\n" 11935 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n" 11936 "\n" 11937 " gl_TessLevelOuter[0] = 1.0;\n" 11938 " gl_TessLevelOuter[1] = 1.0;\n" 11939 " gl_TessLevelOuter[2] = 1.0;\n" 11940 " gl_TessLevelOuter[3] = 1.0;\n" 11941 " gl_TessLevelInner[0] = 1.0;\n" 11942 " gl_TessLevelInner[1] = 1.0;\n" 11943 "}\n" 11944 "\n"; 11945 static const GLchar* tes = "#version 430 core\n" 11946 "#extension GL_ARB_enhanced_layouts : require\n" 11947 "\n" 11948 "layout(isolines, point_mode) in;\n" 11949 "\n" 11950 "in vec4 tcs_tes[];\n" 11951 "out vec4 tes_gs;\n" 11952 "\n" 11953 "void main()\n" 11954 "{\n" 11955 " tes_gs = tcs_tes[0];\n" 11956 "}\n" 11957 "\n"; 11958 static const GLchar* tes_tested = "#version 430 core\n" 11959 "#extension GL_ARB_enhanced_layouts : require\n" 11960 "\n" 11961 "layout(isolines, point_mode) in;\n" 11962 "\n" 11963 "layout (std140) buffer Block {\n" 11964 " vec4 boy;\n" 11965 " layout (align = ALIGN) TYPE man;\n" 11966 "} block;\n" 11967 "\n" 11968 "in vec4 tcs_tes[];\n" 11969 "out vec4 tes_gs;\n" 11970 "\n" 11971 "void main()\n" 11972 "{\n" 11973 " if (TYPE(0) == block.man)\n" 11974 " {\n" 11975 " tes_gs = block.boy;\n" 11976 " }\n" 11977 "\n" 11978 " tes_gs += tcs_tes[0];\n" 11979 "}\n" 11980 "\n"; 11981 static const GLchar* vs = "#version 430 core\n" 11982 "#extension GL_ARB_enhanced_layouts : require\n" 11983 "\n" 11984 "in vec4 in_vs;\n" 11985 "out vec4 vs_tcs;\n" 11986 "\n" 11987 "void main()\n" 11988 "{\n" 11989 " vs_tcs = in_vs;\n" 11990 "}\n" 11991 "\n"; 11992 static const GLchar* vs_tested = "#version 430 core\n" 11993 "#extension GL_ARB_enhanced_layouts : require\n" 11994 "\n" 11995 "layout (std140) buffer Block {\n" 11996 " vec4 boy;\n" 11997 " layout (align = ALIGN) TYPE man;\n" 11998 "} block;\n" 11999 "\n" 12000 "in vec4 in_vs;\n" 12001 "out vec4 vs_tcs;\n" 12002 "\n" 12003 "void main()\n" 12004 "{\n" 12005 " if (TYPE(0) == block.man)\n" 12006 " {\n" 12007 " vs_tcs = block.boy;\n" 12008 " }\n" 12009 "\n" 12010 " vs_tcs += in_vs;\n" 12011 "}\n" 12012 "\n"; 12013 12014 std::string source; 12015 testCase& test_case = m_test_cases[test_case_index]; 12016 12017 if (test_case.m_stage == stage) 12018 { 12019 GLchar buffer[16]; 12020 const GLuint alignment = test_case.m_alignment; 12021 const Utils::Type& type = test_case.m_type; 12022 const GLchar* type_name = type.GetGLSLTypeName(); 12023 size_t position = 0; 12024 12025 switch (stage) 12026 { 12027 case Utils::Shader::COMPUTE: 12028 source = cs; 12029 break; 12030 case Utils::Shader::FRAGMENT: 12031 source = fs_tested; 12032 break; 12033 case Utils::Shader::GEOMETRY: 12034 source = gs_tested; 12035 break; 12036 case Utils::Shader::TESS_CTRL: 12037 source = tcs_tested; 12038 break; 12039 case Utils::Shader::TESS_EVAL: 12040 source = tes_tested; 12041 break; 12042 case Utils::Shader::VERTEX: 12043 source = vs_tested; 12044 break; 12045 default: 12046 TCU_FAIL("Invalid enum"); 12047 } 12048 12049 sprintf(buffer, "%d", alignment); 12050 Utils::replaceToken("ALIGN", position, buffer, source); 12051 Utils::replaceToken("TYPE", position, type_name, source); 12052 Utils::replaceToken("TYPE", position, type_name, source); 12053 } 12054 else 12055 { 12056 switch (stage) 12057 { 12058 case Utils::Shader::FRAGMENT: 12059 source = fs; 12060 break; 12061 case Utils::Shader::GEOMETRY: 12062 source = gs; 12063 break; 12064 case Utils::Shader::TESS_CTRL: 12065 source = tcs; 12066 break; 12067 case Utils::Shader::TESS_EVAL: 12068 source = tes; 12069 break; 12070 case Utils::Shader::VERTEX: 12071 source = vs; 12072 break; 12073 default: 12074 TCU_FAIL("Invalid enum"); 12075 } 12076 } 12077 12078 return source; 12079 } 12080 12081 /** Checks if stage is supported 12082 * 12083 * @param stage Shader stage 12084 * 12085 * @return true if supported, false otherwise 12086 **/ 12087 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage) 12088 { 12089 const Functions& gl = m_context.getRenderContext().getFunctions(); 12090 GLint max_supported_buffers = 0; 12091 GLenum pname = 0; 12092 12093 switch (stage) 12094 { 12095 case Utils::Shader::COMPUTE: 12096 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS; 12097 break; 12098 case Utils::Shader::FRAGMENT: 12099 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS; 12100 break; 12101 case Utils::Shader::GEOMETRY: 12102 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS; 12103 break; 12104 case Utils::Shader::TESS_CTRL: 12105 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS; 12106 break; 12107 case Utils::Shader::TESS_EVAL: 12108 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS; 12109 break; 12110 case Utils::Shader::VERTEX: 12111 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS; 12112 break; 12113 default: 12114 TCU_FAIL("Invalid enum"); 12115 } 12116 12117 gl.getIntegerv(pname, &max_supported_buffers); 12118 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 12119 12120 return 1 <= max_supported_buffers; 12121 } 12122 12123 /** Constructor 12124 * 12125 * @param context Test framework context 12126 **/ 12127 SSBAlignmentTest::SSBAlignmentTest(deqp::Context& context) 12128 : TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer") 12129 { 12130 } 12131 12132 /** Get interface of program 12133 * 12134 * @param ignored 12135 * @param program_interface Interface of program 12136 * @param varying_passthrough Collection of connections between in and out variables 12137 **/ 12138 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface& program_interface, 12139 Utils::VaryingPassthrough& varying_passthrough) 12140 { 12141 static const Utils::Type vec4 = Utils::Type::vec4; 12142 12143 #if WRKARD_UNIFORMBLOCKALIGNMENT 12144 12145 static const GLuint block_align = 16; 12146 12147 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */ 12148 12149 static const GLuint block_align = 64; 12150 12151 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */ 12152 12153 static const GLuint fifth_align = 16; 12154 static const GLuint vec4_stride = 16; 12155 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */ 12156 12157 const GLuint first_offset = 0; /* vec4 at 0 */ 12158 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */ 12159 const GLuint third_offset = 12160 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */ 12161 const GLuint fourth_offset = 12162 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */ 12163 const GLuint fifth_offset = 12164 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */ 12165 const GLuint sixth_offset = 12166 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */ 12167 12168 Utils::Interface* structure = program_interface.Structure("Data"); 12169 12170 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4, 12171 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */); 12172 12173 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float, 12174 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(), 12175 Utils::Type::vec4.GetSize() /* offset */); 12176 12177 /* Prepare Block */ 12178 Utils::Interface* vs_buf_Block = program_interface.Block("vs_buf_Block"); 12179 12180 vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4, 12181 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */); 12182 12183 vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure, 12184 0 /* n_array_elements */, data_stride, second_offset); 12185 12186 vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure, 12187 2 /* n_array_elements */, data_stride, third_offset); 12188 12189 vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4, 12190 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset); 12191 12192 vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4, 12193 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset); 12194 12195 vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure, 12196 0 /* n_array_elements */, data_stride, sixth_offset); 12197 12198 const GLuint stride = calculateStride(*vs_buf_Block); 12199 m_data.resize(stride); 12200 generateData(*vs_buf_Block, 0, m_data); 12201 12202 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 12203 12204 /* Add uniform BLOCK */ 12205 #if WRKARD_UNIFORMBLOCKALIGNMENT 12206 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0, 12207 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size()); 12208 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */ 12209 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0, 12210 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size()); 12211 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */ 12212 12213 program_interface.CloneVertexInterface(varying_passthrough); 12214 } 12215 12216 /** Selects if "draw" stages are relevant for test 12217 * 12218 * @param ignored 12219 * 12220 * @return true if all stages support shader storage buffers, false otherwise 12221 **/ 12222 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */) 12223 { 12224 const Functions& gl = m_context.getRenderContext().getFunctions(); 12225 GLint gs_supported_buffers = 0; 12226 GLint tcs_supported_buffers = 0; 12227 GLint tes_supported_buffers = 0; 12228 GLint vs_supported_buffers = 0; 12229 12230 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers); 12231 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers); 12232 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers); 12233 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers); 12234 12235 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 12236 12237 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) && 12238 (1 <= vs_supported_buffers)); 12239 } 12240 12241 /** Constructor 12242 * 12243 * @param context Test framework context 12244 **/ 12245 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context) 12246 : TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected") 12247 { 12248 } 12249 12250 /** Constructor 12251 * 12252 * @param context Test context 12253 * @param test_name Name of test 12254 * @param test_description Description of test 12255 **/ 12256 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context, const glw::GLchar* test_name, 12257 const glw::GLchar* test_description) 12258 : TextureTestBase(context, test_name, test_description) 12259 { 12260 } 12261 12262 /** Get interface of program 12263 * 12264 * @param test_case_index Test case 12265 * @param program_interface Interface of program 12266 * @param varying_passthrough Collection of connections between in and out variables 12267 **/ 12268 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface, 12269 Utils::VaryingPassthrough& varying_passthrough) 12270 { 12271 const Utils::Type type = getType(test_case_index); 12272 12273 m_first_data = type.GenerateDataPacked(); 12274 m_last_data = type.GenerateDataPacked(); 12275 12276 prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough); 12277 prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough); 12278 prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough); 12279 prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough); 12280 prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough); 12281 } 12282 12283 /** Get type name 12284 * 12285 * @param test_case_index Index of test case 12286 * 12287 * @return Name of type test in test_case_index 12288 **/ 12289 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index) 12290 { 12291 return getTypeName(test_case_index); 12292 } 12293 12294 /** Returns number of types to test 12295 * 12296 * @return Number of types, 34 12297 **/ 12298 glw::GLuint VaryingLocationsTest::getTestCaseNumber() 12299 { 12300 return getTypesNumber(); 12301 } 12302 12303 /** Selects if "compute" stage is relevant for test 12304 * 12305 * @param ignored 12306 * 12307 * @return false 12308 **/ 12309 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */) 12310 { 12311 return false; 12312 } 12313 12314 /** 12315 * 12316 * 12317 **/ 12318 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc) 12319 { 12320 GLchar buffer[16]; 12321 std::string globals = "const uint first_input_location = 0u;\n" 12322 "const uint first_output_location = 0u;\n" 12323 "const uint last_input_location = LAST_INPUTu;\n" 12324 "const uint last_output_location = LAST_OUTPUTu;\n"; 12325 size_t position = 100; /* Skip first part */ 12326 12327 sprintf(buffer, "%d", last_in_loc); 12328 Utils::replaceToken("LAST_INPUT", position, buffer, globals); 12329 12330 sprintf(buffer, "%d", last_out_loc); 12331 Utils::replaceToken("LAST_OUTPUT", position, buffer, globals); 12332 12333 return globals; 12334 } 12335 12336 /** 12337 * 12338 **/ 12339 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type, 12340 Utils::ProgramInterface& program_interface, 12341 Utils::VaryingPassthrough& varying_passthrough) 12342 { 12343 const GLuint array_length = 1; 12344 const GLuint first_in_loc = 0; 12345 const GLuint first_out_loc = 0; 12346 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length); 12347 size_t position = 0; 12348 12349 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT); 12350 12351 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT); 12352 12353 const GLchar* qual_first_in = "layout (location = first_input_location)"; 12354 const GLchar* qual_first_out = "layout (location = first_output_location)"; 12355 const GLchar* qual_last_in = "layout (location = last_input_location)"; 12356 const GLchar* qual_last_out = "layout (location = last_output_location)"; 12357 12358 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage); 12359 const GLuint type_size = type.GetSize(); 12360 12361 std::string first_in_name = "PREFIXfirst"; 12362 std::string first_out_name = "PREFIXfirst"; 12363 std::string last_in_name = "PREFIXlast"; 12364 std::string last_out_name = "PREFIXlast"; 12365 12366 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name); 12367 position = 0; 12368 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name); 12369 position = 0; 12370 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name); 12371 position = 0; 12372 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name); 12373 12374 if (Utils::Shader::FRAGMENT == stage) 12375 { 12376 qual_first_in = "layout (location = first_input_location) flat"; 12377 qual_last_in = "layout (location = last_input_location) flat"; 12378 } 12379 if (Utils::Shader::GEOMETRY == stage) 12380 { 12381 qual_first_out = "layout (location = first_output_location) flat"; 12382 qual_last_out = "layout (location = last_output_location) flat"; 12383 } 12384 12385 Utils::Variable* first_in = si.Input( 12386 first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */, 12387 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */, 12388 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */); 12389 12390 Utils::Variable* last_in = 12391 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */, 12392 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 12393 0u /* n_array_elements */, 0u /* stride */, type_size /* offset */, 12394 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */); 12395 12396 if (Utils::Shader::FRAGMENT != stage) 12397 { 12398 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length); 12399 12400 Utils::Variable* first_out = 12401 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */, 12402 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 12403 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, 12404 m_first_data.size() /* data_size */); 12405 12406 Utils::Variable* last_out = si.Output( 12407 last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */, 12408 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */, 12409 0u /* stride */, 0u /* offset */, (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */); 12410 12411 si.m_globals = prepareGlobals(last_in_loc, last_out_loc); 12412 12413 varying_passthrough.Add(stage, first_in, first_out); 12414 varying_passthrough.Add(stage, last_in, last_out); 12415 } 12416 else 12417 { 12418 /* No outputs for fragment shader, so last_output_location can be 0 */ 12419 si.m_globals = prepareGlobals(last_in_loc, 0); 12420 } 12421 } 12422 12423 /** This test should be run with separable programs 12424 * 12425 * @param ignored 12426 * 12427 * @return true 12428 **/ 12429 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */) 12430 { 12431 return false; 12432 } 12433 12434 /* Constants used by VertexAttribLocationsTest */ 12435 const GLuint VertexAttribLocationsTest::m_base_vertex = 4; 12436 const GLuint VertexAttribLocationsTest::m_base_instance = 2; 12437 const GLuint VertexAttribLocationsTest::m_loc_vertex = 2; 12438 const GLuint VertexAttribLocationsTest::m_loc_instance = 5; 12439 const GLuint VertexAttribLocationsTest::m_n_instances = 4; 12440 12441 /** Constructor 12442 * 12443 * @param context Test framework context 12444 **/ 12445 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context& context) 12446 : TextureTestBase(context, "vertex_attrib_locations", 12447 "Test verifies that attribute locations are respected by drawing operations") 12448 { 12449 } 12450 12451 /** Execute proper draw command for test case 12452 * 12453 * @param test_case_index Index of test case 12454 **/ 12455 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index) 12456 { 12457 const Functions& gl = m_context.getRenderContext().getFunctions(); 12458 12459 switch (test_case_index) 12460 { 12461 case DRAWARRAYS: 12462 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 12463 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 12464 break; 12465 case DRAWARRAYSINSTANCED: 12466 gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances); 12467 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced"); 12468 break; 12469 case DRAWELEMENTS: 12470 gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL); 12471 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements"); 12472 break; 12473 case DRAWELEMENTSBASEVERTEX: 12474 gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_base_vertex); 12475 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex"); 12476 break; 12477 case DRAWELEMENTSINSTANCED: 12478 gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances); 12479 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced"); 12480 break; 12481 case DRAWELEMENTSINSTANCEDBASEINSTANCE: 12482 gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances, 12483 m_base_instance); 12484 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance"); 12485 break; 12486 case DRAWELEMENTSINSTANCEDBASEVERTEX: 12487 gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances, 12488 m_base_vertex); 12489 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex"); 12490 break; 12491 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE: 12492 gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, 12493 m_n_instances, m_base_vertex, m_base_instance); 12494 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance"); 12495 break; 12496 default: 12497 TCU_FAIL("Invalid enum"); 12498 } 12499 } 12500 12501 /** Get interface of program 12502 * 12503 * @param ignored 12504 * @param program_interface Interface of program 12505 * @param ignored 12506 **/ 12507 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */, 12508 Utils::ProgramInterface& program_interface, 12509 Utils::VaryingPassthrough& /* varying_passthrough */) 12510 { 12511 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 12512 12513 /* Globals */ 12514 si.m_globals = "const uint vertex_index_location = 2;\n" 12515 "const uint instance_index_location = 5;\n"; 12516 12517 /* Attributes */ 12518 si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */, 12519 0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */, 12520 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */, 12521 (GLvoid*)0 /* data */, 0 /* data_size */); 12522 si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */, 12523 0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */, 12524 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */, 12525 (GLvoid*)0 /* data */, 0 /* data_size */); 12526 } 12527 12528 /** Get name of test case 12529 * 12530 * @param test_case_index Index of test case 12531 * 12532 * @return Name of test case 12533 **/ 12534 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index) 12535 { 12536 std::string result; 12537 12538 switch (test_case_index) 12539 { 12540 case DRAWARRAYS: 12541 result = "DrawArrays"; 12542 break; 12543 case DRAWARRAYSINSTANCED: 12544 result = "DrawArraysInstanced"; 12545 break; 12546 case DRAWELEMENTS: 12547 result = "DrawElements"; 12548 break; 12549 case DRAWELEMENTSBASEVERTEX: 12550 result = "DrawElementsBaseVertex"; 12551 break; 12552 case DRAWELEMENTSINSTANCED: 12553 result = "DrawElementsInstanced"; 12554 break; 12555 case DRAWELEMENTSINSTANCEDBASEINSTANCE: 12556 result = "DrawElementsInstancedBaseInstance"; 12557 break; 12558 case DRAWELEMENTSINSTANCEDBASEVERTEX: 12559 result = "DrawElementsInstancedBaseVertex"; 12560 break; 12561 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE: 12562 result = "DrawElementsInstancedBaseVertexBaseInstance"; 12563 break; 12564 default: 12565 TCU_FAIL("Invalid enum"); 12566 } 12567 12568 return result; 12569 } 12570 12571 /** Get number of test cases 12572 * 12573 * @return Number of test cases 12574 **/ 12575 GLuint VertexAttribLocationsTest::getTestCaseNumber() 12576 { 12577 return TESTCASES_MAX; 12578 } 12579 12580 /** Prepare code snippet that will verify in and uniform variables 12581 * 12582 * @param ignored 12583 * @param ignored 12584 * @param stage Shader stage 12585 * 12586 * @return Code that verify variables 12587 **/ 12588 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */, 12589 Utils::ProgramInterface& /* program_interface */, 12590 Utils::Shader::STAGES stage) 12591 { 12592 std::string verification; 12593 12594 if (Utils::Shader::VERTEX == stage) 12595 { 12596 12597 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE 12598 12599 verification = "if (gl_InstanceID != instance_index)\n" 12600 " {\n" 12601 " result = 12u;\n" 12602 " }\n" 12603 " else if (gl_VertexID != vertex_index)\n" 12604 " {\n" 12605 " result = 11u;\n" 12606 " }\n"; 12607 12608 #else 12609 12610 verification = "if ((gl_VertexID != vertex_index) ||\n" 12611 " (gl_InstanceID != instance_index) )\n" 12612 " {\n" 12613 " result = 0u;\n" 12614 " }\n"; 12615 12616 #endif 12617 } 12618 else 12619 { 12620 verification = ""; 12621 } 12622 12623 return verification; 12624 } 12625 12626 /** Selects if "compute" stage is relevant for test 12627 * 12628 * @param ignored 12629 * 12630 * @return false 12631 **/ 12632 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */) 12633 { 12634 return false; 12635 } 12636 12637 /** Prepare attributes, vertex array object and array buffer 12638 * 12639 * @param ignored 12640 * @param ignored Interface of program 12641 * @param buffer Array buffer 12642 * @param vao Vertex array object 12643 **/ 12644 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */, 12645 Utils::ProgramInterface& /* program_interface */, 12646 Utils::Buffer& buffer, Utils::VertexArray& vao) 12647 { 12648 static const GLuint vertex_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; 12649 static const GLuint instance_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; 12650 12651 std::vector<GLuint> buffer_data; 12652 buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */ 12653 12654 GLubyte* ptr = (GLubyte*)&buffer_data[0]; 12655 12656 /* 12657 When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on, 12658 So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER 12659 */ 12660 if (test_case_index >= 2) 12661 { 12662 buffer.m_buffer = Utils::Buffer::Element; 12663 } 12664 vao.Bind(); 12665 buffer.Bind(); 12666 12667 vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */, 12668 0 /* stride */, 0 /* offset */); 12669 12670 vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */, 12671 false /* normalized */, 0 /* stride */, (GLvoid*)sizeof(vertex_index_data) /* offset */); 12672 // when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance 12673 // the instancecount is 4, the baseinstance is 2, the divisor should be set 2 12674 bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE || 12675 test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE); 12676 vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */, 12677 isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */); 12678 12679 memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data)); 12680 memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data)); 12681 12682 buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr); 12683 } 12684 12685 /** This test should be run with separable programs 12686 * 12687 * @param ignored 12688 * 12689 * @return true 12690 **/ 12691 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */) 12692 { 12693 return false; 12694 } 12695 12696 /** Constructor 12697 * 12698 * @param context Test framework context 12699 **/ 12700 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context& context) 12701 : VaryingLocationsTest(context, "varying_array_locations", 12702 "Test verifies that input and output locations are respected for arrays") 12703 { 12704 } 12705 12706 /** 12707 * 12708 **/ 12709 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type, 12710 Utils::ProgramInterface& program_interface, 12711 Utils::VaryingPassthrough& varying_passthrough) 12712 { 12713 const GLuint array_length = 1u; 12714 const GLuint first_in_loc = 0; 12715 const GLuint first_out_loc = 0; 12716 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length); 12717 size_t position = 0; 12718 12719 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT); 12720 12721 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT); 12722 12723 const GLchar* qual_first_in = "layout (location = first_input_location)"; 12724 const GLchar* qual_first_out = "layout (location = first_output_location)"; 12725 const GLchar* qual_last_in = "layout (location = last_input_location)"; 12726 const GLchar* qual_last_out = "layout (location = last_output_location)"; 12727 12728 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage); 12729 const GLuint type_size = type.GetSize(); 12730 12731 std::string first_in_name = "PREFIXfirst"; 12732 std::string first_out_name = "PREFIXfirst"; 12733 std::string last_in_name = "PREFIXlast"; 12734 std::string last_out_name = "PREFIXlast"; 12735 12736 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name); 12737 position = 0; 12738 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name); 12739 position = 0; 12740 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name); 12741 position = 0; 12742 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name); 12743 12744 if (Utils::Shader::FRAGMENT == stage) 12745 { 12746 qual_first_in = "layout (location = first_input_location) flat"; 12747 qual_last_in = "layout (location = last_input_location) flat"; 12748 } 12749 if (Utils::Shader::GEOMETRY == stage) 12750 { 12751 qual_first_out = "layout (location = first_output_location) flat"; 12752 qual_last_out = "layout (location = last_output_location) flat"; 12753 } 12754 12755 Utils::Variable* first_in = 12756 si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */, 12757 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 12758 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */, 12759 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */); 12760 12761 Utils::Variable* last_in = 12762 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */, 12763 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 12764 array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */, 12765 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */); 12766 12767 if (Utils::Shader::FRAGMENT != stage) 12768 { 12769 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length); 12770 12771 Utils::Variable* first_out = 12772 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */, 12773 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 12774 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */, 12775 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */); 12776 12777 Utils::Variable* last_out = 12778 si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */, 12779 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 12780 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */, 12781 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */); 12782 12783 si.m_globals = prepareGlobals(last_in_loc, last_out_loc); 12784 12785 varying_passthrough.Add(stage, first_in, first_out); 12786 varying_passthrough.Add(stage, last_in, last_out); 12787 } 12788 else 12789 { 12790 /* No outputs for fragment shader, so last_output_location can be 0 */ 12791 si.m_globals = prepareGlobals(last_in_loc, 0); 12792 } 12793 } 12794 12795 /** Constructor 12796 * 12797 * @param context Test framework context 12798 **/ 12799 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context& context) 12800 : TextureTestBase(context, "varying_structure_locations", 12801 "Test verifies that locations are respected when structures are used as in and out ") 12802 { 12803 } 12804 12805 /** Prepare code snippet that will pass in variables to out variables 12806 * 12807 * @param ignored 12808 * @param varying_passthrough Collection of connections between in and out variables 12809 * @param stage Shader stage 12810 * 12811 * @return Code that pass in variables to next stage 12812 **/ 12813 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */, 12814 Utils::VaryingPassthrough& varying_passthrough, 12815 Utils::Shader::STAGES stage) 12816 { 12817 std::string result; 12818 12819 if (Utils::Shader::VERTEX != stage) 12820 { 12821 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage); 12822 } 12823 else 12824 { 12825 result = " vs_tcs_output[0].single = vs_in_single[0];\n" 12826 " vs_tcs_output[0].array[0] = vs_in_array[0];\n"; 12827 } 12828 12829 return result; 12830 } 12831 12832 /** Get interface of program 12833 * 12834 * @param test_case_index Test case 12835 * @param program_interface Interface of program 12836 * @param varying_passthrough Collection of connections between in and out variables 12837 **/ 12838 void VaryingStructureLocationsTest::getProgramInterface(GLuint test_case_index, 12839 Utils::ProgramInterface& program_interface, 12840 Utils::VaryingPassthrough& varying_passthrough) 12841 { 12842 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 12843 const Utils::Type type = getType(test_case_index); 12844 12845 /* Prepare data */ 12846 // We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct 12847 m_single_data = type.GenerateDataPacked(); 12848 m_array_data = type.GenerateDataPacked(); 12849 12850 m_data.resize(m_single_data.size() + m_array_data.size()); 12851 GLubyte* ptr = (GLubyte*)&m_data[0]; 12852 memcpy(ptr, &m_single_data[0], m_single_data.size()); 12853 memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size()); 12854 12855 Utils::Interface* structure = program_interface.Structure("Data"); 12856 12857 structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */, 12858 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */); 12859 12860 // the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed. 12861 structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type, 12862 false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */); 12863 12864 si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */, 12865 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_single_data[0] /* data */, 12866 m_single_data.size() /* data_size */); 12867 12868 si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */, 12869 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */, 12870 (GLvoid*)&m_array_data[0] /* data */, m_array_data.size() /* data_size */); 12871 12872 si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure, 12873 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */, 12874 m_data.size() /* data_size */); 12875 12876 program_interface.CloneVertexInterface(varying_passthrough); 12877 } 12878 12879 /** Get type name 12880 * 12881 * @param test_case_index Index of test case 12882 * 12883 * @return Name of type test in test_case_index 12884 **/ 12885 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index) 12886 { 12887 return getTypeName(test_case_index); 12888 } 12889 12890 /** Returns number of types to test 12891 * 12892 * @return Number of types, 34 12893 **/ 12894 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber() 12895 { 12896 return getTypesNumber(); 12897 } 12898 12899 /** Selects if "compute" stage is relevant for test 12900 * 12901 * @param ignored 12902 * 12903 * @return false 12904 **/ 12905 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */) 12906 { 12907 return false; 12908 } 12909 12910 /** This test should be run with separable programs 12911 * 12912 * @param ignored 12913 * 12914 * @return true 12915 **/ 12916 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */) 12917 { 12918 return false; 12919 } 12920 12921 /** Constructor 12922 * 12923 * @param context Test context 12924 * @param test_name Name of test 12925 * @param test_description Description of test 12926 **/ 12927 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context& context) 12928 : NegativeTestBase(context, "varying_structure_member_location", 12929 "Test verifies that compiler does not allow location qualifier on member of strucure") 12930 { 12931 } 12932 12933 /** Source for given test case and stage 12934 * 12935 * @param test_case_index Index of test case 12936 * @param stage Shader stage 12937 * 12938 * @return Shader source 12939 **/ 12940 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 12941 { 12942 static const GLchar* struct_definition = "struct Data {\n" 12943 " vec4 gohan;\n" 12944 " layout (location = 4) vec4 goten;\n" 12945 "};\n"; 12946 static const GLchar* input_var = "in Data data;\n"; 12947 static const GLchar* output_var = "out Data data;\n"; 12948 static const GLchar* input_use = " result += data.gohan + data.goten;\n"; 12949 static const GLchar* output_use = " data.gohan = result / 2;\n" 12950 " data.goten = result / 4 - data.gohan;\n"; 12951 static const GLchar* fs = "#version 430 core\n" 12952 "#extension GL_ARB_enhanced_layouts : require\n" 12953 "\n" 12954 "in vec4 gs_fs;\n" 12955 "out vec4 fs_out;\n" 12956 "\n" 12957 "void main()\n" 12958 "{\n" 12959 " fs_out = gs_fs;\n" 12960 "}\n" 12961 "\n"; 12962 static const GLchar* fs_tested = "#version 430 core\n" 12963 "#extension GL_ARB_enhanced_layouts : require\n" 12964 "\n" 12965 "STRUCT_DEFINITION" 12966 "\n" 12967 "VARIABLE_DEFINITION" 12968 "\n" 12969 "in vec4 gs_fs;\n" 12970 "out vec4 fs_out;\n" 12971 "\n" 12972 "void main()\n" 12973 "{\n" 12974 " vec4 result = gs_fs;\n" 12975 "\n" 12976 "VARIABLE_USE" 12977 "\n" 12978 " fs_out += result;\n" 12979 "}\n" 12980 "\n"; 12981 static const GLchar* gs = "#version 430 core\n" 12982 "#extension GL_ARB_enhanced_layouts : require\n" 12983 "\n" 12984 "layout(points) in;\n" 12985 "layout(triangle_strip, max_vertices = 4) out;\n" 12986 "\n" 12987 "in vec4 tes_gs[];\n" 12988 "out vec4 gs_fs;\n" 12989 "\n" 12990 "void main()\n" 12991 "{\n" 12992 " gs_fs = tes_gs[0];\n" 12993 " gl_Position = vec4(-1, -1, 0, 1);\n" 12994 " EmitVertex();\n" 12995 " gs_fs = tes_gs[0];\n" 12996 " gl_Position = vec4(-1, 1, 0, 1);\n" 12997 " EmitVertex();\n" 12998 " gs_fs = tes_gs[0];\n" 12999 " gl_Position = vec4(1, -1, 0, 1);\n" 13000 " EmitVertex();\n" 13001 " gs_fs = tes_gs[0];\n" 13002 " gl_Position = vec4(1, 1, 0, 1);\n" 13003 " EmitVertex();\n" 13004 "}\n" 13005 "\n"; 13006 static const GLchar* gs_tested = "#version 430 core\n" 13007 "#extension GL_ARB_enhanced_layouts : require\n" 13008 "\n" 13009 "layout(points) in;\n" 13010 "layout(triangle_strip, max_vertices = 4) out;\n" 13011 "\n" 13012 "STRUCT_DEFINITION" 13013 "\n" 13014 "VARIABLE_DEFINITION" 13015 "\n" 13016 "in vec4 tes_gs[];\n" 13017 "out vec4 gs_fs;\n" 13018 "\n" 13019 "void main()\n" 13020 "{\n" 13021 " vec4 result = tes_gs[0];\n" 13022 "\n" 13023 "VARIABLE_USE" 13024 "\n" 13025 " gs_fs = result;\n" 13026 " gl_Position = vec4(-1, -1, 0, 1);\n" 13027 " EmitVertex();\n" 13028 " gs_fs = result;\n" 13029 " gl_Position = vec4(-1, 1, 0, 1);\n" 13030 " EmitVertex();\n" 13031 " gs_fs = result;\n" 13032 " gl_Position = vec4(1, -1, 0, 1);\n" 13033 " EmitVertex();\n" 13034 " gs_fs = result;\n" 13035 " gl_Position = vec4(1, 1, 0, 1);\n" 13036 " EmitVertex();\n" 13037 "}\n" 13038 "\n"; 13039 static const GLchar* tcs = "#version 430 core\n" 13040 "#extension GL_ARB_enhanced_layouts : require\n" 13041 "\n" 13042 "layout(vertices = 1) out;\n" 13043 "\n" 13044 "in vec4 vs_tcs[];\n" 13045 "out vec4 tcs_tes[];\n" 13046 "\n" 13047 "void main()\n" 13048 "{\n" 13049 "\n" 13050 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 13051 "\n" 13052 " gl_TessLevelOuter[0] = 1.0;\n" 13053 " gl_TessLevelOuter[1] = 1.0;\n" 13054 " gl_TessLevelOuter[2] = 1.0;\n" 13055 " gl_TessLevelOuter[3] = 1.0;\n" 13056 " gl_TessLevelInner[0] = 1.0;\n" 13057 " gl_TessLevelInner[1] = 1.0;\n" 13058 "}\n" 13059 "\n"; 13060 static const GLchar* tcs_tested = "#version 430 core\n" 13061 "#extension GL_ARB_enhanced_layouts : require\n" 13062 "\n" 13063 "layout(vertices = 1) out;\n" 13064 "\n" 13065 "STRUCT_DEFINITION" 13066 "\n" 13067 "VARIABLE_DEFINITION" 13068 "\n" 13069 "in vec4 vs_tcs[];\n" 13070 "out vec4 tcs_tes[];\n" 13071 "\n" 13072 "void main()\n" 13073 "{\n" 13074 " vec4 result = vs_tcs[gl_InvocationID];\n" 13075 "\n" 13076 "VARIABLE_USE" 13077 "\n" 13078 " tcs_tes[gl_InvocationID] = result;\n" 13079 "\n" 13080 " gl_TessLevelOuter[0] = 1.0;\n" 13081 " gl_TessLevelOuter[1] = 1.0;\n" 13082 " gl_TessLevelOuter[2] = 1.0;\n" 13083 " gl_TessLevelOuter[3] = 1.0;\n" 13084 " gl_TessLevelInner[0] = 1.0;\n" 13085 " gl_TessLevelInner[1] = 1.0;\n" 13086 "}\n" 13087 "\n"; 13088 static const GLchar* tes = "#version 430 core\n" 13089 "#extension GL_ARB_enhanced_layouts : require\n" 13090 "\n" 13091 "layout(isolines, point_mode) in;\n" 13092 "\n" 13093 "in vec4 tcs_tes[];\n" 13094 "out vec4 tes_gs;\n" 13095 "\n" 13096 "void main()\n" 13097 "{\n" 13098 " tes_gs = tcs_tes[0];\n" 13099 "}\n" 13100 "\n"; 13101 static const GLchar* tes_tested = "#version 430 core\n" 13102 "#extension GL_ARB_enhanced_layouts : require\n" 13103 "\n" 13104 "layout(isolines, point_mode) in;\n" 13105 "\n" 13106 "STRUCT_DEFINITION" 13107 "\n" 13108 "VARIABLE_DEFINITION" 13109 "\n" 13110 "in vec4 tcs_tes[];\n" 13111 "out vec4 tes_gs;\n" 13112 "\n" 13113 "void main()\n" 13114 "{\n" 13115 " vec4 result = tcs_tes[0];\n" 13116 "\n" 13117 "VARIABLE_USE" 13118 "\n" 13119 " tes_gs += result;\n" 13120 "}\n" 13121 "\n"; 13122 static const GLchar* vs = "#version 430 core\n" 13123 "#extension GL_ARB_enhanced_layouts : require\n" 13124 "\n" 13125 "in vec4 in_vs;\n" 13126 "out vec4 vs_tcs;\n" 13127 "\n" 13128 "void main()\n" 13129 "{\n" 13130 " vs_tcs = in_vs;\n" 13131 "}\n" 13132 "\n"; 13133 static const GLchar* vs_tested = "#version 430 core\n" 13134 "#extension GL_ARB_enhanced_layouts : require\n" 13135 "\n" 13136 "STRUCT_DEFINITION" 13137 "\n" 13138 "VARIABLE_DEFINITION" 13139 "\n" 13140 "in vec4 in_vs;\n" 13141 "out vec4 vs_tcs;\n" 13142 "\n" 13143 "void main()\n" 13144 "{\n" 13145 " vec4 result = in_vs;\n" 13146 "\n" 13147 "VARIABLE_USE" 13148 "\n" 13149 " vs_tcs += result;\n" 13150 "}\n" 13151 "\n"; 13152 13153 std::string source; 13154 testCase& test_case = m_test_cases[test_case_index]; 13155 const GLchar* var_definition = 0; 13156 const GLchar* var_use = 0; 13157 13158 if (true == test_case.m_is_input) 13159 { 13160 var_definition = input_var; 13161 var_use = input_use; 13162 } 13163 else 13164 { 13165 var_definition = output_var; 13166 var_use = output_use; 13167 } 13168 13169 if (test_case.m_stage == stage) 13170 { 13171 size_t position = 0; 13172 13173 switch (stage) 13174 { 13175 case Utils::Shader::FRAGMENT: 13176 source = fs_tested; 13177 break; 13178 case Utils::Shader::GEOMETRY: 13179 source = gs_tested; 13180 break; 13181 case Utils::Shader::TESS_CTRL: 13182 source = tcs_tested; 13183 break; 13184 case Utils::Shader::TESS_EVAL: 13185 source = tes_tested; 13186 break; 13187 case Utils::Shader::VERTEX: 13188 source = vs_tested; 13189 break; 13190 default: 13191 TCU_FAIL("Invalid enum"); 13192 } 13193 13194 Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source); 13195 Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source); 13196 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 13197 } 13198 else 13199 { 13200 switch (stage) 13201 { 13202 case Utils::Shader::FRAGMENT: 13203 source = fs; 13204 break; 13205 case Utils::Shader::GEOMETRY: 13206 source = gs; 13207 break; 13208 case Utils::Shader::TESS_CTRL: 13209 source = tcs; 13210 break; 13211 case Utils::Shader::TESS_EVAL: 13212 source = tes; 13213 break; 13214 case Utils::Shader::VERTEX: 13215 source = vs; 13216 break; 13217 default: 13218 TCU_FAIL("Invalid enum"); 13219 } 13220 } 13221 13222 return source; 13223 } 13224 13225 /** Get description of test case 13226 * 13227 * @param test_case_index Index of test case 13228 * 13229 * @return Test case description 13230 **/ 13231 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index) 13232 { 13233 std::stringstream stream; 13234 testCase& test_case = m_test_cases[test_case_index]; 13235 13236 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: "; 13237 13238 if (true == test_case.m_is_input) 13239 { 13240 stream << "input"; 13241 } 13242 else 13243 { 13244 stream << "output"; 13245 } 13246 13247 return stream.str(); 13248 } 13249 13250 /** Get number of test cases 13251 * 13252 * @return Number of test cases 13253 **/ 13254 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber() 13255 { 13256 return static_cast<GLuint>(m_test_cases.size()); 13257 } 13258 13259 /** Selects if "compute" stage is relevant for test 13260 * 13261 * @param ignored 13262 * 13263 * @return false 13264 **/ 13265 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */) 13266 { 13267 return false; 13268 } 13269 13270 /** Prepare all test cases 13271 * 13272 **/ 13273 void VaryingStructureMemberLocationTest::testInit() 13274 { 13275 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 13276 { 13277 if (Utils::Shader::COMPUTE == stage) 13278 { 13279 continue; 13280 } 13281 13282 testCase test_case_in = { true, (Utils::Shader::STAGES)stage }; 13283 testCase test_case_out = { false, (Utils::Shader::STAGES)stage }; 13284 13285 m_test_cases.push_back(test_case_in); 13286 13287 if (Utils::Shader::FRAGMENT != stage) 13288 { 13289 m_test_cases.push_back(test_case_out); 13290 } 13291 } 13292 } 13293 13294 /** Constructor 13295 * 13296 * @param context Test framework context 13297 **/ 13298 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context& context) 13299 : TextureTestBase(context, "varying_block_locations", 13300 "Test verifies that locations are respected when blocks are used as in and out ") 13301 { 13302 } 13303 13304 /** Prepare code snippet that will pass in variables to out variables 13305 * 13306 * @param ignored 13307 * @param varying_passthrough Collection of connections between in and out variables 13308 * @param stage Shader stage 13309 * 13310 * @return Code that pass in variables to next stage 13311 **/ 13312 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */, 13313 Utils::VaryingPassthrough& varying_passthrough, 13314 Utils::Shader::STAGES stage) 13315 { 13316 std::string result; 13317 13318 if (Utils::Shader::VERTEX != stage) 13319 { 13320 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage); 13321 } 13322 else 13323 { 13324 result = "vs_tcs_block.third = vs_in_third;\n" 13325 " vs_tcs_block.fourth = vs_in_fourth;\n" 13326 " vs_tcs_block.fifth = vs_in_fifth;\n"; 13327 } 13328 13329 return result; 13330 } 13331 13332 /** Get interface of program 13333 * 13334 * @param ignored 13335 * @param program_interface Interface of program 13336 * @param varying_passthrough Collection of connections between in and out variables 13337 **/ 13338 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */, 13339 Utils::ProgramInterface& program_interface, 13340 Utils::VaryingPassthrough& varying_passthrough) 13341 { 13342 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 13343 const Utils::Type vec4 = Utils::Type::vec4; 13344 13345 /* Prepare data */ 13346 m_third_data = vec4.GenerateData(); 13347 m_fourth_data = vec4.GenerateData(); 13348 m_fifth_data = vec4.GenerateData(); 13349 13350 /* Memory layout is different from location layout */ 13351 const GLuint fifth_offset = 0u; 13352 const GLuint third_offset = static_cast<GLuint>(fifth_offset + m_fifth_data.size()); 13353 const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size()); 13354 13355 m_data.resize(fourth_offset + m_fourth_data.size()); 13356 GLubyte* ptr = (GLubyte*)&m_data[0]; 13357 memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size()); 13358 memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size()); 13359 memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size()); 13360 13361 Utils::Interface* block = program_interface.Block("vs_tcs_Block"); 13362 13363 block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */, 13364 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */); 13365 13366 block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4, 13367 false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */); 13368 13369 block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */, 13370 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */); 13371 13372 si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block, 13373 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */, 13374 m_data.size() /* data_size */); 13375 13376 si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */, 13377 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */, 13378 (GLvoid*)&m_third_data[0] /* data */, m_third_data.size() /* data_size */); 13379 13380 si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */, 13381 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */, 13382 (GLvoid*)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */); 13383 13384 si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */, 13385 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */, 13386 (GLvoid*)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */); 13387 13388 program_interface.CloneVertexInterface(varying_passthrough); 13389 } 13390 13391 /** Selects if "compute" stage is relevant for test 13392 * 13393 * @param ignored 13394 * 13395 * @return false 13396 **/ 13397 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */) 13398 { 13399 return false; 13400 } 13401 13402 /** This test should be run with separable programs 13403 * 13404 * @param ignored 13405 * 13406 * @return true 13407 **/ 13408 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */) 13409 { 13410 return false; 13411 } 13412 13413 /** Constructor 13414 * 13415 * @param context Test framework context 13416 **/ 13417 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context& context) 13418 : NegativeTestBase( 13419 context, "varying_block_member_locations", 13420 "Test verifies that compilation error is reported when not all members of block are qualified with location") 13421 { 13422 } 13423 13424 /** Source for given test case and stage 13425 * 13426 * @param test_case_index Index of test case 13427 * @param stage Shader stage 13428 * 13429 * @return Shader source 13430 **/ 13431 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 13432 { 13433 static const GLchar* block_definition_all = "Goku {\n" 13434 " layout (location = 2) vec4 gohan;\n" 13435 " layout (location = 4) vec4 goten;\n" 13436 " layout (location = 6) vec4 chichi;\n" 13437 "} gokuARRAY;\n"; 13438 static const GLchar* block_definition_default = "Goku {\n" 13439 " vec4 gohan;\n" 13440 " vec4 goten;\n" 13441 " vec4 chichi;\n" 13442 "} gokuARRAY;\n"; 13443 static const GLchar* block_definition_one = "Goku {\n" 13444 " vec4 gohan;\n" 13445 " layout (location = 4) vec4 goten;\n" 13446 " vec4 chichi;\n" 13447 "} gokuARRAY;\n"; 13448 static const GLchar* input_use = " result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n"; 13449 static const GLchar* output_use = " gokuINDEX.gohan = result / 2;\n" 13450 " gokuINDEX.goten = result / 4 - gokuINDEX.gohan;\n" 13451 " gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n"; 13452 static const GLchar* fs = "#version 430 core\n" 13453 "#extension GL_ARB_enhanced_layouts : require\n" 13454 "\n" 13455 "in vec4 gs_fs;\n" 13456 "out vec4 fs_out;\n" 13457 "\n" 13458 "void main()\n" 13459 "{\n" 13460 " fs_out = gs_fs;\n" 13461 "}\n" 13462 "\n"; 13463 static const GLchar* fs_tested = "#version 430 core\n" 13464 "#extension GL_ARB_enhanced_layouts : require\n" 13465 "\n" 13466 "DIRECTION BLOCK_DEFINITION" 13467 "\n" 13468 "in vec4 gs_fs;\n" 13469 "out vec4 fs_out;\n" 13470 "\n" 13471 "void main()\n" 13472 "{\n" 13473 " vec4 result = gs_fs;\n" 13474 "\n" 13475 "VARIABLE_USE" 13476 "\n" 13477 " fs_out = result;\n" 13478 "}\n" 13479 "\n"; 13480 static const GLchar* gs = "#version 430 core\n" 13481 "#extension GL_ARB_enhanced_layouts : require\n" 13482 "\n" 13483 "layout(points) in;\n" 13484 "layout(triangle_strip, max_vertices = 4) out;\n" 13485 "\n" 13486 "in vec4 tes_gs[];\n" 13487 "out vec4 gs_fs;\n" 13488 "\n" 13489 "void main()\n" 13490 "{\n" 13491 " gs_fs = tes_gs[0];\n" 13492 " gl_Position = vec4(-1, -1, 0, 1);\n" 13493 " EmitVertex();\n" 13494 " gs_fs = tes_gs[0];\n" 13495 " gl_Position = vec4(-1, 1, 0, 1);\n" 13496 " EmitVertex();\n" 13497 " gs_fs = tes_gs[0];\n" 13498 " gl_Position = vec4(1, -1, 0, 1);\n" 13499 " EmitVertex();\n" 13500 " gs_fs = tes_gs[0];\n" 13501 " gl_Position = vec4(1, 1, 0, 1);\n" 13502 " EmitVertex();\n" 13503 "}\n" 13504 "\n"; 13505 static const GLchar* gs_tested = "#version 430 core\n" 13506 "#extension GL_ARB_enhanced_layouts : require\n" 13507 "\n" 13508 "layout(points) in;\n" 13509 "layout(triangle_strip, max_vertices = 4) out;\n" 13510 "\n" 13511 "DIRECTION BLOCK_DEFINITION" 13512 "\n" 13513 "in vec4 tes_gs[];\n" 13514 "out vec4 gs_fs;\n" 13515 "\n" 13516 "void main()\n" 13517 "{\n" 13518 " vec4 result = tes_gs[0];\n" 13519 "\n" 13520 "VARIABLE_USE" 13521 "\n" 13522 " gs_fs = result;\n" 13523 " gl_Position = vec4(-1, -1, 0, 1);\n" 13524 " EmitVertex();\n" 13525 " gs_fs = result;\n" 13526 " gl_Position = vec4(-1, 1, 0, 1);\n" 13527 " EmitVertex();\n" 13528 " gs_fs = result;\n" 13529 " gl_Position = vec4(1, -1, 0, 1);\n" 13530 " EmitVertex();\n" 13531 " gs_fs = result;\n" 13532 " gl_Position = vec4(1, 1, 0, 1);\n" 13533 " EmitVertex();\n" 13534 "}\n" 13535 "\n"; 13536 static const GLchar* tcs = "#version 430 core\n" 13537 "#extension GL_ARB_enhanced_layouts : require\n" 13538 "\n" 13539 "layout(vertices = 1) out;\n" 13540 "\n" 13541 "in vec4 vs_tcs[];\n" 13542 "out vec4 tcs_tes[];\n" 13543 "\n" 13544 "void main()\n" 13545 "{\n" 13546 "\n" 13547 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 13548 "\n" 13549 " gl_TessLevelOuter[0] = 1.0;\n" 13550 " gl_TessLevelOuter[1] = 1.0;\n" 13551 " gl_TessLevelOuter[2] = 1.0;\n" 13552 " gl_TessLevelOuter[3] = 1.0;\n" 13553 " gl_TessLevelInner[0] = 1.0;\n" 13554 " gl_TessLevelInner[1] = 1.0;\n" 13555 "}\n" 13556 "\n"; 13557 static const GLchar* tcs_tested = "#version 430 core\n" 13558 "#extension GL_ARB_enhanced_layouts : require\n" 13559 "\n" 13560 "layout(vertices = 1) out;\n" 13561 "\n" 13562 "DIRECTION BLOCK_DEFINITION" 13563 "\n" 13564 "in vec4 vs_tcs[];\n" 13565 "out vec4 tcs_tes[];\n" 13566 "\n" 13567 "void main()\n" 13568 "{\n" 13569 " vec4 result = vs_tcs[gl_InvocationID];\n" 13570 "\n" 13571 "VARIABLE_USE" 13572 "\n" 13573 " tcs_tes[gl_InvocationID] = result;\n" 13574 "\n" 13575 " gl_TessLevelOuter[0] = 1.0;\n" 13576 " gl_TessLevelOuter[1] = 1.0;\n" 13577 " gl_TessLevelOuter[2] = 1.0;\n" 13578 " gl_TessLevelOuter[3] = 1.0;\n" 13579 " gl_TessLevelInner[0] = 1.0;\n" 13580 " gl_TessLevelInner[1] = 1.0;\n" 13581 "}\n" 13582 "\n"; 13583 static const GLchar* tes = "#version 430 core\n" 13584 "#extension GL_ARB_enhanced_layouts : require\n" 13585 "\n" 13586 "layout(isolines, point_mode) in;\n" 13587 "\n" 13588 "in vec4 tcs_tes[];\n" 13589 "out vec4 tes_gs;\n" 13590 "\n" 13591 "void main()\n" 13592 "{\n" 13593 " tes_gs = tcs_tes[0];\n" 13594 "}\n" 13595 "\n"; 13596 static const GLchar* tes_tested = "#version 430 core\n" 13597 "#extension GL_ARB_enhanced_layouts : require\n" 13598 "\n" 13599 "layout(isolines, point_mode) in;\n" 13600 "\n" 13601 "DIRECTION BLOCK_DEFINITION" 13602 "\n" 13603 "in vec4 tcs_tes[];\n" 13604 "out vec4 tes_gs;\n" 13605 "\n" 13606 "void main()\n" 13607 "{\n" 13608 " vec4 result = tcs_tes[0];\n" 13609 "\n" 13610 "VARIABLE_USE" 13611 "\n" 13612 " tes_gs = result;\n" 13613 "}\n" 13614 "\n"; 13615 static const GLchar* vs = "#version 430 core\n" 13616 "#extension GL_ARB_enhanced_layouts : require\n" 13617 "\n" 13618 "in vec4 in_vs;\n" 13619 "out vec4 vs_tcs;\n" 13620 "\n" 13621 "void main()\n" 13622 "{\n" 13623 " vs_tcs = in_vs;\n" 13624 "}\n" 13625 "\n"; 13626 static const GLchar* vs_tested = "#version 430 core\n" 13627 "#extension GL_ARB_enhanced_layouts : require\n" 13628 "\n" 13629 "DIRECTION BLOCK_DEFINITION" 13630 "\n" 13631 "in vec4 in_vs;\n" 13632 "out vec4 vs_tcs;\n" 13633 "\n" 13634 "void main()\n" 13635 "{\n" 13636 " vec4 result = in_vs;\n" 13637 "\n" 13638 "VARIABLE_USE" 13639 "\n" 13640 " vs_tcs = result;\n" 13641 "}\n" 13642 "\n"; 13643 13644 static const GLchar* shaders_in[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 }, 13645 /* vs */ { 0, vs_tested, tcs, tes, gs, fs }, 13646 /* tcs */ { 0, vs_tested, tcs_tested, tes, gs, fs }, 13647 /* tes */ { 0, vs, tcs_tested, tes_tested, gs, fs }, 13648 /* gs */ { 0, vs, tcs, tes_tested, gs_tested, fs }, 13649 /* fs */ { 0, vs, tcs, tes, gs_tested, fs_tested } }; 13650 13651 static const GLchar* shaders_out[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 }, 13652 /* vs */ { 0, vs_tested, tcs_tested, tes, gs, fs }, 13653 /* tcs */ { 0, vs, tcs_tested, tes_tested, gs, fs }, 13654 /* tes */ { 0, vs, tcs, tes_tested, gs_tested, fs }, 13655 /* gs */ { 0, vs, tcs, tes, gs_tested, fs_tested }, 13656 /* fs */ { 0, 0, 0, 0, 0, 0 } }; 13657 13658 static const bool require_modifications_in[6][6] = { 13659 /* cs */ { false, false, false, false, false, false }, 13660 /* vs */ { false, true, false, false, false, false }, 13661 /* tcs */ { false, true, true, false, false, false }, 13662 /* tes */ { false, false, true, true, false, false }, 13663 /* gs */ { false, false, false, true, true, false }, 13664 /* fs */ { false, false, false, false, true, true } 13665 }; 13666 13667 static const bool require_modifications_out[6][6] = { 13668 /* cs */ { false, false, false, false, false, false }, 13669 /* vs */ { false, true, true, false, false, false }, 13670 /* tcs */ { false, false, true, true, false, false }, 13671 /* tes */ { false, false, false, true, true, false }, 13672 /* gs */ { false, false, false, false, true, true }, 13673 /* fs */ { false, false, false, false, false, false } 13674 }; 13675 13676 const GLchar* array = ""; 13677 const GLchar* definition = block_definition_default; 13678 const GLchar* direction = "out"; 13679 const GLchar* index = ""; 13680 bool require_modifications = false; 13681 std::string source; 13682 testCase& test_case = m_test_cases[test_case_index]; 13683 const GLchar* var_use = output_use; 13684 13685 if (true == test_case.m_is_input) 13686 { 13687 require_modifications = require_modifications_in[test_case.m_stage][stage]; 13688 source = shaders_in[test_case.m_stage][stage]; 13689 13690 if (test_case.m_stage == stage) 13691 { 13692 direction = "in"; 13693 var_use = input_use; 13694 } 13695 } 13696 else 13697 { 13698 require_modifications = require_modifications_out[test_case.m_stage][stage]; 13699 source = shaders_out[test_case.m_stage][stage]; 13700 13701 if (test_case.m_stage != stage) 13702 { 13703 direction = "in"; 13704 var_use = input_use; 13705 } 13706 } 13707 13708 if (test_case.m_stage == stage) 13709 { 13710 if (true == test_case.m_qualify_all) 13711 { 13712 definition = block_definition_all; 13713 } 13714 else 13715 { 13716 definition = block_definition_one; 13717 } 13718 } 13719 13720 // Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation evaluation 13721 // inputs all have an additional level of arrayness relative to other shader inputs and outputs. 13722 switch (stage) 13723 { 13724 case Utils::Shader::FRAGMENT: 13725 break; 13726 case Utils::Shader::TESS_CTRL: 13727 array = "[]"; 13728 index = "[gl_InvocationID]"; 13729 break; 13730 // geometry shader's input must have one more dimension than tessellation evaluation shader's output, 13731 // the GS input block is an array, so the DS output can't be declared as an array 13732 case Utils::Shader::GEOMETRY: 13733 case Utils::Shader::TESS_EVAL: 13734 { 13735 if (std::string(direction) == std::string("in")) // match HS output and DS input 13736 { 13737 array = "[]"; 13738 index = "[0]"; 13739 } 13740 else // match DS output and GS input 13741 { 13742 array = ""; 13743 index = ""; 13744 } 13745 } 13746 break; 13747 case Utils::Shader::VERTEX: 13748 break; 13749 default: 13750 TCU_FAIL("Invalid enum"); 13751 } 13752 13753 if (true == require_modifications) 13754 { 13755 size_t position = 0; 13756 size_t temp; 13757 13758 Utils::replaceToken("DIRECTION", position, direction, source); 13759 temp = position; 13760 Utils::replaceToken("BLOCK_DEFINITION", position, definition, source); 13761 position = temp; 13762 Utils::replaceToken("ARRAY", position, array, source); 13763 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 13764 13765 Utils::replaceAllTokens("INDEX", index, source); 13766 } 13767 else 13768 { 13769 switch (stage) 13770 { 13771 case Utils::Shader::FRAGMENT: 13772 source = fs; 13773 break; 13774 case Utils::Shader::GEOMETRY: 13775 source = gs; 13776 break; 13777 case Utils::Shader::TESS_CTRL: 13778 source = tcs; 13779 break; 13780 case Utils::Shader::TESS_EVAL: 13781 source = tes; 13782 break; 13783 case Utils::Shader::VERTEX: 13784 source = vs; 13785 break; 13786 default: 13787 TCU_FAIL("Invalid enum"); 13788 } 13789 } 13790 13791 return source; 13792 } 13793 13794 /** Get description of test case 13795 * 13796 * @param test_case_index Index of test case 13797 * 13798 * @return Test case description 13799 **/ 13800 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index) 13801 { 13802 std::stringstream stream; 13803 testCase& test_case = m_test_cases[test_case_index]; 13804 13805 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: "; 13806 13807 if (true == test_case.m_is_input) 13808 { 13809 stream << "input"; 13810 } 13811 else 13812 { 13813 stream << "output"; 13814 } 13815 13816 if (true == test_case.m_qualify_all) 13817 { 13818 stream << ", all members qualified"; 13819 } 13820 else 13821 { 13822 stream << ", not all members qualified"; 13823 } 13824 13825 return stream.str(); 13826 } 13827 13828 /** Get number of test cases 13829 * 13830 * @return Number of test cases 13831 **/ 13832 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber() 13833 { 13834 return static_cast<GLuint>(m_test_cases.size()); 13835 } 13836 13837 /** Selects if "compute" stage is relevant for test 13838 * 13839 * @param ignored 13840 * 13841 * @return false 13842 **/ 13843 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */) 13844 { 13845 return false; 13846 } 13847 13848 /** Selects if compilation failure is expected result 13849 * 13850 * @param test_case_index Index of test case 13851 * 13852 * @return false when all members are qualified, true otherwise 13853 **/ 13854 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index) 13855 { 13856 return (true != m_test_cases[test_case_index].m_qualify_all); 13857 } 13858 13859 /** Prepare all test cases 13860 * 13861 **/ 13862 void VaryingBlockMemberLocationsTest::testInit() 13863 { 13864 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 13865 { 13866 if (Utils::Shader::COMPUTE == stage) 13867 { 13868 continue; 13869 } 13870 13871 testCase test_case_in_all = { true, true, (Utils::Shader::STAGES)stage }; 13872 testCase test_case_in_one = { true, false, (Utils::Shader::STAGES)stage }; 13873 testCase test_case_out_all = { false, true, (Utils::Shader::STAGES)stage }; 13874 testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage }; 13875 13876 if (Utils::Shader::VERTEX != stage) 13877 { 13878 m_test_cases.push_back(test_case_in_all); 13879 m_test_cases.push_back(test_case_in_one); 13880 } 13881 13882 if (Utils::Shader::FRAGMENT != stage) 13883 { 13884 m_test_cases.push_back(test_case_out_all); 13885 m_test_cases.push_back(test_case_out_one); 13886 } 13887 } 13888 } 13889 13890 /** Constructor 13891 * 13892 * @param context Test framework context 13893 **/ 13894 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context& context) 13895 : NegativeTestBase( 13896 context, "varying_block_automatic_member_locations", 13897 "Test verifies that compiler assigns subsequent locations to block members, even if this causes errors") 13898 { 13899 } 13900 13901 /** Source for given test case and stage 13902 * 13903 * @param test_case_index Index of test case 13904 * @param stage Shader stage 13905 * 13906 * @return Shader source 13907 **/ 13908 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint test_case_index, 13909 Utils::Shader::STAGES stage) 13910 { 13911 static const GLchar* block_definition = "layout (location = 2) DIRECTION DBZ {\n" 13912 " vec4 goku;\n" 13913 " vec4 gohan[4];\n" 13914 " vec4 goten;\n" 13915 " layout (location = 1) vec4 chichi;\n" 13916 " vec4 pan;\n" 13917 "} dbzARRAY;\n"; 13918 static const GLchar* input_use = " result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + " 13919 "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + " 13920 "dbzINDEX.pan;\n"; 13921 static const GLchar* output_use = " dbzINDEX.goku = result;\n" 13922 " dbzINDEX.gohan[0] = result / 2;\n" 13923 " dbzINDEX.gohan[1] = result / 2.25;\n" 13924 " dbzINDEX.gohan[2] = result / 2.5;\n" 13925 " dbzINDEX.gohan[3] = result / 2.75;\n" 13926 " dbzINDEX.goten = result / 4 - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - " 13927 "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n" 13928 " dbzINDEX.chichi = result / 8 - dbzINDEX.goten;\n" 13929 " dbzINDEX.pan = result / 16 - dbzINDEX.chichi;\n"; 13930 static const GLchar* fs = "#version 430 core\n" 13931 "#extension GL_ARB_enhanced_layouts : require\n" 13932 "\n" 13933 "in vec4 gs_fs;\n" 13934 "out vec4 fs_out;\n" 13935 "\n" 13936 "void main()\n" 13937 "{\n" 13938 " fs_out = gs_fs;\n" 13939 "}\n" 13940 "\n"; 13941 static const GLchar* fs_tested = "#version 430 core\n" 13942 "#extension GL_ARB_enhanced_layouts : require\n" 13943 "\n" 13944 "BLOCK_DEFINITION" 13945 "\n" 13946 "in vec4 gs_fs;\n" 13947 "out vec4 fs_out;\n" 13948 "\n" 13949 "void main()\n" 13950 "{\n" 13951 " vec4 result = gs_fs;\n" 13952 "\n" 13953 "VARIABLE_USE" 13954 "\n" 13955 " fs_out += result;\n" 13956 "}\n" 13957 "\n"; 13958 static const GLchar* gs = "#version 430 core\n" 13959 "#extension GL_ARB_enhanced_layouts : require\n" 13960 "\n" 13961 "layout(points) in;\n" 13962 "layout(triangle_strip, max_vertices = 4) out;\n" 13963 "\n" 13964 "in vec4 tes_gs[];\n" 13965 "out vec4 gs_fs;\n" 13966 "\n" 13967 "void main()\n" 13968 "{\n" 13969 " gs_fs = tes_gs[0];\n" 13970 " gl_Position = vec4(-1, -1, 0, 1);\n" 13971 " EmitVertex();\n" 13972 " gs_fs = tes_gs[0];\n" 13973 " gl_Position = vec4(-1, 1, 0, 1);\n" 13974 " EmitVertex();\n" 13975 " gs_fs = tes_gs[0];\n" 13976 " gl_Position = vec4(1, -1, 0, 1);\n" 13977 " EmitVertex();\n" 13978 " gs_fs = tes_gs[0];\n" 13979 " gl_Position = vec4(1, 1, 0, 1);\n" 13980 " EmitVertex();\n" 13981 "}\n" 13982 "\n"; 13983 static const GLchar* gs_tested = "#version 430 core\n" 13984 "#extension GL_ARB_enhanced_layouts : require\n" 13985 "\n" 13986 "layout(points) in;\n" 13987 "layout(triangle_strip, max_vertices = 4) out;\n" 13988 "\n" 13989 "BLOCK_DEFINITION" 13990 "\n" 13991 "in vec4 tes_gs[];\n" 13992 "out vec4 gs_fs;\n" 13993 "\n" 13994 "void main()\n" 13995 "{\n" 13996 " vec4 result = tes_gs[0];\n" 13997 "\n" 13998 "VARIABLE_USE" 13999 "\n" 14000 " gs_fs = result;\n" 14001 " gl_Position = vec4(-1, -1, 0, 1);\n" 14002 " EmitVertex();\n" 14003 " gs_fs = result;\n" 14004 " gl_Position = vec4(-1, 1, 0, 1);\n" 14005 " EmitVertex();\n" 14006 " gs_fs = result;\n" 14007 " gl_Position = vec4(1, -1, 0, 1);\n" 14008 " EmitVertex();\n" 14009 " gs_fs = result;\n" 14010 " gl_Position = vec4(1, 1, 0, 1);\n" 14011 " EmitVertex();\n" 14012 "}\n" 14013 "\n"; 14014 static const GLchar* tcs = "#version 430 core\n" 14015 "#extension GL_ARB_enhanced_layouts : require\n" 14016 "\n" 14017 "layout(vertices = 1) out;\n" 14018 "\n" 14019 "in vec4 vs_tcs[];\n" 14020 "out vec4 tcs_tes[];\n" 14021 "\n" 14022 "void main()\n" 14023 "{\n" 14024 "\n" 14025 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 14026 "\n" 14027 " gl_TessLevelOuter[0] = 1.0;\n" 14028 " gl_TessLevelOuter[1] = 1.0;\n" 14029 " gl_TessLevelOuter[2] = 1.0;\n" 14030 " gl_TessLevelOuter[3] = 1.0;\n" 14031 " gl_TessLevelInner[0] = 1.0;\n" 14032 " gl_TessLevelInner[1] = 1.0;\n" 14033 "}\n" 14034 "\n"; 14035 static const GLchar* tcs_tested = "#version 430 core\n" 14036 "#extension GL_ARB_enhanced_layouts : require\n" 14037 "\n" 14038 "layout(vertices = 1) out;\n" 14039 "\n" 14040 "BLOCK_DEFINITION" 14041 "\n" 14042 "in vec4 vs_tcs[];\n" 14043 "out vec4 tcs_tes[];\n" 14044 "\n" 14045 "void main()\n" 14046 "{\n" 14047 " vec4 result = vs_tcs[gl_InvocationID];\n" 14048 "\n" 14049 "VARIABLE_USE" 14050 "\n" 14051 " tcs_tes[gl_InvocationID] = result;\n" 14052 "\n" 14053 " gl_TessLevelOuter[0] = 1.0;\n" 14054 " gl_TessLevelOuter[1] = 1.0;\n" 14055 " gl_TessLevelOuter[2] = 1.0;\n" 14056 " gl_TessLevelOuter[3] = 1.0;\n" 14057 " gl_TessLevelInner[0] = 1.0;\n" 14058 " gl_TessLevelInner[1] = 1.0;\n" 14059 "}\n" 14060 "\n"; 14061 static const GLchar* tes = "#version 430 core\n" 14062 "#extension GL_ARB_enhanced_layouts : require\n" 14063 "\n" 14064 "layout(isolines, point_mode) in;\n" 14065 "\n" 14066 "in vec4 tcs_tes[];\n" 14067 "out vec4 tes_gs;\n" 14068 "\n" 14069 "void main()\n" 14070 "{\n" 14071 " tes_gs = tcs_tes[0];\n" 14072 "}\n" 14073 "\n"; 14074 static const GLchar* tes_tested = "#version 430 core\n" 14075 "#extension GL_ARB_enhanced_layouts : require\n" 14076 "\n" 14077 "layout(isolines, point_mode) in;\n" 14078 "\n" 14079 "BLOCK_DEFINITION" 14080 "\n" 14081 "in vec4 tcs_tes[];\n" 14082 "out vec4 tes_gs;\n" 14083 "\n" 14084 "void main()\n" 14085 "{\n" 14086 " vec4 result = tcs_tes[0];\n" 14087 "\n" 14088 "VARIABLE_USE" 14089 "\n" 14090 " tes_gs += result;\n" 14091 "}\n" 14092 "\n"; 14093 static const GLchar* vs = "#version 430 core\n" 14094 "#extension GL_ARB_enhanced_layouts : require\n" 14095 "\n" 14096 "in vec4 in_vs;\n" 14097 "out vec4 vs_tcs;\n" 14098 "\n" 14099 "void main()\n" 14100 "{\n" 14101 " vs_tcs = in_vs;\n" 14102 "}\n" 14103 "\n"; 14104 static const GLchar* vs_tested = "#version 430 core\n" 14105 "#extension GL_ARB_enhanced_layouts : require\n" 14106 "\n" 14107 "BLOCK_DEFINITION" 14108 "\n" 14109 "in vec4 in_vs;\n" 14110 "out vec4 vs_tcs;\n" 14111 "\n" 14112 "void main()\n" 14113 "{\n" 14114 " vec4 result = in_vs;\n" 14115 "\n" 14116 "VARIABLE_USE" 14117 "\n" 14118 " vs_tcs += result;\n" 14119 "}\n" 14120 "\n"; 14121 14122 const GLchar* array = ""; 14123 const GLchar* direction = "out"; 14124 const GLchar* index = ""; 14125 std::string source; 14126 testCase& test_case = m_test_cases[test_case_index]; 14127 const GLchar* var_use = output_use; 14128 14129 if (true == test_case.m_is_input) 14130 { 14131 direction = "in "; 14132 var_use = input_use; 14133 } 14134 14135 if (test_case.m_stage == stage) 14136 { 14137 size_t position = 0; 14138 size_t temp; 14139 14140 switch (stage) 14141 { 14142 case Utils::Shader::FRAGMENT: 14143 source = fs_tested; 14144 break; 14145 case Utils::Shader::GEOMETRY: 14146 source = gs_tested; 14147 array = "[]"; 14148 index = "[0]"; 14149 break; 14150 case Utils::Shader::TESS_CTRL: 14151 source = tcs_tested; 14152 array = "[]"; 14153 index = "[gl_InvocationID]"; 14154 break; 14155 case Utils::Shader::TESS_EVAL: 14156 source = tes_tested; 14157 array = "[]"; 14158 index = "[0]"; 14159 break; 14160 case Utils::Shader::VERTEX: 14161 source = vs_tested; 14162 break; 14163 default: 14164 TCU_FAIL("Invalid enum"); 14165 } 14166 14167 temp = position; 14168 Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source); 14169 position = temp; 14170 Utils::replaceToken("DIRECTION", position, direction, source); 14171 Utils::replaceToken("ARRAY", position, array, source); 14172 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 14173 14174 Utils::replaceAllTokens("INDEX", index, source); 14175 } 14176 else 14177 { 14178 switch (stage) 14179 { 14180 case Utils::Shader::FRAGMENT: 14181 source = fs; 14182 break; 14183 case Utils::Shader::GEOMETRY: 14184 source = gs; 14185 break; 14186 case Utils::Shader::TESS_CTRL: 14187 source = tcs; 14188 break; 14189 case Utils::Shader::TESS_EVAL: 14190 source = tes; 14191 break; 14192 case Utils::Shader::VERTEX: 14193 source = vs; 14194 break; 14195 default: 14196 TCU_FAIL("Invalid enum"); 14197 } 14198 } 14199 14200 return source; 14201 } 14202 14203 /** Get description of test case 14204 * 14205 * @param test_case_index Index of test case 14206 * 14207 * @return Test case description 14208 **/ 14209 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index) 14210 { 14211 std::stringstream stream; 14212 testCase& test_case = m_test_cases[test_case_index]; 14213 14214 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: "; 14215 14216 if (true == test_case.m_is_input) 14217 { 14218 stream << "input"; 14219 } 14220 else 14221 { 14222 stream << "output"; 14223 } 14224 14225 return stream.str(); 14226 } 14227 14228 /** Get number of test cases 14229 * 14230 * @return Number of test cases 14231 **/ 14232 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber() 14233 { 14234 return static_cast<GLuint>(m_test_cases.size()); 14235 } 14236 14237 /** Selects if "compute" stage is relevant for test 14238 * 14239 * @param ignored 14240 * 14241 * @return false 14242 **/ 14243 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */) 14244 { 14245 return false; 14246 } 14247 14248 /** Prepare all test cases 14249 * 14250 **/ 14251 void VaryingBlockAutomaticMemberLocationsTest::testInit() 14252 { 14253 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 14254 { 14255 if (Utils::Shader::COMPUTE == stage) 14256 { 14257 continue; 14258 } 14259 14260 testCase test_case_in = { true, (Utils::Shader::STAGES)stage }; 14261 testCase test_case_out = { false, (Utils::Shader::STAGES)stage }; 14262 14263 if (Utils::Shader::VERTEX != stage) 14264 { 14265 m_test_cases.push_back(test_case_in); 14266 } 14267 14268 if (Utils::Shader::FRAGMENT != stage) 14269 { 14270 m_test_cases.push_back(test_case_out); 14271 } 14272 } 14273 } 14274 14275 /** Constructor 14276 * 14277 * @param context Test framework context 14278 **/ 14279 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context& context) 14280 : NegativeTestBase(context, "varying_location_limit", 14281 "Test verifies that compiler reports error when location qualifier exceed limits") 14282 { 14283 } 14284 14285 /** Source for given test case and stage 14286 * 14287 * @param test_case_index Index of test case 14288 * @param stage Shader stage 14289 * 14290 * @return Shader source 14291 **/ 14292 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 14293 { 14294 static const GLchar* var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n"; 14295 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n" 14296 " {\n" 14297 " result += vec4(1, 0.5, 0.25, 0.125);\n" 14298 " }\n"; 14299 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n" 14300 " if (vec4(0) == result)\n" 14301 " {\n" 14302 " gokuINDEX = TYPE(1);\n" 14303 " }\n"; 14304 static const GLchar* fs = "#version 430 core\n" 14305 "#extension GL_ARB_enhanced_layouts : require\n" 14306 "\n" 14307 "in vec4 gs_fs;\n" 14308 "out vec4 fs_out;\n" 14309 "\n" 14310 "void main()\n" 14311 "{\n" 14312 " fs_out = gs_fs;\n" 14313 "}\n" 14314 "\n"; 14315 static const GLchar* fs_tested = "#version 430 core\n" 14316 "#extension GL_ARB_enhanced_layouts : require\n" 14317 "\n" 14318 "VAR_DEFINITION" 14319 "\n" 14320 "in vec4 gs_fs;\n" 14321 "out vec4 fs_out;\n" 14322 "\n" 14323 "void main()\n" 14324 "{\n" 14325 " vec4 result = gs_fs;\n" 14326 "\n" 14327 "VARIABLE_USE" 14328 "\n" 14329 " fs_out += result;\n" 14330 "}\n" 14331 "\n"; 14332 static const GLchar* gs = "#version 430 core\n" 14333 "#extension GL_ARB_enhanced_layouts : require\n" 14334 "\n" 14335 "layout(points) in;\n" 14336 "layout(triangle_strip, max_vertices = 4) out;\n" 14337 "\n" 14338 "in vec4 tes_gs[];\n" 14339 "out vec4 gs_fs;\n" 14340 "\n" 14341 "void main()\n" 14342 "{\n" 14343 " gs_fs = tes_gs[0];\n" 14344 " gl_Position = vec4(-1, -1, 0, 1);\n" 14345 " EmitVertex();\n" 14346 " gs_fs = tes_gs[0];\n" 14347 " gl_Position = vec4(-1, 1, 0, 1);\n" 14348 " EmitVertex();\n" 14349 " gs_fs = tes_gs[0];\n" 14350 " gl_Position = vec4(1, -1, 0, 1);\n" 14351 " EmitVertex();\n" 14352 " gs_fs = tes_gs[0];\n" 14353 " gl_Position = vec4(1, 1, 0, 1);\n" 14354 " EmitVertex();\n" 14355 "}\n" 14356 "\n"; 14357 static const GLchar* gs_tested = "#version 430 core\n" 14358 "#extension GL_ARB_enhanced_layouts : require\n" 14359 "\n" 14360 "layout(points) in;\n" 14361 "layout(triangle_strip, max_vertices = 4) out;\n" 14362 "\n" 14363 "VAR_DEFINITION" 14364 "\n" 14365 "in vec4 tes_gs[];\n" 14366 "out vec4 gs_fs;\n" 14367 "\n" 14368 "void main()\n" 14369 "{\n" 14370 " vec4 result = tes_gs[0];\n" 14371 "\n" 14372 "VARIABLE_USE" 14373 "\n" 14374 " gs_fs = result;\n" 14375 " gl_Position = vec4(-1, -1, 0, 1);\n" 14376 " EmitVertex();\n" 14377 " gs_fs = result;\n" 14378 " gl_Position = vec4(-1, 1, 0, 1);\n" 14379 " EmitVertex();\n" 14380 " gs_fs = result;\n" 14381 " gl_Position = vec4(1, -1, 0, 1);\n" 14382 " EmitVertex();\n" 14383 " gs_fs = result;\n" 14384 " gl_Position = vec4(1, 1, 0, 1);\n" 14385 " EmitVertex();\n" 14386 "}\n" 14387 "\n"; 14388 static const GLchar* tcs = "#version 430 core\n" 14389 "#extension GL_ARB_enhanced_layouts : require\n" 14390 "\n" 14391 "layout(vertices = 1) out;\n" 14392 "\n" 14393 "in vec4 vs_tcs[];\n" 14394 "out vec4 tcs_tes[];\n" 14395 "\n" 14396 "void main()\n" 14397 "{\n" 14398 "\n" 14399 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 14400 "\n" 14401 " gl_TessLevelOuter[0] = 1.0;\n" 14402 " gl_TessLevelOuter[1] = 1.0;\n" 14403 " gl_TessLevelOuter[2] = 1.0;\n" 14404 " gl_TessLevelOuter[3] = 1.0;\n" 14405 " gl_TessLevelInner[0] = 1.0;\n" 14406 " gl_TessLevelInner[1] = 1.0;\n" 14407 "}\n" 14408 "\n"; 14409 static const GLchar* tcs_tested = "#version 430 core\n" 14410 "#extension GL_ARB_enhanced_layouts : require\n" 14411 "\n" 14412 "layout(vertices = 1) out;\n" 14413 "\n" 14414 "VAR_DEFINITION" 14415 "\n" 14416 "in vec4 vs_tcs[];\n" 14417 "out vec4 tcs_tes[];\n" 14418 "\n" 14419 "void main()\n" 14420 "{\n" 14421 " vec4 result = vs_tcs[gl_InvocationID];\n" 14422 "\n" 14423 "VARIABLE_USE" 14424 "\n" 14425 " tcs_tes[gl_InvocationID] = result;\n" 14426 "\n" 14427 " gl_TessLevelOuter[0] = 1.0;\n" 14428 " gl_TessLevelOuter[1] = 1.0;\n" 14429 " gl_TessLevelOuter[2] = 1.0;\n" 14430 " gl_TessLevelOuter[3] = 1.0;\n" 14431 " gl_TessLevelInner[0] = 1.0;\n" 14432 " gl_TessLevelInner[1] = 1.0;\n" 14433 "}\n" 14434 "\n"; 14435 static const GLchar* tes = "#version 430 core\n" 14436 "#extension GL_ARB_enhanced_layouts : require\n" 14437 "\n" 14438 "layout(isolines, point_mode) in;\n" 14439 "\n" 14440 "in vec4 tcs_tes[];\n" 14441 "out vec4 tes_gs;\n" 14442 "\n" 14443 "void main()\n" 14444 "{\n" 14445 " tes_gs = tcs_tes[0];\n" 14446 "}\n" 14447 "\n"; 14448 static const GLchar* tes_tested = "#version 430 core\n" 14449 "#extension GL_ARB_enhanced_layouts : require\n" 14450 "\n" 14451 "layout(isolines, point_mode) in;\n" 14452 "\n" 14453 "VAR_DEFINITION" 14454 "\n" 14455 "in vec4 tcs_tes[];\n" 14456 "out vec4 tes_gs;\n" 14457 "\n" 14458 "void main()\n" 14459 "{\n" 14460 " vec4 result = tcs_tes[0];\n" 14461 "\n" 14462 "VARIABLE_USE" 14463 "\n" 14464 " tes_gs += result;\n" 14465 "}\n" 14466 "\n"; 14467 static const GLchar* vs = "#version 430 core\n" 14468 "#extension GL_ARB_enhanced_layouts : require\n" 14469 "\n" 14470 "in vec4 in_vs;\n" 14471 "out vec4 vs_tcs;\n" 14472 "\n" 14473 "void main()\n" 14474 "{\n" 14475 " vs_tcs = in_vs;\n" 14476 "}\n" 14477 "\n"; 14478 static const GLchar* vs_tested = "#version 430 core\n" 14479 "#extension GL_ARB_enhanced_layouts : require\n" 14480 "\n" 14481 "VAR_DEFINITION" 14482 "\n" 14483 "in vec4 in_vs;\n" 14484 "out vec4 vs_tcs;\n" 14485 "\n" 14486 "void main()\n" 14487 "{\n" 14488 " vec4 result = in_vs;\n" 14489 "\n" 14490 "VARIABLE_USE" 14491 "\n" 14492 " vs_tcs += result;\n" 14493 "}\n" 14494 "\n"; 14495 14496 std::string source; 14497 testCase& test_case = m_test_cases[test_case_index]; 14498 14499 if (test_case.m_stage == stage) 14500 { 14501 const GLchar* array = ""; 14502 GLchar buffer[16]; 14503 const GLchar* direction = "in "; 14504 const GLchar* flat = ""; 14505 const GLchar* index = ""; 14506 GLuint last = getLastInputLocation(stage, test_case.m_type, 0); 14507 size_t position = 0; 14508 size_t temp; 14509 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 14510 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT; 14511 const GLchar* var_use = input_use; 14512 14513 if (false == test_case.m_is_input) 14514 { 14515 direction = "out"; 14516 last = getLastOutputLocation(stage, test_case.m_type, 0); 14517 storage = Utils::Variable::VARYING_OUTPUT; 14518 var_use = output_use; 14519 } 14520 14521 if (true == isFlatRequired(stage, test_case.m_type, storage)) 14522 { 14523 flat = "flat"; 14524 } 14525 14526 sprintf(buffer, "%d", last); 14527 14528 switch (stage) 14529 { 14530 case Utils::Shader::FRAGMENT: 14531 source = fs_tested; 14532 break; 14533 case Utils::Shader::GEOMETRY: 14534 source = gs_tested; 14535 array = "[]"; 14536 index = "[0]"; 14537 break; 14538 case Utils::Shader::TESS_CTRL: 14539 source = tcs_tested; 14540 array = "[]"; 14541 index = "[gl_InvocationID]"; 14542 break; 14543 case Utils::Shader::TESS_EVAL: 14544 source = tes_tested; 14545 array = "[]"; 14546 index = "[0]"; 14547 break; 14548 case Utils::Shader::VERTEX: 14549 source = vs_tested; 14550 break; 14551 default: 14552 TCU_FAIL("Invalid enum"); 14553 } 14554 14555 temp = position; 14556 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 14557 position = temp; 14558 Utils::replaceToken("LAST", position, buffer, source); 14559 Utils::replaceToken("FLAT", position, flat, source); 14560 Utils::replaceToken("DIRECTION", position, direction, source); 14561 Utils::replaceToken("ARRAY", position, array, source); 14562 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 14563 14564 Utils::replaceAllTokens("TYPE", type_name, source); 14565 Utils::replaceAllTokens("INDEX", index, source); 14566 } 14567 else 14568 { 14569 switch (stage) 14570 { 14571 case Utils::Shader::FRAGMENT: 14572 source = fs; 14573 break; 14574 case Utils::Shader::GEOMETRY: 14575 source = gs; 14576 break; 14577 case Utils::Shader::TESS_CTRL: 14578 source = tcs; 14579 break; 14580 case Utils::Shader::TESS_EVAL: 14581 source = tes; 14582 break; 14583 case Utils::Shader::VERTEX: 14584 source = vs; 14585 break; 14586 default: 14587 TCU_FAIL("Invalid enum"); 14588 } 14589 } 14590 14591 return source; 14592 } 14593 14594 /** Get description of test case 14595 * 14596 * @param test_case_index Index of test case 14597 * 14598 * @return Test case description 14599 **/ 14600 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index) 14601 { 14602 std::stringstream stream; 14603 testCase& test_case = m_test_cases[test_case_index]; 14604 14605 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 14606 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: "; 14607 14608 if (true == test_case.m_is_input) 14609 { 14610 stream << "input"; 14611 } 14612 else 14613 { 14614 stream << "output"; 14615 } 14616 14617 return stream.str(); 14618 } 14619 14620 /** Get number of test cases 14621 * 14622 * @return Number of test cases 14623 **/ 14624 GLuint VaryingLocationLimitTest::getTestCaseNumber() 14625 { 14626 return static_cast<GLuint>(m_test_cases.size()); 14627 } 14628 14629 /** Selects if "compute" stage is relevant for test 14630 * 14631 * @param ignored 14632 * 14633 * @return false 14634 **/ 14635 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */) 14636 { 14637 return false; 14638 } 14639 14640 /** Prepare all test cases 14641 * 14642 **/ 14643 void VaryingLocationLimitTest::testInit() 14644 { 14645 const GLuint n_types = getTypesNumber(); 14646 14647 for (GLuint i = 0; i < n_types; ++i) 14648 { 14649 const Utils::Type& type = getType(i); 14650 14651 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 14652 { 14653 if (Utils::Shader::COMPUTE == stage) 14654 { 14655 continue; 14656 } 14657 14658 testCase test_case_in = { true, type, (Utils::Shader::STAGES)stage }; 14659 testCase test_case_out = { false, type, (Utils::Shader::STAGES)stage }; 14660 14661 m_test_cases.push_back(test_case_in); 14662 14663 if (Utils::Shader::FRAGMENT != stage) 14664 { 14665 m_test_cases.push_back(test_case_out); 14666 } 14667 } 14668 } 14669 } 14670 14671 /** Constructor 14672 * 14673 * @param context Test framework context 14674 **/ 14675 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context) 14676 : VaryingLocationsTest(context, "varying_components", 14677 "Test verifies that input and output components are respected") 14678 { 14679 } 14680 14681 /** Constructor 14682 * 14683 * @param context Test framework context 14684 * @param test_name Name of test 14685 * @param test_description Description of test 14686 **/ 14687 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context, const glw::GLchar* test_name, 14688 const glw::GLchar* test_description) 14689 : VaryingLocationsTest(context, test_name, test_description) 14690 { 14691 } 14692 14693 /** Get interface of program 14694 * 14695 * @param test_case_index Test case 14696 * @param program_interface Interface of program 14697 * @param varying_passthrough Collection of connections between in and out variables 14698 **/ 14699 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface, 14700 Utils::VaryingPassthrough& varying_passthrough) 14701 { 14702 GLuint array_length = getArrayLength(); 14703 const testCase& test_case = m_test_cases[test_case_index]; 14704 const Utils::Type vector_type = Utils::Type::GetType(test_case.m_type, 1, 4); 14705 Utils::ShaderInterface si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 14706 14707 /* Zero means no array, however we still need at least 1 slot of data */ 14708 if (0 == array_length) 14709 { 14710 array_length += 1; 14711 } 14712 14713 /* Generate data */ 14714 const std::vector<GLubyte>& data = vector_type.GenerateDataPacked(); 14715 const size_t data_size = data.size(); 14716 14717 /* Prepare data for variables */ 14718 m_data.resize(array_length * data_size); 14719 14720 GLubyte* dst = &m_data[0]; 14721 const GLubyte* src = &data[0]; 14722 14723 for (GLuint i = 0; i < array_length; ++i) 14724 { 14725 memcpy(dst + data_size * i, src, data_size); 14726 } 14727 14728 /* Prepare interface for each stage */ 14729 prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough); 14730 prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough); 14731 prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough); 14732 prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough); 14733 prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough); 14734 } 14735 14736 /** Get type name 14737 * 14738 * @param test_case_index Index of test case 14739 * 14740 * @return Name of type test in test_case_index 14741 **/ 14742 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index) 14743 { 14744 std::string name; 14745 14746 const testCase& test_case = m_test_cases[test_case_index]; 14747 14748 name = "Type: "; 14749 14750 switch (test_case.m_type) 14751 { 14752 case Utils::Type::Double: 14753 name.append(Utils::Type::_double.GetGLSLTypeName()); 14754 break; 14755 case Utils::Type::Float: 14756 name.append(Utils::Type::_float.GetGLSLTypeName()); 14757 break; 14758 case Utils::Type::Int: 14759 name.append(Utils::Type::_int.GetGLSLTypeName()); 14760 break; 14761 case Utils::Type::Uint: 14762 name.append(Utils::Type::uint.GetGLSLTypeName()); 14763 break; 14764 } 14765 14766 name.append(", layout: "); 14767 14768 switch (test_case.m_layout) 14769 { 14770 case GVEC4: 14771 name.append("GVEC4"); 14772 break; 14773 case SCALAR_GVEC3: 14774 name.append("SCALAR_GVEC3"); 14775 break; 14776 case GVEC3_SCALAR: 14777 name.append("GVEC3_SCALAR"); 14778 break; 14779 case GVEC2_GVEC2: 14780 name.append("GVEC2_GVEC2"); 14781 break; 14782 case GVEC2_SCALAR_SCALAR: 14783 name.append("GVEC2_SCALAR_SCALAR"); 14784 break; 14785 case SCALAR_GVEC2_SCALAR: 14786 name.append("SCALAR_GVEC2_SCALAR"); 14787 break; 14788 case SCALAR_SCALAR_GVEC2: 14789 name.append("SCALAR_SCALAR_GVEC2"); 14790 break; 14791 case SCALAR_SCALAR_SCALAR_SCALAR: 14792 name.append("SCALAR_SCALAR_SCALAR_SCALAR"); 14793 break; 14794 } 14795 14796 return name; 14797 } 14798 14799 /** Returns number of types to test 14800 * 14801 * @return Number of types, 34 14802 **/ 14803 glw::GLuint VaryingComponentsTest::getTestCaseNumber() 14804 { 14805 return static_cast<GLuint>(m_test_cases.size()); 14806 } 14807 14808 /* Prepare test cases */ 14809 void VaryingComponentsTest::testInit() 14810 { 14811 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Double)); 14812 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Double)); 14813 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Double)); 14814 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Double)); 14815 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Double)); 14816 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Double)); 14817 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Double)); 14818 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Double)); 14819 14820 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float)); 14821 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float)); 14822 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float)); 14823 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float)); 14824 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float)); 14825 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float)); 14826 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float)); 14827 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float)); 14828 14829 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int)); 14830 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int)); 14831 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int)); 14832 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int)); 14833 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int)); 14834 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int)); 14835 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int)); 14836 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int)); 14837 14838 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint)); 14839 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint)); 14840 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint)); 14841 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint)); 14842 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint)); 14843 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint)); 14844 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint)); 14845 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint)); 14846 } 14847 14848 /** Inform that test use components 14849 * 14850 * @param ignored 14851 * 14852 * @return true 14853 **/ 14854 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */) 14855 { 14856 return true; 14857 } 14858 14859 /** Get length of arrays that should be used during test 14860 * 14861 * @return 0u - no array at all 14862 **/ 14863 GLuint VaryingComponentsTest::getArrayLength() 14864 { 14865 return 0; 14866 } 14867 14868 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location) 14869 { 14870 std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location); 14871 14872 globals.append("const uint comp_x = 0u;\n" 14873 "const uint comp_y = 1u;\n" 14874 "const uint comp_z = 2u;\n" 14875 "const uint comp_w = 3u;\n"); 14876 14877 return globals; 14878 } 14879 14880 /** 14881 * 14882 **/ 14883 std::string VaryingComponentsTest::prepareName(const glw::GLchar* name, glw::GLint location, glw::GLint component, 14884 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage) 14885 { 14886 GLchar buffer[16]; 14887 std::string result = "PREFIXNAME_lLOCATION_cCOMPONENT"; 14888 size_t position = 0; 14889 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, storage); 14890 14891 Utils::replaceToken("PREFIX", position, prefix, result); 14892 Utils::replaceToken("NAME", position, name, result); 14893 14894 sprintf(buffer, "%d", location); 14895 Utils::replaceToken("LOCATION", position, buffer, result); 14896 14897 sprintf(buffer, "%d", component); 14898 Utils::replaceToken("COMPONENT", position, buffer, result); 14899 14900 return result; 14901 } 14902 14903 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar* location, const glw::GLchar* component, 14904 const glw::GLchar* interpolation) 14905 { 14906 size_t position = 0; 14907 std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION"; 14908 14909 Utils::replaceToken("LOCATION", position, location, qualifiers); 14910 Utils::replaceToken("COMPONENT", position, component, qualifiers); 14911 Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers); 14912 14913 return qualifiers; 14914 } 14915 14916 /** 14917 * 14918 **/ 14919 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& vector_type, 14920 Utils::ProgramInterface& program_interface, const testCase& test_case, 14921 Utils::VaryingPassthrough& varying_passthrough) 14922 { 14923 const GLuint array_length = getArrayLength(); 14924 const Utils::Type& basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */); 14925 descriptor desc_in[8]; 14926 descriptor desc_out[8]; 14927 const GLuint first_in_loc = 0; 14928 const GLuint first_out_loc = 0; 14929 const GLchar* interpolation = ""; 14930 const GLuint last_in_loc = getLastInputLocation(stage, vector_type, array_length); 14931 GLuint last_out_loc = 0; 14932 GLuint n_desc = 0; 14933 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage); 14934 14935 /* Select interpolation */ 14936 if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage)) 14937 { 14938 interpolation = " flat"; 14939 } 14940 14941 if (Utils::Shader::FRAGMENT != stage) 14942 { 14943 last_out_loc = getLastOutputLocation(stage, vector_type, array_length); 14944 } 14945 14946 switch (test_case.m_layout) 14947 { 14948 case GVEC4: 14949 n_desc = 2; 14950 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4"); 14951 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4"); 14952 14953 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4"); 14954 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4"); 14955 break; 14956 case SCALAR_GVEC3: 14957 n_desc = 4; 14958 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar"); 14959 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar"); 14960 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3"); 14961 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3"); 14962 14963 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar"); 14964 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar"); 14965 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3"); 14966 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3"); 14967 break; 14968 case GVEC3_SCALAR: 14969 n_desc = 4; 14970 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3"); 14971 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3"); 14972 desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar"); 14973 desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar"); 14974 14975 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3"); 14976 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3"); 14977 desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar"); 14978 desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar"); 14979 break; 14980 case GVEC2_GVEC2: 14981 n_desc = 4; 14982 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2"); 14983 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2"); 14984 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2"); 14985 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2"); 14986 14987 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2"); 14988 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2"); 14989 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2"); 14990 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2"); 14991 break; 14992 case GVEC2_SCALAR_SCALAR: 14993 n_desc = 6; 14994 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2"); 14995 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2"); 14996 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar"); 14997 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar"); 14998 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar"); 14999 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar"); 15000 15001 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2"); 15002 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2"); 15003 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar"); 15004 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar"); 15005 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar"); 15006 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar"); 15007 break; 15008 case SCALAR_GVEC2_SCALAR: 15009 n_desc = 6; 15010 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar"); 15011 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar"); 15012 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2"); 15013 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2"); 15014 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar"); 15015 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar"); 15016 15017 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar"); 15018 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar"); 15019 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2"); 15020 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2"); 15021 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar"); 15022 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar"); 15023 break; 15024 case SCALAR_SCALAR_GVEC2: 15025 n_desc = 6; 15026 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar"); 15027 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar"); 15028 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar"); 15029 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar"); 15030 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2"); 15031 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2"); 15032 15033 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar"); 15034 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar"); 15035 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar"); 15036 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar"); 15037 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2"); 15038 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2"); 15039 break; 15040 case SCALAR_SCALAR_SCALAR_SCALAR: 15041 n_desc = 8; 15042 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar"); 15043 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar"); 15044 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar"); 15045 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar"); 15046 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar"); 15047 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar"); 15048 desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar"); 15049 desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar"); 15050 15051 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar"); 15052 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar"); 15053 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar"); 15054 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar"); 15055 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar"); 15056 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar"); 15057 desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar"); 15058 desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar"); 15059 break; 15060 } 15061 15062 for (GLuint i = 0; i < n_desc; ++i) 15063 { 15064 const descriptor& in_desc = desc_in[i]; 15065 15066 Utils::Variable* in = 15067 prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT); 15068 15069 if (Utils::Shader::FRAGMENT != stage) 15070 { 15071 const descriptor& out_desc = desc_out[i]; 15072 15073 Utils::Variable* out = 15074 prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT); 15075 15076 varying_passthrough.Add(stage, in, out); 15077 } 15078 } 15079 15080 si.m_globals = prepareGlobals(last_in_loc, last_out_loc); 15081 } 15082 15083 /** 15084 * 15085 **/ 15086 Utils::Variable* VaryingComponentsTest::prepareVarying(const Utils::Type& basic_type, const descriptor& desc, 15087 const GLchar* interpolation, Utils::ShaderInterface& si, 15088 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage) 15089 { 15090 const GLuint array_length = getArrayLength(); 15091 const GLuint component_size = basic_type.GetSize(); 15092 const std::string& name = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage); 15093 const GLuint offset = desc.m_component * component_size; 15094 const std::string& qual = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation); 15095 const GLuint size = desc.m_n_rows * component_size; 15096 const Utils::Type& type = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows); 15097 Utils::Variable* var = 0; 15098 15099 if (Utils::Variable::VARYING_INPUT == storage) 15100 { 15101 var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */, 15102 desc.m_location /* expected_location */, type, /* built_in_type */ 15103 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */, 15104 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */); 15105 } 15106 else 15107 { 15108 var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */, 15109 desc.m_location /* expected_location */, type, /* built_in_type */ 15110 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */, 15111 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */); 15112 } 15113 15114 return var; 15115 } 15116 15117 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar* component_str, 15118 glw::GLint location, const glw::GLchar* location_str, glw::GLuint n_rows, 15119 const glw::GLchar* name) 15120 { 15121 m_component = component; 15122 m_component_str = component_str; 15123 m_location = location; 15124 m_location_str = location_str; 15125 m_n_rows = n_rows; 15126 m_name = name; 15127 } 15128 15129 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type) 15130 : m_layout(layout), m_type(type) 15131 { 15132 } 15133 15134 /** Constructor 15135 * 15136 * @param context Test framework context 15137 **/ 15138 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context& context) 15139 : VaryingComponentsTest(context, "varying_array_components", 15140 "Test verifies that input and output components are respected for arrays") 15141 { 15142 } 15143 15144 /** Get length of arrays that should be used during test 15145 * 15146 * @return 4u 15147 **/ 15148 GLuint VaryingArrayComponentsTest::getArrayLength() 15149 { 15150 return 4u; 15151 } 15152 15153 /** Constructor 15154 * 15155 * @param context Test framework context 15156 **/ 15157 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context& context) 15158 : NegativeTestBase(context, "varying_exceeding_components", 15159 "Test verifies that compiler reports error when component qualifier exceed limits") 15160 { 15161 } 15162 15163 /** Source for given test case and stage 15164 * 15165 * @param test_case_index Index of test case 15166 * @param stage Shader stage 15167 * 15168 * @return Shader source 15169 **/ 15170 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 15171 { 15172 static const GLchar* var_definition_arr = 15173 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n"; 15174 static const GLchar* var_definition_one = 15175 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n"; 15176 static const GLchar* input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n" 15177 " {\n" 15178 " result += vec4(1, 0.5, 0.25, 0.125);\n" 15179 " }\n"; 15180 static const GLchar* input_use_one = " if (TYPE(0) == gokuINDEX)\n" 15181 " {\n" 15182 " result += vec4(1, 0.5, 0.25, 0.125);\n" 15183 " }\n"; 15184 static const GLchar* output_use_arr = " gokuINDEX[0] = TYPE(0);\n" 15185 " if (vec4(0) == result)\n" 15186 " {\n" 15187 " gokuINDEX[0] = TYPE(1);\n" 15188 " }\n"; 15189 static const GLchar* output_use_one = " gokuINDEX = TYPE(0);\n" 15190 " if (vec4(0) == result)\n" 15191 " {\n" 15192 " gokuINDEX = TYPE(1);\n" 15193 " }\n"; 15194 static const GLchar* fs = "#version 430 core\n" 15195 "#extension GL_ARB_enhanced_layouts : require\n" 15196 "\n" 15197 "in vec4 gs_fs;\n" 15198 "out vec4 fs_out;\n" 15199 "\n" 15200 "void main()\n" 15201 "{\n" 15202 " fs_out = gs_fs;\n" 15203 "}\n" 15204 "\n"; 15205 static const GLchar* fs_tested = "#version 430 core\n" 15206 "#extension GL_ARB_enhanced_layouts : require\n" 15207 "\n" 15208 "VAR_DEFINITION" 15209 "\n" 15210 "in vec4 gs_fs;\n" 15211 "out vec4 fs_out;\n" 15212 "\n" 15213 "void main()\n" 15214 "{\n" 15215 " vec4 result = gs_fs;\n" 15216 "\n" 15217 "VARIABLE_USE" 15218 "\n" 15219 " fs_out += result;\n" 15220 "}\n" 15221 "\n"; 15222 static const GLchar* gs = "#version 430 core\n" 15223 "#extension GL_ARB_enhanced_layouts : require\n" 15224 "\n" 15225 "layout(points) in;\n" 15226 "layout(triangle_strip, max_vertices = 4) out;\n" 15227 "\n" 15228 "in vec4 tes_gs[];\n" 15229 "out vec4 gs_fs;\n" 15230 "\n" 15231 "void main()\n" 15232 "{\n" 15233 " gs_fs = tes_gs[0];\n" 15234 " gl_Position = vec4(-1, -1, 0, 1);\n" 15235 " EmitVertex();\n" 15236 " gs_fs = tes_gs[0];\n" 15237 " gl_Position = vec4(-1, 1, 0, 1);\n" 15238 " EmitVertex();\n" 15239 " gs_fs = tes_gs[0];\n" 15240 " gl_Position = vec4(1, -1, 0, 1);\n" 15241 " EmitVertex();\n" 15242 " gs_fs = tes_gs[0];\n" 15243 " gl_Position = vec4(1, 1, 0, 1);\n" 15244 " EmitVertex();\n" 15245 "}\n" 15246 "\n"; 15247 static const GLchar* gs_tested = "#version 430 core\n" 15248 "#extension GL_ARB_enhanced_layouts : require\n" 15249 "\n" 15250 "layout(points) in;\n" 15251 "layout(triangle_strip, max_vertices = 4) out;\n" 15252 "\n" 15253 "VAR_DEFINITION" 15254 "\n" 15255 "in vec4 tes_gs[];\n" 15256 "out vec4 gs_fs;\n" 15257 "\n" 15258 "void main()\n" 15259 "{\n" 15260 " vec4 result = tes_gs[0];\n" 15261 "\n" 15262 "VARIABLE_USE" 15263 "\n" 15264 " gs_fs = result;\n" 15265 " gl_Position = vec4(-1, -1, 0, 1);\n" 15266 " EmitVertex();\n" 15267 " gs_fs = result;\n" 15268 " gl_Position = vec4(-1, 1, 0, 1);\n" 15269 " EmitVertex();\n" 15270 " gs_fs = result;\n" 15271 " gl_Position = vec4(1, -1, 0, 1);\n" 15272 " EmitVertex();\n" 15273 " gs_fs = result;\n" 15274 " gl_Position = vec4(1, 1, 0, 1);\n" 15275 " EmitVertex();\n" 15276 "}\n" 15277 "\n"; 15278 static const GLchar* tcs = "#version 430 core\n" 15279 "#extension GL_ARB_enhanced_layouts : require\n" 15280 "\n" 15281 "layout(vertices = 1) out;\n" 15282 "\n" 15283 "in vec4 vs_tcs[];\n" 15284 "out vec4 tcs_tes[];\n" 15285 "\n" 15286 "void main()\n" 15287 "{\n" 15288 "\n" 15289 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 15290 "\n" 15291 " gl_TessLevelOuter[0] = 1.0;\n" 15292 " gl_TessLevelOuter[1] = 1.0;\n" 15293 " gl_TessLevelOuter[2] = 1.0;\n" 15294 " gl_TessLevelOuter[3] = 1.0;\n" 15295 " gl_TessLevelInner[0] = 1.0;\n" 15296 " gl_TessLevelInner[1] = 1.0;\n" 15297 "}\n" 15298 "\n"; 15299 static const GLchar* tcs_tested = "#version 430 core\n" 15300 "#extension GL_ARB_enhanced_layouts : require\n" 15301 "\n" 15302 "layout(vertices = 1) out;\n" 15303 "\n" 15304 "VAR_DEFINITION" 15305 "\n" 15306 "in vec4 vs_tcs[];\n" 15307 "out vec4 tcs_tes[];\n" 15308 "\n" 15309 "void main()\n" 15310 "{\n" 15311 " vec4 result = vs_tcs[gl_InvocationID];\n" 15312 "\n" 15313 "VARIABLE_USE" 15314 "\n" 15315 " tcs_tes[gl_InvocationID] = result;\n" 15316 "\n" 15317 " gl_TessLevelOuter[0] = 1.0;\n" 15318 " gl_TessLevelOuter[1] = 1.0;\n" 15319 " gl_TessLevelOuter[2] = 1.0;\n" 15320 " gl_TessLevelOuter[3] = 1.0;\n" 15321 " gl_TessLevelInner[0] = 1.0;\n" 15322 " gl_TessLevelInner[1] = 1.0;\n" 15323 "}\n" 15324 "\n"; 15325 static const GLchar* tes = "#version 430 core\n" 15326 "#extension GL_ARB_enhanced_layouts : require\n" 15327 "\n" 15328 "layout(isolines, point_mode) in;\n" 15329 "\n" 15330 "in vec4 tcs_tes[];\n" 15331 "out vec4 tes_gs;\n" 15332 "\n" 15333 "void main()\n" 15334 "{\n" 15335 " tes_gs = tcs_tes[0];\n" 15336 "}\n" 15337 "\n"; 15338 static const GLchar* tes_tested = "#version 430 core\n" 15339 "#extension GL_ARB_enhanced_layouts : require\n" 15340 "\n" 15341 "layout(isolines, point_mode) in;\n" 15342 "\n" 15343 "VAR_DEFINITION" 15344 "\n" 15345 "in vec4 tcs_tes[];\n" 15346 "out vec4 tes_gs;\n" 15347 "\n" 15348 "void main()\n" 15349 "{\n" 15350 " vec4 result = tcs_tes[0];\n" 15351 "\n" 15352 "VARIABLE_USE" 15353 "\n" 15354 " tes_gs += result;\n" 15355 "}\n" 15356 "\n"; 15357 static const GLchar* vs = "#version 430 core\n" 15358 "#extension GL_ARB_enhanced_layouts : require\n" 15359 "\n" 15360 "in vec4 in_vs;\n" 15361 "out vec4 vs_tcs;\n" 15362 "\n" 15363 "void main()\n" 15364 "{\n" 15365 " vs_tcs = in_vs;\n" 15366 "}\n" 15367 "\n"; 15368 static const GLchar* vs_tested = "#version 430 core\n" 15369 "#extension GL_ARB_enhanced_layouts : require\n" 15370 "\n" 15371 "VAR_DEFINITION" 15372 "\n" 15373 "in vec4 in_vs;\n" 15374 "out vec4 vs_tcs;\n" 15375 "\n" 15376 "void main()\n" 15377 "{\n" 15378 " vec4 result = in_vs;\n" 15379 "\n" 15380 "VARIABLE_USE" 15381 "\n" 15382 " vs_tcs += result;\n" 15383 "}\n" 15384 "\n"; 15385 15386 std::string source; 15387 testCase& test_case = m_test_cases[test_case_index]; 15388 15389 if (test_case.m_stage == stage) 15390 { 15391 const GLchar* array = ""; 15392 GLchar buffer[16]; 15393 const GLchar* var_definition = 0; 15394 const GLchar* direction = "in "; 15395 const GLchar* index = ""; 15396 size_t position = 0; 15397 size_t temp; 15398 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 15399 const GLchar* var_use = 0; 15400 15401 if (false == test_case.m_is_input) 15402 { 15403 direction = "out"; 15404 15405 if (false == test_case.m_is_array) 15406 { 15407 var_definition = var_definition_one; 15408 var_use = output_use_one; 15409 } 15410 else 15411 { 15412 var_definition = var_definition_arr; 15413 var_use = output_use_arr; 15414 } 15415 } 15416 else 15417 { 15418 if (false == test_case.m_is_array) 15419 { 15420 var_definition = var_definition_one; 15421 var_use = input_use_one; 15422 } 15423 else 15424 { 15425 var_definition = var_definition_arr; 15426 var_use = input_use_arr; 15427 } 15428 } 15429 15430 sprintf(buffer, "%d", test_case.m_component); 15431 15432 switch (stage) 15433 { 15434 case Utils::Shader::FRAGMENT: 15435 source = fs_tested; 15436 break; 15437 case Utils::Shader::GEOMETRY: 15438 source = gs_tested; 15439 array = "[]"; 15440 index = "[0]"; 15441 break; 15442 case Utils::Shader::TESS_CTRL: 15443 source = tcs_tested; 15444 array = "[]"; 15445 index = "[gl_InvocationID]"; 15446 break; 15447 case Utils::Shader::TESS_EVAL: 15448 source = tes_tested; 15449 array = "[]"; 15450 index = "[0]"; 15451 break; 15452 case Utils::Shader::VERTEX: 15453 source = vs_tested; 15454 break; 15455 default: 15456 TCU_FAIL("Invalid enum"); 15457 } 15458 15459 temp = position; 15460 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 15461 position = temp; 15462 Utils::replaceToken("COMPONENT", position, buffer, source); 15463 Utils::replaceToken("DIRECTION", position, direction, source); 15464 Utils::replaceToken("ARRAY", position, array, source); 15465 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 15466 15467 Utils::replaceAllTokens("TYPE", type_name, source); 15468 Utils::replaceAllTokens("INDEX", index, source); 15469 } 15470 else 15471 { 15472 switch (stage) 15473 { 15474 case Utils::Shader::FRAGMENT: 15475 source = fs; 15476 break; 15477 case Utils::Shader::GEOMETRY: 15478 source = gs; 15479 break; 15480 case Utils::Shader::TESS_CTRL: 15481 source = tcs; 15482 break; 15483 case Utils::Shader::TESS_EVAL: 15484 source = tes; 15485 break; 15486 case Utils::Shader::VERTEX: 15487 source = vs; 15488 break; 15489 default: 15490 TCU_FAIL("Invalid enum"); 15491 } 15492 } 15493 15494 return source; 15495 } 15496 15497 /** Get description of test case 15498 * 15499 * @param test_case_index Index of test case 15500 * 15501 * @return Test case description 15502 **/ 15503 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index) 15504 { 15505 std::stringstream stream; 15506 testCase& test_case = m_test_cases[test_case_index]; 15507 15508 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 15509 << " type: " << test_case.m_type.GetGLSLTypeName(); 15510 15511 if (true == test_case.m_is_array) 15512 { 15513 stream << "[1]"; 15514 } 15515 15516 stream << ", direction: "; 15517 15518 if (true == test_case.m_is_input) 15519 { 15520 stream << "input"; 15521 } 15522 else 15523 { 15524 stream << "output"; 15525 } 15526 15527 stream << ", component: " << test_case.m_component; 15528 15529 return stream.str(); 15530 } 15531 15532 /** Get number of test cases 15533 * 15534 * @return Number of test cases 15535 **/ 15536 GLuint VaryingExceedingComponentsTest::getTestCaseNumber() 15537 { 15538 return static_cast<GLuint>(m_test_cases.size()); 15539 } 15540 15541 /** Selects if "compute" stage is relevant for test 15542 * 15543 * @param ignored 15544 * 15545 * @return false 15546 **/ 15547 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */) 15548 { 15549 return false; 15550 } 15551 15552 /** Prepare all test cases 15553 * 15554 **/ 15555 void VaryingExceedingComponentsTest::testInit() 15556 { 15557 static const GLuint n_components_per_location = 4; 15558 const GLuint n_types = getTypesNumber(); 15559 15560 for (GLuint i = 0; i < n_types; ++i) 15561 { 15562 const Utils::Type& type = getType(i); 15563 const GLuint n_req_components = type.m_n_rows; 15564 const GLuint valid_component = n_components_per_location - n_req_components; 15565 const GLuint invalid_component = valid_component + 1; 15566 15567 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 15568 { 15569 if (Utils::Shader::COMPUTE == stage) 15570 { 15571 continue; 15572 } 15573 15574 /* Component cannot be used for matrices */ 15575 if (1 != type.m_n_columns) 15576 { 15577 continue; 15578 } 15579 15580 testCase test_case_in_arr = { invalid_component, true, true, (Utils::Shader::STAGES)stage, type }; 15581 testCase test_case_in_one = { invalid_component, true, false, (Utils::Shader::STAGES)stage, type }; 15582 testCase test_case_out_arr = { invalid_component, false, true, (Utils::Shader::STAGES)stage, type }; 15583 testCase test_case_out_one = { invalid_component, false, false, (Utils::Shader::STAGES)stage, type }; 15584 15585 m_test_cases.push_back(test_case_in_arr); 15586 m_test_cases.push_back(test_case_in_one); 15587 15588 if (Utils::Shader::FRAGMENT != stage) 15589 { 15590 m_test_cases.push_back(test_case_out_arr); 15591 m_test_cases.push_back(test_case_out_one); 15592 } 15593 } 15594 } 15595 } 15596 15597 /** Constructor 15598 * 15599 * @param context Test framework context 15600 **/ 15601 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context& context) 15602 : NegativeTestBase(context, "varying_component_without_location", 15603 "Test verifies that compiler reports error when component qualifier is used without location") 15604 { 15605 } 15606 15607 /** Source for given test case and stage 15608 * 15609 * @param test_case_index Index of test case 15610 * @param stage Shader stage 15611 * 15612 * @return Shader source 15613 **/ 15614 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 15615 { 15616 static const GLchar* var_definition = "layout (component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n"; 15617 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n" 15618 " {\n" 15619 " result += vec4(1, 0.5, 0.25, 0.125);\n" 15620 " }\n"; 15621 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n" 15622 " if (vec4(0) == result)\n" 15623 " {\n" 15624 " gokuINDEX = TYPE(1);\n" 15625 " }\n"; 15626 static const GLchar* fs = "#version 430 core\n" 15627 "#extension GL_ARB_enhanced_layouts : require\n" 15628 "\n" 15629 "in vec4 gs_fs;\n" 15630 "out vec4 fs_out;\n" 15631 "\n" 15632 "void main()\n" 15633 "{\n" 15634 " fs_out = gs_fs;\n" 15635 "}\n" 15636 "\n"; 15637 static const GLchar* fs_tested = "#version 430 core\n" 15638 "#extension GL_ARB_enhanced_layouts : require\n" 15639 "\n" 15640 "VAR_DEFINITION" 15641 "\n" 15642 "in vec4 gs_fs;\n" 15643 "out vec4 fs_out;\n" 15644 "\n" 15645 "void main()\n" 15646 "{\n" 15647 " vec4 result = gs_fs;\n" 15648 "\n" 15649 "VARIABLE_USE" 15650 "\n" 15651 " fs_out = result;\n" 15652 "}\n" 15653 "\n"; 15654 static const GLchar* gs = "#version 430 core\n" 15655 "#extension GL_ARB_enhanced_layouts : require\n" 15656 "\n" 15657 "layout(points) in;\n" 15658 "layout(triangle_strip, max_vertices = 4) out;\n" 15659 "\n" 15660 "in vec4 tes_gs[];\n" 15661 "out vec4 gs_fs;\n" 15662 "\n" 15663 "void main()\n" 15664 "{\n" 15665 " gs_fs = tes_gs[0];\n" 15666 " gl_Position = vec4(-1, -1, 0, 1);\n" 15667 " EmitVertex();\n" 15668 " gs_fs = tes_gs[0];\n" 15669 " gl_Position = vec4(-1, 1, 0, 1);\n" 15670 " EmitVertex();\n" 15671 " gs_fs = tes_gs[0];\n" 15672 " gl_Position = vec4(1, -1, 0, 1);\n" 15673 " EmitVertex();\n" 15674 " gs_fs = tes_gs[0];\n" 15675 " gl_Position = vec4(1, 1, 0, 1);\n" 15676 " EmitVertex();\n" 15677 "}\n" 15678 "\n"; 15679 static const GLchar* gs_tested = "#version 430 core\n" 15680 "#extension GL_ARB_enhanced_layouts : require\n" 15681 "\n" 15682 "layout(points) in;\n" 15683 "layout(triangle_strip, max_vertices = 4) out;\n" 15684 "\n" 15685 "VAR_DEFINITION" 15686 "\n" 15687 "in vec4 tes_gs[];\n" 15688 "out vec4 gs_fs;\n" 15689 "\n" 15690 "void main()\n" 15691 "{\n" 15692 " vec4 result = tes_gs[0];\n" 15693 "\n" 15694 "VARIABLE_USE" 15695 "\n" 15696 " gs_fs = result;\n" 15697 " gl_Position = vec4(-1, -1, 0, 1);\n" 15698 " EmitVertex();\n" 15699 " gs_fs = result;\n" 15700 " gl_Position = vec4(-1, 1, 0, 1);\n" 15701 " EmitVertex();\n" 15702 " gs_fs = result;\n" 15703 " gl_Position = vec4(1, -1, 0, 1);\n" 15704 " EmitVertex();\n" 15705 " gs_fs = result;\n" 15706 " gl_Position = vec4(1, 1, 0, 1);\n" 15707 " EmitVertex();\n" 15708 "}\n" 15709 "\n"; 15710 static const GLchar* tcs = "#version 430 core\n" 15711 "#extension GL_ARB_enhanced_layouts : require\n" 15712 "\n" 15713 "layout(vertices = 1) out;\n" 15714 "\n" 15715 "in vec4 vs_tcs[];\n" 15716 "out vec4 tcs_tes[];\n" 15717 "\n" 15718 "void main()\n" 15719 "{\n" 15720 "\n" 15721 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 15722 "\n" 15723 " gl_TessLevelOuter[0] = 1.0;\n" 15724 " gl_TessLevelOuter[1] = 1.0;\n" 15725 " gl_TessLevelOuter[2] = 1.0;\n" 15726 " gl_TessLevelOuter[3] = 1.0;\n" 15727 " gl_TessLevelInner[0] = 1.0;\n" 15728 " gl_TessLevelInner[1] = 1.0;\n" 15729 "}\n" 15730 "\n"; 15731 static const GLchar* tcs_tested = "#version 430 core\n" 15732 "#extension GL_ARB_enhanced_layouts : require\n" 15733 "\n" 15734 "layout(vertices = 1) out;\n" 15735 "\n" 15736 "VAR_DEFINITION" 15737 "\n" 15738 "in vec4 vs_tcs[];\n" 15739 "out vec4 tcs_tes[];\n" 15740 "\n" 15741 "void main()\n" 15742 "{\n" 15743 " vec4 result = vs_tcs[gl_InvocationID];\n" 15744 "\n" 15745 "VARIABLE_USE" 15746 "\n" 15747 " tcs_tes[gl_InvocationID] = result;\n" 15748 "\n" 15749 " gl_TessLevelOuter[0] = 1.0;\n" 15750 " gl_TessLevelOuter[1] = 1.0;\n" 15751 " gl_TessLevelOuter[2] = 1.0;\n" 15752 " gl_TessLevelOuter[3] = 1.0;\n" 15753 " gl_TessLevelInner[0] = 1.0;\n" 15754 " gl_TessLevelInner[1] = 1.0;\n" 15755 "}\n" 15756 "\n"; 15757 static const GLchar* tes = "#version 430 core\n" 15758 "#extension GL_ARB_enhanced_layouts : require\n" 15759 "\n" 15760 "layout(isolines, point_mode) in;\n" 15761 "\n" 15762 "in vec4 tcs_tes[];\n" 15763 "out vec4 tes_gs;\n" 15764 "\n" 15765 "void main()\n" 15766 "{\n" 15767 " tes_gs = tcs_tes[0];\n" 15768 "}\n" 15769 "\n"; 15770 static const GLchar* tes_tested = "#version 430 core\n" 15771 "#extension GL_ARB_enhanced_layouts : require\n" 15772 "\n" 15773 "layout(isolines, point_mode) in;\n" 15774 "\n" 15775 "VAR_DEFINITION" 15776 "\n" 15777 "in vec4 tcs_tes[];\n" 15778 "out vec4 tes_gs;\n" 15779 "\n" 15780 "void main()\n" 15781 "{\n" 15782 " vec4 result = tcs_tes[0];\n" 15783 "\n" 15784 "VARIABLE_USE" 15785 "\n" 15786 " tes_gs = result;\n" 15787 "}\n" 15788 "\n"; 15789 static const GLchar* vs = "#version 430 core\n" 15790 "#extension GL_ARB_enhanced_layouts : require\n" 15791 "\n" 15792 "in vec4 in_vs;\n" 15793 "out vec4 vs_tcs;\n" 15794 "\n" 15795 "void main()\n" 15796 "{\n" 15797 " vs_tcs = in_vs;\n" 15798 "}\n" 15799 "\n"; 15800 static const GLchar* vs_tested = "#version 430 core\n" 15801 "#extension GL_ARB_enhanced_layouts : require\n" 15802 "\n" 15803 "VAR_DEFINITION" 15804 "\n" 15805 "in vec4 in_vs;\n" 15806 "out vec4 vs_tcs;\n" 15807 "\n" 15808 "void main()\n" 15809 "{\n" 15810 " vec4 result = in_vs;\n" 15811 "\n" 15812 "VARIABLE_USE" 15813 "\n" 15814 " vs_tcs = result;\n" 15815 "}\n" 15816 "\n"; 15817 15818 std::string source; 15819 testCase& test_case = m_test_cases[test_case_index]; 15820 15821 if (test_case.m_stage == stage) 15822 { 15823 const GLchar* array = ""; 15824 GLchar buffer[16]; 15825 const GLchar* direction = "in "; 15826 const GLchar* index = ""; 15827 size_t position = 0; 15828 size_t temp; 15829 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 15830 const GLchar* var_use = input_use; 15831 const GLchar* flat = "flat"; 15832 15833 if (false == test_case.m_is_input) 15834 { 15835 direction = "out"; 15836 var_use = output_use; 15837 } 15838 15839 sprintf(buffer, "%d", test_case.m_component); 15840 15841 switch (stage) 15842 { 15843 case Utils::Shader::FRAGMENT: 15844 source = fs_tested; 15845 break; 15846 case Utils::Shader::GEOMETRY: 15847 source = gs_tested; 15848 array = "[]"; 15849 index = "[0]"; 15850 break; 15851 case Utils::Shader::TESS_CTRL: 15852 source = tcs_tested; 15853 array = "[]"; 15854 index = "[gl_InvocationID]"; 15855 break; 15856 case Utils::Shader::TESS_EVAL: 15857 source = tes_tested; 15858 array = "[]"; 15859 index = "[0]"; 15860 break; 15861 case Utils::Shader::VERTEX: 15862 source = vs_tested; 15863 flat = ""; 15864 break; 15865 default: 15866 TCU_FAIL("Invalid enum"); 15867 } 15868 15869 temp = position; 15870 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 15871 position = temp; 15872 Utils::replaceToken("COMPONENT", position, buffer, source); 15873 Utils::replaceToken("FLAT", position, flat, source); 15874 Utils::replaceToken("DIRECTION", position, direction, source); 15875 Utils::replaceToken("ARRAY", position, array, source); 15876 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 15877 15878 Utils::replaceAllTokens("TYPE", type_name, source); 15879 Utils::replaceAllTokens("INDEX", index, source); 15880 } 15881 else 15882 { 15883 switch (stage) 15884 { 15885 case Utils::Shader::FRAGMENT: 15886 source = fs; 15887 break; 15888 case Utils::Shader::GEOMETRY: 15889 source = gs; 15890 break; 15891 case Utils::Shader::TESS_CTRL: 15892 source = tcs; 15893 break; 15894 case Utils::Shader::TESS_EVAL: 15895 source = tes; 15896 break; 15897 case Utils::Shader::VERTEX: 15898 source = vs; 15899 break; 15900 default: 15901 TCU_FAIL("Invalid enum"); 15902 } 15903 } 15904 15905 return source; 15906 } 15907 15908 /** Get description of test case 15909 * 15910 * @param test_case_index Index of test case 15911 * 15912 * @return Test case description 15913 **/ 15914 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index) 15915 { 15916 std::stringstream stream; 15917 testCase& test_case = m_test_cases[test_case_index]; 15918 15919 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 15920 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: "; 15921 15922 if (true == test_case.m_is_input) 15923 { 15924 stream << "input"; 15925 } 15926 else 15927 { 15928 stream << "output"; 15929 } 15930 15931 stream << ", component: " << test_case.m_component; 15932 15933 return stream.str(); 15934 } 15935 15936 /** Get number of test cases 15937 * 15938 * @return Number of test cases 15939 **/ 15940 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber() 15941 { 15942 return static_cast<GLuint>(m_test_cases.size()); 15943 } 15944 15945 /** Selects if "compute" stage is relevant for test 15946 * 15947 * @param ignored 15948 * 15949 * @return false 15950 **/ 15951 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */) 15952 { 15953 return false; 15954 } 15955 15956 /** Prepare all test cases 15957 * 15958 **/ 15959 void VaryingComponentWithoutLocationTest::testInit() 15960 { 15961 static const GLuint n_components_per_location = 4; 15962 const GLuint n_types = getTypesNumber(); 15963 15964 for (GLuint i = 0; i < n_types; ++i) 15965 { 15966 const Utils::Type& type = getType(i); 15967 const GLuint n_req_components = type.m_n_rows; 15968 const GLuint valid_component = n_components_per_location - n_req_components; 15969 15970 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 15971 { 15972 if (Utils::Shader::COMPUTE == stage) 15973 { 15974 continue; 15975 } 15976 15977 /* Component cannot be used for matrices */ 15978 if (1 != type.m_n_columns) 15979 { 15980 continue; 15981 } 15982 15983 testCase test_case_in = { valid_component, true, (Utils::Shader::STAGES)stage, type }; 15984 testCase test_case_out = { valid_component, false, (Utils::Shader::STAGES)stage, type }; 15985 15986 m_test_cases.push_back(test_case_in); 15987 15988 if (Utils::Shader::FRAGMENT != stage) 15989 { 15990 m_test_cases.push_back(test_case_out); 15991 } 15992 } 15993 } 15994 } 15995 15996 /** Constructor 15997 * 15998 * @param context Test framework context 15999 **/ 16000 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context& context) 16001 : NegativeTestBase(context, "varying_component_of_invalid_type", 16002 "Test verifies that compiler reports error when component qualifier is used for invalid type") 16003 { 16004 } 16005 16006 /** Source for given test case and stage 16007 * 16008 * @param test_case_index Index of test case 16009 * @param stage Shader stage 16010 * 16011 * @return Shader source 16012 **/ 16013 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 16014 { 16015 static const GLchar* block_definition_arr = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n" 16016 " TYPE member;\n" 16017 "} gokuARRAY[1];\n"; 16018 static const GLchar* block_definition_one = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n" 16019 " TYPE member;\n" 16020 "} gokuARRAY;\n"; 16021 static const GLchar* matrix_definition_arr = 16022 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n"; 16023 static const GLchar* matrix_definition_one = 16024 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n"; 16025 static const GLchar* struct_definition_arr = 16026 "struct Goku {\n" 16027 " TYPE member;\n" 16028 "};\n" 16029 "\n" 16030 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY[1];\n"; 16031 static const GLchar* struct_definition_one = 16032 "struct Goku {\n" 16033 " TYPE member;\n" 16034 "};\n" 16035 "\n" 16036 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY;\n"; 16037 static const GLchar* matrix_input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n" 16038 " {\n" 16039 " result += vec4(1, 0.5, 0.25, 0.125);\n" 16040 " }\n"; 16041 static const GLchar* matrix_input_use_one = " if (TYPE(0) == gokuINDEX)\n" 16042 " {\n" 16043 " result += vec4(1, 0.5, 0.25, 0.125);\n" 16044 " }\n"; 16045 static const GLchar* matrix_output_use_arr = " gokuINDEX[0] = TYPE(0);\n" 16046 " if (vec4(0) == result)\n" 16047 " {\n" 16048 " gokuINDEX[0] = TYPE(1);\n" 16049 " }\n"; 16050 static const GLchar* matrix_output_use_one = " gokuINDEX = TYPE(0);\n" 16051 " if (vec4(0) == result)\n" 16052 " {\n" 16053 " gokuINDEX = TYPE(1);\n" 16054 " }\n"; 16055 static const GLchar* member_input_use_arr = " if (TYPE(0) == gokuINDEX[0].member)\n" 16056 " {\n" 16057 " result += vec4(1, 0.5, 0.25, 0.125);\n" 16058 " }\n"; 16059 static const GLchar* member_input_use_one = " if (TYPE(0) == gokuINDEX.member)\n" 16060 " {\n" 16061 " result += vec4(1, 0.5, 0.25, 0.125);\n" 16062 " }\n"; 16063 static const GLchar* member_output_use_arr = " gokuINDEX[0].member = TYPE(0);\n" 16064 " if (vec4(0) == result)\n" 16065 " {\n" 16066 " gokuINDEX[0].member = TYPE(1);\n" 16067 " }\n"; 16068 static const GLchar* member_output_use_one = " gokuINDEX.member = TYPE(0);\n" 16069 " if (vec4(0) == result)\n" 16070 " {\n" 16071 " gokuINDEX.member = TYPE(1);\n" 16072 " }\n"; 16073 static const GLchar* fs = "#version 430 core\n" 16074 "#extension GL_ARB_enhanced_layouts : require\n" 16075 "\n" 16076 "in vec4 gs_fs;\n" 16077 "out vec4 fs_out;\n" 16078 "\n" 16079 "void main()\n" 16080 "{\n" 16081 " fs_out = gs_fs;\n" 16082 "}\n" 16083 "\n"; 16084 static const GLchar* fs_tested = "#version 430 core\n" 16085 "#extension GL_ARB_enhanced_layouts : require\n" 16086 "\n" 16087 "VAR_DEFINITION" 16088 "\n" 16089 "in vec4 gs_fs;\n" 16090 "out vec4 fs_out;\n" 16091 "\n" 16092 "void main()\n" 16093 "{\n" 16094 " vec4 result = gs_fs;\n" 16095 "\n" 16096 "VARIABLE_USE" 16097 "\n" 16098 " fs_out += result;\n" 16099 "}\n" 16100 "\n"; 16101 static const GLchar* gs = "#version 430 core\n" 16102 "#extension GL_ARB_enhanced_layouts : require\n" 16103 "\n" 16104 "layout(points) in;\n" 16105 "layout(triangle_strip, max_vertices = 4) out;\n" 16106 "\n" 16107 "in vec4 tes_gs[];\n" 16108 "out vec4 gs_fs;\n" 16109 "\n" 16110 "void main()\n" 16111 "{\n" 16112 " gs_fs = tes_gs[0];\n" 16113 " gl_Position = vec4(-1, -1, 0, 1);\n" 16114 " EmitVertex();\n" 16115 " gs_fs = tes_gs[0];\n" 16116 " gl_Position = vec4(-1, 1, 0, 1);\n" 16117 " EmitVertex();\n" 16118 " gs_fs = tes_gs[0];\n" 16119 " gl_Position = vec4(1, -1, 0, 1);\n" 16120 " EmitVertex();\n" 16121 " gs_fs = tes_gs[0];\n" 16122 " gl_Position = vec4(1, 1, 0, 1);\n" 16123 " EmitVertex();\n" 16124 "}\n" 16125 "\n"; 16126 static const GLchar* gs_tested = "#version 430 core\n" 16127 "#extension GL_ARB_enhanced_layouts : require\n" 16128 "\n" 16129 "layout(points) in;\n" 16130 "layout(triangle_strip, max_vertices = 4) out;\n" 16131 "\n" 16132 "VAR_DEFINITION" 16133 "\n" 16134 "in vec4 tes_gs[];\n" 16135 "out vec4 gs_fs;\n" 16136 "\n" 16137 "void main()\n" 16138 "{\n" 16139 " vec4 result = tes_gs[0];\n" 16140 "\n" 16141 "VARIABLE_USE" 16142 "\n" 16143 " gs_fs = result;\n" 16144 " gl_Position = vec4(-1, -1, 0, 1);\n" 16145 " EmitVertex();\n" 16146 " gs_fs = result;\n" 16147 " gl_Position = vec4(-1, 1, 0, 1);\n" 16148 " EmitVertex();\n" 16149 " gs_fs = result;\n" 16150 " gl_Position = vec4(1, -1, 0, 1);\n" 16151 " EmitVertex();\n" 16152 " gs_fs = result;\n" 16153 " gl_Position = vec4(1, 1, 0, 1);\n" 16154 " EmitVertex();\n" 16155 "}\n" 16156 "\n"; 16157 static const GLchar* tcs = "#version 430 core\n" 16158 "#extension GL_ARB_enhanced_layouts : require\n" 16159 "\n" 16160 "layout(vertices = 1) out;\n" 16161 "\n" 16162 "in vec4 vs_tcs[];\n" 16163 "out vec4 tcs_tes[];\n" 16164 "\n" 16165 "void main()\n" 16166 "{\n" 16167 "\n" 16168 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 16169 "\n" 16170 " gl_TessLevelOuter[0] = 1.0;\n" 16171 " gl_TessLevelOuter[1] = 1.0;\n" 16172 " gl_TessLevelOuter[2] = 1.0;\n" 16173 " gl_TessLevelOuter[3] = 1.0;\n" 16174 " gl_TessLevelInner[0] = 1.0;\n" 16175 " gl_TessLevelInner[1] = 1.0;\n" 16176 "}\n" 16177 "\n"; 16178 static const GLchar* tcs_tested = "#version 430 core\n" 16179 "#extension GL_ARB_enhanced_layouts : require\n" 16180 "\n" 16181 "layout(vertices = 1) out;\n" 16182 "\n" 16183 "VAR_DEFINITION" 16184 "\n" 16185 "in vec4 vs_tcs[];\n" 16186 "out vec4 tcs_tes[];\n" 16187 "\n" 16188 "void main()\n" 16189 "{\n" 16190 " vec4 result = vs_tcs[gl_InvocationID];\n" 16191 "\n" 16192 "VARIABLE_USE" 16193 "\n" 16194 " tcs_tes[gl_InvocationID] = result;\n" 16195 "\n" 16196 " gl_TessLevelOuter[0] = 1.0;\n" 16197 " gl_TessLevelOuter[1] = 1.0;\n" 16198 " gl_TessLevelOuter[2] = 1.0;\n" 16199 " gl_TessLevelOuter[3] = 1.0;\n" 16200 " gl_TessLevelInner[0] = 1.0;\n" 16201 " gl_TessLevelInner[1] = 1.0;\n" 16202 "}\n" 16203 "\n"; 16204 static const GLchar* tes = "#version 430 core\n" 16205 "#extension GL_ARB_enhanced_layouts : require\n" 16206 "\n" 16207 "layout(isolines, point_mode) in;\n" 16208 "\n" 16209 "in vec4 tcs_tes[];\n" 16210 "out vec4 tes_gs;\n" 16211 "\n" 16212 "void main()\n" 16213 "{\n" 16214 " tes_gs = tcs_tes[0];\n" 16215 "}\n" 16216 "\n"; 16217 static const GLchar* tes_tested = "#version 430 core\n" 16218 "#extension GL_ARB_enhanced_layouts : require\n" 16219 "\n" 16220 "layout(isolines, point_mode) in;\n" 16221 "\n" 16222 "VAR_DEFINITION" 16223 "\n" 16224 "in vec4 tcs_tes[];\n" 16225 "out vec4 tes_gs;\n" 16226 "\n" 16227 "void main()\n" 16228 "{\n" 16229 " vec4 result = tcs_tes[0];\n" 16230 "\n" 16231 "VARIABLE_USE" 16232 "\n" 16233 " tes_gs += result;\n" 16234 "}\n" 16235 "\n"; 16236 static const GLchar* vs = "#version 430 core\n" 16237 "#extension GL_ARB_enhanced_layouts : require\n" 16238 "\n" 16239 "in vec4 in_vs;\n" 16240 "out vec4 vs_tcs;\n" 16241 "\n" 16242 "void main()\n" 16243 "{\n" 16244 " vs_tcs = in_vs;\n" 16245 "}\n" 16246 "\n"; 16247 static const GLchar* vs_tested = "#version 430 core\n" 16248 "#extension GL_ARB_enhanced_layouts : require\n" 16249 "\n" 16250 "VAR_DEFINITION" 16251 "\n" 16252 "in vec4 in_vs;\n" 16253 "out vec4 vs_tcs;\n" 16254 "\n" 16255 "void main()\n" 16256 "{\n" 16257 " vec4 result = in_vs;\n" 16258 "\n" 16259 "VARIABLE_USE" 16260 "\n" 16261 " vs_tcs += result;\n" 16262 "}\n" 16263 "\n"; 16264 16265 std::string source; 16266 testCase& test_case = m_test_cases[test_case_index]; 16267 16268 if (test_case.m_stage == stage) 16269 { 16270 const GLchar* array = ""; 16271 GLchar buffer[16]; 16272 const GLchar* var_definition = 0; 16273 const GLchar* direction = "in "; 16274 const GLchar* index = ""; 16275 size_t position = 0; 16276 size_t temp; 16277 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 16278 const GLchar* var_use = 0; 16279 16280 if (false == test_case.m_is_input) 16281 { 16282 direction = "out"; 16283 16284 if (false == test_case.m_is_array) 16285 { 16286 switch (test_case.m_case) 16287 { 16288 case BLOCK: 16289 var_definition = block_definition_one; 16290 var_use = member_output_use_one; 16291 break; 16292 case MATRIX: 16293 var_definition = matrix_definition_one; 16294 var_use = matrix_output_use_one; 16295 break; 16296 case STRUCT: 16297 var_definition = struct_definition_one; 16298 var_use = member_output_use_one; 16299 break; 16300 default: 16301 TCU_FAIL("Invalid enum"); 16302 } 16303 } 16304 else 16305 { 16306 switch (test_case.m_case) 16307 { 16308 case BLOCK: 16309 var_definition = block_definition_arr; 16310 var_use = member_output_use_arr; 16311 break; 16312 case MATRIX: 16313 var_definition = matrix_definition_arr; 16314 var_use = matrix_output_use_arr; 16315 break; 16316 case STRUCT: 16317 var_definition = struct_definition_arr; 16318 var_use = member_output_use_arr; 16319 break; 16320 default: 16321 TCU_FAIL("Invalid enum"); 16322 } 16323 } 16324 } 16325 else 16326 { 16327 if (false == test_case.m_is_array) 16328 { 16329 switch (test_case.m_case) 16330 { 16331 case BLOCK: 16332 var_definition = block_definition_one; 16333 var_use = member_input_use_one; 16334 break; 16335 case MATRIX: 16336 var_definition = matrix_definition_one; 16337 var_use = matrix_input_use_one; 16338 break; 16339 case STRUCT: 16340 var_definition = struct_definition_one; 16341 var_use = member_input_use_one; 16342 break; 16343 default: 16344 TCU_FAIL("Invalid enum"); 16345 } 16346 } 16347 else 16348 { 16349 switch (test_case.m_case) 16350 { 16351 case BLOCK: 16352 var_definition = block_definition_arr; 16353 var_use = member_input_use_arr; 16354 break; 16355 case MATRIX: 16356 var_definition = matrix_definition_arr; 16357 var_use = matrix_input_use_arr; 16358 break; 16359 case STRUCT: 16360 var_definition = struct_definition_arr; 16361 var_use = member_input_use_arr; 16362 break; 16363 default: 16364 TCU_FAIL("Invalid enum"); 16365 } 16366 } 16367 } 16368 16369 sprintf(buffer, "%d", test_case.m_component); 16370 16371 switch (stage) 16372 { 16373 case Utils::Shader::FRAGMENT: 16374 source = fs_tested; 16375 break; 16376 case Utils::Shader::GEOMETRY: 16377 source = gs_tested; 16378 array = "[]"; 16379 index = "[0]"; 16380 break; 16381 case Utils::Shader::TESS_CTRL: 16382 source = tcs_tested; 16383 array = "[]"; 16384 index = "[gl_InvocationID]"; 16385 break; 16386 case Utils::Shader::TESS_EVAL: 16387 source = tes_tested; 16388 array = "[]"; 16389 index = "[0]"; 16390 break; 16391 case Utils::Shader::VERTEX: 16392 source = vs_tested; 16393 break; 16394 default: 16395 TCU_FAIL("Invalid enum"); 16396 } 16397 16398 temp = position; 16399 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 16400 position = temp; 16401 Utils::replaceToken("COMPONENT", position, buffer, source); 16402 Utils::replaceToken("DIRECTION", position, direction, source); 16403 Utils::replaceToken("ARRAY", position, array, source); 16404 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 16405 16406 Utils::replaceAllTokens("TYPE", type_name, source); 16407 Utils::replaceAllTokens("INDEX", index, source); 16408 } 16409 else 16410 { 16411 switch (stage) 16412 { 16413 case Utils::Shader::FRAGMENT: 16414 source = fs; 16415 break; 16416 case Utils::Shader::GEOMETRY: 16417 source = gs; 16418 break; 16419 case Utils::Shader::TESS_CTRL: 16420 source = tcs; 16421 break; 16422 case Utils::Shader::TESS_EVAL: 16423 source = tes; 16424 break; 16425 case Utils::Shader::VERTEX: 16426 source = vs; 16427 break; 16428 default: 16429 TCU_FAIL("Invalid enum"); 16430 } 16431 } 16432 16433 return source; 16434 } 16435 16436 /** Get description of test case 16437 * 16438 * @param test_case_index Index of test case 16439 * 16440 * @return Test case description 16441 **/ 16442 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index) 16443 { 16444 std::stringstream stream; 16445 testCase& test_case = m_test_cases[test_case_index]; 16446 16447 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 16448 << " type: " << test_case.m_type.GetGLSLTypeName(); 16449 16450 if (true == test_case.m_is_array) 16451 { 16452 stream << "[1]"; 16453 } 16454 16455 stream << ", direction: "; 16456 16457 if (true == test_case.m_is_input) 16458 { 16459 stream << "input"; 16460 } 16461 else 16462 { 16463 stream << "output"; 16464 } 16465 16466 stream << ", component: " << test_case.m_component; 16467 16468 return stream.str(); 16469 } 16470 16471 /** Get number of test cases 16472 * 16473 * @return Number of test cases 16474 **/ 16475 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber() 16476 { 16477 return static_cast<GLuint>(m_test_cases.size()); 16478 } 16479 16480 /** Selects if "compute" stage is relevant for test 16481 * 16482 * @param ignored 16483 * 16484 * @return false 16485 **/ 16486 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */) 16487 { 16488 return false; 16489 } 16490 16491 /** Prepare all test cases 16492 * 16493 **/ 16494 void VaryingComponentOfInvalidTypeTest::testInit() 16495 { 16496 static const GLuint n_components_per_location = 4; 16497 const GLuint n_types = getTypesNumber(); 16498 16499 for (GLuint i = 0; i < n_types; ++i) 16500 { 16501 const Utils::Type& type = getType(i); 16502 const GLuint n_req_components = type.m_n_rows; 16503 const GLuint valid_component = n_components_per_location - n_req_components; 16504 16505 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 16506 { 16507 if (Utils::Shader::COMPUTE == stage) 16508 { 16509 continue; 16510 } 16511 16512 /* Use different CASE for matrices */ 16513 if (1 != type.m_n_columns) 16514 { 16515 testCase test_case_in_arr = { MATRIX, valid_component, true, true, (Utils::Shader::STAGES)stage, type }; 16516 testCase test_case_in_one = { 16517 MATRIX, valid_component, false, true, (Utils::Shader::STAGES)stage, type 16518 }; 16519 testCase test_case_out_arr = { 16520 MATRIX, valid_component, true, false, (Utils::Shader::STAGES)stage, type 16521 }; 16522 testCase test_case_out_one = { 16523 MATRIX, valid_component, false, false, (Utils::Shader::STAGES)stage, type 16524 }; 16525 16526 m_test_cases.push_back(test_case_in_arr); 16527 m_test_cases.push_back(test_case_in_one); 16528 16529 if (Utils::Shader::FRAGMENT != stage) 16530 { 16531 m_test_cases.push_back(test_case_out_arr); 16532 m_test_cases.push_back(test_case_out_one); 16533 } 16534 } 16535 else 16536 { 16537 for (GLuint c = BLOCK; c < MAX_CASES; ++c) 16538 { 16539 testCase test_case_in_arr = { (CASES)c, valid_component, true, true, (Utils::Shader::STAGES)stage, 16540 type }; 16541 testCase test_case_in_one = { (CASES)c, valid_component, false, true, (Utils::Shader::STAGES)stage, 16542 type }; 16543 testCase test_case_out_arr = { (CASES)c, valid_component, true, false, (Utils::Shader::STAGES)stage, 16544 type }; 16545 testCase test_case_out_one = { 16546 (CASES)c, valid_component, false, false, (Utils::Shader::STAGES)stage, type 16547 }; 16548 16549 if (Utils::Shader::VERTEX != stage) 16550 { 16551 m_test_cases.push_back(test_case_in_arr); 16552 m_test_cases.push_back(test_case_in_one); 16553 } 16554 16555 if (Utils::Shader::FRAGMENT != stage) 16556 { 16557 m_test_cases.push_back(test_case_out_arr); 16558 m_test_cases.push_back(test_case_out_one); 16559 } 16560 } 16561 } 16562 } 16563 } 16564 } 16565 16566 /** Constructor 16567 * 16568 * @param context Test framework context 16569 **/ 16570 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context& context) 16571 : NegativeTestBase(context, "input_component_aliasing", 16572 "Test verifies that compiler reports component aliasing as error") 16573 { 16574 } 16575 16576 /** Source for given test case and stage 16577 * 16578 * @param test_case_index Index of test case 16579 * @param stage Shader stage 16580 * 16581 * @return Shader source 16582 **/ 16583 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 16584 { 16585 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n" 16586 "layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n"; 16587 static const GLchar* test_one = " if (TYPE(0) == gohanINDEX)\n" 16588 " {\n" 16589 " result += vec4(1, 0.5, 0.25, 0.125);\n" 16590 " }\n"; 16591 static const GLchar* fs = "#version 430 core\n" 16592 "#extension GL_ARB_enhanced_layouts : require\n" 16593 "\n" 16594 "in vec4 gs_fs;\n" 16595 "out vec4 fs_out;\n" 16596 "\n" 16597 "void main()\n" 16598 "{\n" 16599 " fs_out = gs_fs;\n" 16600 "}\n" 16601 "\n"; 16602 static const GLchar* fs_tested = "#version 430 core\n" 16603 "#extension GL_ARB_enhanced_layouts : require\n" 16604 "\n" 16605 "VAR_DEFINITION" 16606 "\n" 16607 "in vec4 gs_fs;\n" 16608 "out vec4 fs_out;\n" 16609 "\n" 16610 "void main()\n" 16611 "{\n" 16612 " vec4 result = gs_fs;\n" 16613 "\n" 16614 "VARIABLE_USE" 16615 "\n" 16616 " fs_out += result;\n" 16617 "}\n" 16618 "\n"; 16619 static const GLchar* gs = "#version 430 core\n" 16620 "#extension GL_ARB_enhanced_layouts : require\n" 16621 "\n" 16622 "layout(points) in;\n" 16623 "layout(triangle_strip, max_vertices = 4) out;\n" 16624 "\n" 16625 "in vec4 tes_gs[];\n" 16626 "out vec4 gs_fs;\n" 16627 "\n" 16628 "void main()\n" 16629 "{\n" 16630 " gs_fs = tes_gs[0];\n" 16631 " gl_Position = vec4(-1, -1, 0, 1);\n" 16632 " EmitVertex();\n" 16633 " gs_fs = tes_gs[0];\n" 16634 " gl_Position = vec4(-1, 1, 0, 1);\n" 16635 " EmitVertex();\n" 16636 " gs_fs = tes_gs[0];\n" 16637 " gl_Position = vec4(1, -1, 0, 1);\n" 16638 " EmitVertex();\n" 16639 " gs_fs = tes_gs[0];\n" 16640 " gl_Position = vec4(1, 1, 0, 1);\n" 16641 " EmitVertex();\n" 16642 "}\n" 16643 "\n"; 16644 static const GLchar* gs_tested = "#version 430 core\n" 16645 "#extension GL_ARB_enhanced_layouts : require\n" 16646 "\n" 16647 "layout(points) in;\n" 16648 "layout(triangle_strip, max_vertices = 4) out;\n" 16649 "\n" 16650 "VAR_DEFINITION" 16651 "\n" 16652 "in vec4 tes_gs[];\n" 16653 "out vec4 gs_fs;\n" 16654 "\n" 16655 "void main()\n" 16656 "{\n" 16657 " vec4 result = tes_gs[0];\n" 16658 "\n" 16659 "VARIABLE_USE" 16660 "\n" 16661 " gs_fs = result;\n" 16662 " gl_Position = vec4(-1, -1, 0, 1);\n" 16663 " EmitVertex();\n" 16664 " gs_fs = result;\n" 16665 " gl_Position = vec4(-1, 1, 0, 1);\n" 16666 " EmitVertex();\n" 16667 " gs_fs = result;\n" 16668 " gl_Position = vec4(1, -1, 0, 1);\n" 16669 " EmitVertex();\n" 16670 " gs_fs = result;\n" 16671 " gl_Position = vec4(1, 1, 0, 1);\n" 16672 " EmitVertex();\n" 16673 "}\n" 16674 "\n"; 16675 static const GLchar* tcs = "#version 430 core\n" 16676 "#extension GL_ARB_enhanced_layouts : require\n" 16677 "\n" 16678 "layout(vertices = 1) out;\n" 16679 "\n" 16680 "in vec4 vs_tcs[];\n" 16681 "out vec4 tcs_tes[];\n" 16682 "\n" 16683 "void main()\n" 16684 "{\n" 16685 "\n" 16686 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 16687 "\n" 16688 " gl_TessLevelOuter[0] = 1.0;\n" 16689 " gl_TessLevelOuter[1] = 1.0;\n" 16690 " gl_TessLevelOuter[2] = 1.0;\n" 16691 " gl_TessLevelOuter[3] = 1.0;\n" 16692 " gl_TessLevelInner[0] = 1.0;\n" 16693 " gl_TessLevelInner[1] = 1.0;\n" 16694 "}\n" 16695 "\n"; 16696 static const GLchar* tcs_tested = "#version 430 core\n" 16697 "#extension GL_ARB_enhanced_layouts : require\n" 16698 "\n" 16699 "layout(vertices = 1) out;\n" 16700 "\n" 16701 "VAR_DEFINITION" 16702 "\n" 16703 "in vec4 vs_tcs[];\n" 16704 "out vec4 tcs_tes[];\n" 16705 "\n" 16706 "void main()\n" 16707 "{\n" 16708 " vec4 result = vs_tcs[gl_InvocationID];\n" 16709 "\n" 16710 "VARIABLE_USE" 16711 "\n" 16712 " tcs_tes[gl_InvocationID] = result;\n" 16713 "\n" 16714 " gl_TessLevelOuter[0] = 1.0;\n" 16715 " gl_TessLevelOuter[1] = 1.0;\n" 16716 " gl_TessLevelOuter[2] = 1.0;\n" 16717 " gl_TessLevelOuter[3] = 1.0;\n" 16718 " gl_TessLevelInner[0] = 1.0;\n" 16719 " gl_TessLevelInner[1] = 1.0;\n" 16720 "}\n" 16721 "\n"; 16722 static const GLchar* tes = "#version 430 core\n" 16723 "#extension GL_ARB_enhanced_layouts : require\n" 16724 "\n" 16725 "layout(isolines, point_mode) in;\n" 16726 "\n" 16727 "in vec4 tcs_tes[];\n" 16728 "out vec4 tes_gs;\n" 16729 "\n" 16730 "void main()\n" 16731 "{\n" 16732 " tes_gs = tcs_tes[0];\n" 16733 "}\n" 16734 "\n"; 16735 static const GLchar* tes_tested = "#version 430 core\n" 16736 "#extension GL_ARB_enhanced_layouts : require\n" 16737 "\n" 16738 "layout(isolines, point_mode) in;\n" 16739 "\n" 16740 "VAR_DEFINITION" 16741 "\n" 16742 "in vec4 tcs_tes[];\n" 16743 "out vec4 tes_gs;\n" 16744 "\n" 16745 "void main()\n" 16746 "{\n" 16747 " vec4 result = tcs_tes[0];\n" 16748 "\n" 16749 "VARIABLE_USE" 16750 "\n" 16751 " tes_gs += result;\n" 16752 "}\n" 16753 "\n"; 16754 static const GLchar* vs = "#version 430 core\n" 16755 "#extension GL_ARB_enhanced_layouts : require\n" 16756 "\n" 16757 "in vec4 in_vs;\n" 16758 "out vec4 vs_tcs;\n" 16759 "\n" 16760 "void main()\n" 16761 "{\n" 16762 " vs_tcs = in_vs;\n" 16763 "}\n" 16764 "\n"; 16765 static const GLchar* vs_tested = "#version 430 core\n" 16766 "#extension GL_ARB_enhanced_layouts : require\n" 16767 "\n" 16768 "VAR_DEFINITION" 16769 "\n" 16770 "in vec4 in_vs;\n" 16771 "out vec4 vs_tcs;\n" 16772 "\n" 16773 "void main()\n" 16774 "{\n" 16775 " vec4 result = in_vs;\n" 16776 "\n" 16777 "VARIABLE_USE" 16778 "\n" 16779 " vs_tcs += result;\n" 16780 "}\n" 16781 "\n"; 16782 16783 std::string source; 16784 testCase& test_case = m_test_cases[test_case_index]; 16785 16786 if (test_case.m_stage == stage) 16787 { 16788 const GLchar* array = ""; 16789 GLchar buffer_gohan[16]; 16790 GLchar buffer_goten[16]; 16791 const GLchar* flat = ""; 16792 const GLchar* index = ""; 16793 const bool is_flat_req = isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT); 16794 size_t position = 0; 16795 size_t temp; 16796 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 16797 const GLchar* var_use = test_one; 16798 16799 if (true == is_flat_req) 16800 { 16801 flat = "flat"; 16802 } 16803 16804 sprintf(buffer_gohan, "%d", test_case.m_component_gohan); 16805 sprintf(buffer_goten, "%d", test_case.m_component_goten); 16806 16807 switch (stage) 16808 { 16809 case Utils::Shader::FRAGMENT: 16810 source = fs_tested; 16811 break; 16812 case Utils::Shader::GEOMETRY: 16813 source = gs_tested; 16814 array = "[]"; 16815 index = "[0]"; 16816 break; 16817 case Utils::Shader::TESS_CTRL: 16818 source = tcs_tested; 16819 array = "[]"; 16820 index = "[gl_InvocationID]"; 16821 break; 16822 case Utils::Shader::TESS_EVAL: 16823 source = tes_tested; 16824 array = "[]"; 16825 index = "[0]"; 16826 break; 16827 case Utils::Shader::VERTEX: 16828 source = vs_tested; 16829 break; 16830 default: 16831 TCU_FAIL("Invalid enum"); 16832 } 16833 16834 temp = position; 16835 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 16836 position = temp; 16837 Utils::replaceToken("COMPONENT", position, buffer_gohan, source); 16838 Utils::replaceToken("ARRAY", position, array, source); 16839 Utils::replaceToken("COMPONENT", position, buffer_goten, source); 16840 Utils::replaceToken("ARRAY", position, array, source); 16841 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 16842 16843 Utils::replaceAllTokens("FLAT", flat, source); 16844 Utils::replaceAllTokens("TYPE", type_name, source); 16845 Utils::replaceAllTokens("INDEX", index, source); 16846 } 16847 else 16848 { 16849 switch (stage) 16850 { 16851 case Utils::Shader::FRAGMENT: 16852 source = fs; 16853 break; 16854 case Utils::Shader::GEOMETRY: 16855 source = gs; 16856 break; 16857 case Utils::Shader::TESS_CTRL: 16858 source = tcs; 16859 break; 16860 case Utils::Shader::TESS_EVAL: 16861 source = tes; 16862 break; 16863 case Utils::Shader::VERTEX: 16864 source = vs; 16865 break; 16866 default: 16867 TCU_FAIL("Invalid enum"); 16868 } 16869 } 16870 16871 return source; 16872 } 16873 16874 /** Get description of test case 16875 * 16876 * @param test_case_index Index of test case 16877 * 16878 * @return Test case description 16879 **/ 16880 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index) 16881 { 16882 std::stringstream stream; 16883 testCase& test_case = m_test_cases[test_case_index]; 16884 16885 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 16886 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan 16887 << " & " << test_case.m_component_goten; 16888 16889 return stream.str(); 16890 } 16891 16892 /** Get number of test cases 16893 * 16894 * @return Number of test cases 16895 **/ 16896 GLuint InputComponentAliasingTest::getTestCaseNumber() 16897 { 16898 return static_cast<GLuint>(m_test_cases.size()); 16899 } 16900 16901 /** Selects if "compute" stage is relevant for test 16902 * 16903 * @param ignored 16904 * 16905 * @return false 16906 **/ 16907 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */) 16908 { 16909 return false; 16910 } 16911 16912 /** Selects if compilation failure is expected result 16913 * 16914 * @param test_case_index Index of test case 16915 * 16916 * @return false for VS that use only single variable, true otherwise 16917 **/ 16918 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index) 16919 { 16920 testCase& test_case = m_test_cases[test_case_index]; 16921 16922 return (Utils::Shader::VERTEX != test_case.m_stage); 16923 } 16924 16925 /** Prepare all test cases 16926 * 16927 **/ 16928 void InputComponentAliasingTest::testInit() 16929 { 16930 const GLuint n_types = getTypesNumber(); 16931 16932 for (GLuint i = 0; i < n_types; ++i) 16933 { 16934 const Utils::Type& type = getType(i); 16935 const bool use_double = (Utils::Type::Double == type.m_basic_type); 16936 const GLuint n_components_per_location = use_double ? 2 : 4; 16937 const GLuint n_req_components = type.m_n_rows; 16938 const GLint valid_component = (GLint)n_components_per_location - (GLint)n_req_components; 16939 const GLuint component_size = use_double ? 2 : 1; 16940 /* Skip matrices */ 16941 if (1 != type.m_n_columns) 16942 { 16943 continue; 16944 } 16945 /* Skip dvec3/dvec4 which doesn't support the component qualifier */ 16946 if (valid_component < 0) 16947 { 16948 continue; 16949 } 16950 16951 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 16952 { 16953 if (Utils::Shader::COMPUTE == stage) 16954 { 16955 continue; 16956 } 16957 16958 for (GLuint gohan = 0; gohan <= (GLuint)valid_component; ++gohan) 16959 { 16960 const GLint first_aliasing = gohan - n_req_components + 1; 16961 const GLint last_aliasing = gohan + n_req_components - 1; 16962 16963 const GLuint goten_start = std::max(0, first_aliasing); 16964 const GLuint goten_stop = std::min(valid_component, last_aliasing); 16965 16966 for (GLuint goten = goten_start; goten <= goten_stop; ++goten) 16967 { 16968 testCase test_case = { gohan * component_size, goten * component_size, (Utils::Shader::STAGES)stage, 16969 type }; 16970 16971 m_test_cases.push_back(test_case); 16972 } 16973 } 16974 } 16975 } 16976 } 16977 16978 /** Constructor 16979 * 16980 * @param context Test framework context 16981 **/ 16982 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context& context) 16983 : NegativeTestBase(context, "output_component_aliasing", 16984 "Test verifies that compiler reports component aliasing as error") 16985 { 16986 } 16987 16988 /** Source for given test case and stage 16989 * 16990 * @param test_case_index Index of test case 16991 * @param stage Shader stage 16992 * 16993 * @return Shader source 16994 **/ 16995 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 16996 { 16997 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) flat out TYPE gohanARRAY;\n" 16998 "layout (location = 1, component = COMPONENT) flat out TYPE gotenARRAY;\n"; 16999 static const GLchar* l_test = " gohanINDEX = TYPE(1);\n" 17000 " gotenINDEX = TYPE(0);\n"; 17001 static const GLchar* fs = "#version 430 core\n" 17002 "#extension GL_ARB_enhanced_layouts : require\n" 17003 "\n" 17004 "in vec4 gs_fs;\n" 17005 "out vec4 fs_out;\n" 17006 "\n" 17007 "void main()\n" 17008 "{\n" 17009 " fs_out = gs_fs;\n" 17010 "}\n" 17011 "\n"; 17012 static const GLchar* fs_tested = "#version 430 core\n" 17013 "#extension GL_ARB_enhanced_layouts : require\n" 17014 "\n" 17015 "VAR_DEFINITION" 17016 "\n" 17017 "in vec4 gs_fs;\n" 17018 "out vec4 fs_out;\n" 17019 "\n" 17020 "void main()\n" 17021 "{\n" 17022 " vec4 result = gs_fs;\n" 17023 "\n" 17024 "VARIABLE_USE" 17025 "\n" 17026 " fs_out += result;\n" 17027 "}\n" 17028 "\n"; 17029 static const GLchar* gs = "#version 430 core\n" 17030 "#extension GL_ARB_enhanced_layouts : require\n" 17031 "\n" 17032 "layout(points) in;\n" 17033 "layout(triangle_strip, max_vertices = 4) out;\n" 17034 "\n" 17035 "in vec4 tes_gs[];\n" 17036 "out vec4 gs_fs;\n" 17037 "\n" 17038 "void main()\n" 17039 "{\n" 17040 " gs_fs = tes_gs[0];\n" 17041 " gl_Position = vec4(-1, -1, 0, 1);\n" 17042 " EmitVertex();\n" 17043 " gs_fs = tes_gs[0];\n" 17044 " gl_Position = vec4(-1, 1, 0, 1);\n" 17045 " EmitVertex();\n" 17046 " gs_fs = tes_gs[0];\n" 17047 " gl_Position = vec4(1, -1, 0, 1);\n" 17048 " EmitVertex();\n" 17049 " gs_fs = tes_gs[0];\n" 17050 " gl_Position = vec4(1, 1, 0, 1);\n" 17051 " EmitVertex();\n" 17052 "}\n" 17053 "\n"; 17054 static const GLchar* gs_tested = "#version 430 core\n" 17055 "#extension GL_ARB_enhanced_layouts : require\n" 17056 "\n" 17057 "layout(points) in;\n" 17058 "layout(triangle_strip, max_vertices = 4) out;\n" 17059 "\n" 17060 "VAR_DEFINITION" 17061 "\n" 17062 "in vec4 tes_gs[];\n" 17063 "out vec4 gs_fs;\n" 17064 "\n" 17065 "void main()\n" 17066 "{\n" 17067 " vec4 result = tes_gs[0];\n" 17068 "\n" 17069 "VARIABLE_USE" 17070 "\n" 17071 " gs_fs = result;\n" 17072 " gl_Position = vec4(-1, -1, 0, 1);\n" 17073 " EmitVertex();\n" 17074 " gs_fs = result;\n" 17075 " gl_Position = vec4(-1, 1, 0, 1);\n" 17076 " EmitVertex();\n" 17077 " gs_fs = result;\n" 17078 " gl_Position = vec4(1, -1, 0, 1);\n" 17079 " EmitVertex();\n" 17080 " gs_fs = result;\n" 17081 " gl_Position = vec4(1, 1, 0, 1);\n" 17082 " EmitVertex();\n" 17083 "}\n" 17084 "\n"; 17085 static const GLchar* tcs = "#version 430 core\n" 17086 "#extension GL_ARB_enhanced_layouts : require\n" 17087 "\n" 17088 "layout(vertices = 1) out;\n" 17089 "\n" 17090 "in vec4 vs_tcs[];\n" 17091 "out vec4 tcs_tes[];\n" 17092 "\n" 17093 "void main()\n" 17094 "{\n" 17095 "\n" 17096 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 17097 "\n" 17098 " gl_TessLevelOuter[0] = 1.0;\n" 17099 " gl_TessLevelOuter[1] = 1.0;\n" 17100 " gl_TessLevelOuter[2] = 1.0;\n" 17101 " gl_TessLevelOuter[3] = 1.0;\n" 17102 " gl_TessLevelInner[0] = 1.0;\n" 17103 " gl_TessLevelInner[1] = 1.0;\n" 17104 "}\n" 17105 "\n"; 17106 static const GLchar* tcs_tested = "#version 430 core\n" 17107 "#extension GL_ARB_enhanced_layouts : require\n" 17108 "\n" 17109 "layout(vertices = 1) out;\n" 17110 "\n" 17111 "VAR_DEFINITION" 17112 "\n" 17113 "in vec4 vs_tcs[];\n" 17114 "out vec4 tcs_tes[];\n" 17115 "\n" 17116 "void main()\n" 17117 "{\n" 17118 " vec4 result = vs_tcs[gl_InvocationID];\n" 17119 "\n" 17120 "VARIABLE_USE" 17121 "\n" 17122 " tcs_tes[gl_InvocationID] = result;\n" 17123 "\n" 17124 " gl_TessLevelOuter[0] = 1.0;\n" 17125 " gl_TessLevelOuter[1] = 1.0;\n" 17126 " gl_TessLevelOuter[2] = 1.0;\n" 17127 " gl_TessLevelOuter[3] = 1.0;\n" 17128 " gl_TessLevelInner[0] = 1.0;\n" 17129 " gl_TessLevelInner[1] = 1.0;\n" 17130 "}\n" 17131 "\n"; 17132 static const GLchar* tes = "#version 430 core\n" 17133 "#extension GL_ARB_enhanced_layouts : require\n" 17134 "\n" 17135 "layout(isolines, point_mode) in;\n" 17136 "\n" 17137 "in vec4 tcs_tes[];\n" 17138 "out vec4 tes_gs;\n" 17139 "\n" 17140 "void main()\n" 17141 "{\n" 17142 " tes_gs = tcs_tes[0];\n" 17143 "}\n" 17144 "\n"; 17145 static const GLchar* tes_tested = "#version 430 core\n" 17146 "#extension GL_ARB_enhanced_layouts : require\n" 17147 "\n" 17148 "layout(isolines, point_mode) in;\n" 17149 "\n" 17150 "VAR_DEFINITION" 17151 "\n" 17152 "in vec4 tcs_tes[];\n" 17153 "out vec4 tes_gs;\n" 17154 "\n" 17155 "void main()\n" 17156 "{\n" 17157 " vec4 result = tcs_tes[0];\n" 17158 "\n" 17159 "VARIABLE_USE" 17160 "\n" 17161 " tes_gs += result;\n" 17162 "}\n" 17163 "\n"; 17164 static const GLchar* vs = "#version 430 core\n" 17165 "#extension GL_ARB_enhanced_layouts : require\n" 17166 "\n" 17167 "in vec4 in_vs;\n" 17168 "out vec4 vs_tcs;\n" 17169 "\n" 17170 "void main()\n" 17171 "{\n" 17172 " vs_tcs = in_vs;\n" 17173 "}\n" 17174 "\n"; 17175 static const GLchar* vs_tested = "#version 430 core\n" 17176 "#extension GL_ARB_enhanced_layouts : require\n" 17177 "\n" 17178 "VAR_DEFINITION" 17179 "\n" 17180 "in vec4 in_vs;\n" 17181 "out vec4 vs_tcs;\n" 17182 "\n" 17183 "void main()\n" 17184 "{\n" 17185 " vec4 result = in_vs;\n" 17186 "\n" 17187 "VARIABLE_USE" 17188 "\n" 17189 " vs_tcs += result;\n" 17190 "}\n" 17191 "\n"; 17192 17193 std::string source; 17194 testCase& test_case = m_test_cases[test_case_index]; 17195 17196 if (test_case.m_stage == stage) 17197 { 17198 const GLchar* array = ""; 17199 GLchar buffer_gohan[16]; 17200 GLchar buffer_goten[16]; 17201 const GLchar* index = ""; 17202 size_t position = 0; 17203 size_t temp; 17204 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 17205 17206 sprintf(buffer_gohan, "%d", test_case.m_component_gohan); 17207 sprintf(buffer_goten, "%d", test_case.m_component_goten); 17208 17209 switch (stage) 17210 { 17211 case Utils::Shader::FRAGMENT: 17212 source = fs_tested; 17213 break; 17214 case Utils::Shader::GEOMETRY: 17215 source = gs_tested; 17216 array = "[]"; 17217 index = "[0]"; 17218 break; 17219 case Utils::Shader::TESS_CTRL: 17220 source = tcs_tested; 17221 array = "[]"; 17222 index = "[gl_InvocationID]"; 17223 break; 17224 case Utils::Shader::TESS_EVAL: 17225 source = tes_tested; 17226 array = "[]"; 17227 index = "[0]"; 17228 break; 17229 case Utils::Shader::VERTEX: 17230 source = vs_tested; 17231 break; 17232 default: 17233 TCU_FAIL("Invalid enum"); 17234 } 17235 17236 temp = position; 17237 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 17238 position = temp; 17239 Utils::replaceToken("COMPONENT", position, buffer_gohan, source); 17240 Utils::replaceToken("ARRAY", position, array, source); 17241 Utils::replaceToken("COMPONENT", position, buffer_goten, source); 17242 Utils::replaceToken("ARRAY", position, array, source); 17243 Utils::replaceToken("VARIABLE_USE", position, l_test, source); 17244 17245 Utils::replaceAllTokens("TYPE", type_name, source); 17246 Utils::replaceAllTokens("INDEX", index, source); 17247 } 17248 else 17249 { 17250 switch (stage) 17251 { 17252 case Utils::Shader::FRAGMENT: 17253 source = fs; 17254 break; 17255 case Utils::Shader::GEOMETRY: 17256 source = gs; 17257 break; 17258 case Utils::Shader::TESS_CTRL: 17259 source = tcs; 17260 break; 17261 case Utils::Shader::TESS_EVAL: 17262 source = tes; 17263 break; 17264 case Utils::Shader::VERTEX: 17265 source = vs; 17266 break; 17267 default: 17268 TCU_FAIL("Invalid enum"); 17269 } 17270 } 17271 17272 return source; 17273 } 17274 17275 /** Get description of test case 17276 * 17277 * @param test_case_index Index of test case 17278 * 17279 * @return Test case description 17280 **/ 17281 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index) 17282 { 17283 std::stringstream stream; 17284 testCase& test_case = m_test_cases[test_case_index]; 17285 17286 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 17287 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan 17288 << " & " << test_case.m_component_goten; 17289 17290 return stream.str(); 17291 } 17292 17293 /** Get number of test cases 17294 * 17295 * @return Number of test cases 17296 **/ 17297 GLuint OutputComponentAliasingTest::getTestCaseNumber() 17298 { 17299 return static_cast<GLuint>(m_test_cases.size()); 17300 } 17301 17302 /** Selects if "compute" stage is relevant for test 17303 * 17304 * @param ignored 17305 * 17306 * @return false 17307 **/ 17308 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */) 17309 { 17310 return false; 17311 } 17312 17313 /** Prepare all test cases 17314 * 17315 **/ 17316 void OutputComponentAliasingTest::testInit() 17317 { 17318 static const GLuint n_components_per_location = 4; 17319 const GLuint n_types = getTypesNumber(); 17320 17321 for (GLuint i = 0; i < n_types; ++i) 17322 { 17323 const Utils::Type& type = getType(i); 17324 const GLuint n_req_components = type.m_n_rows; 17325 const GLuint valid_component = n_components_per_location - n_req_components; 17326 17327 /* Skip matrices */ 17328 if (1 != type.m_n_columns) 17329 { 17330 continue; 17331 } 17332 17333 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 17334 { 17335 if (Utils::Shader::COMPUTE == stage) 17336 { 17337 continue; 17338 } 17339 17340 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type)) 17341 { 17342 continue; 17343 } 17344 17345 for (GLuint gohan = 0; gohan <= valid_component; ++gohan) 17346 { 17347 const GLint first_aliasing = gohan - n_req_components + 1; 17348 const GLint last_aliasing = gohan + n_req_components - 1; 17349 17350 const GLuint goten_start = std::max(0, first_aliasing); 17351 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing); 17352 17353 for (GLuint goten = goten_start; goten <= goten_stop; ++goten) 17354 { 17355 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type }; 17356 17357 m_test_cases.push_back(test_case); 17358 } 17359 } 17360 } 17361 } 17362 } 17363 17364 /** Constructor 17365 * 17366 * @param context Test framework context 17367 **/ 17368 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context& context) 17369 : NegativeTestBase(context, "varying_location_aliasing_with_mixed_types", 17370 "Test verifies that compiler reports error when float/int types are mixed at one location") 17371 { 17372 } 17373 17374 /** Source for given test case and stage 17375 * 17376 * @param test_case_index Index of test case 17377 * @param stage Shader stage 17378 * 17379 * @return Shader source 17380 **/ 17381 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint test_case_index, 17382 Utils::Shader::STAGES stage) 17383 { 17384 static const GLchar* var_definition = 17385 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n" 17386 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n"; 17387 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n" 17388 " (TYPE(1) == gotenINDEX) )\n" 17389 " {\n" 17390 " result += vec4(1, 0.5, 0.25, 0.125);\n" 17391 " }\n"; 17392 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n" 17393 " gotenINDEX = TYPE(1);\n" 17394 " if (vec4(0) == result)\n" 17395 " {\n" 17396 " gohanINDEX = TYPE(1);\n" 17397 " gotenINDEX = TYPE(0);\n" 17398 " }\n"; 17399 static const GLchar* fs = "#version 430 core\n" 17400 "#extension GL_ARB_enhanced_layouts : require\n" 17401 "\n" 17402 "in vec4 gs_fs;\n" 17403 "out vec4 fs_out;\n" 17404 "\n" 17405 "void main()\n" 17406 "{\n" 17407 " fs_out = gs_fs;\n" 17408 "}\n" 17409 "\n"; 17410 static const GLchar* fs_tested = "#version 430 core\n" 17411 "#extension GL_ARB_enhanced_layouts : require\n" 17412 "\n" 17413 "VAR_DEFINITION" 17414 "\n" 17415 "in vec4 gs_fs;\n" 17416 "out vec4 fs_out;\n" 17417 "\n" 17418 "void main()\n" 17419 "{\n" 17420 " vec4 result = gs_fs;\n" 17421 "\n" 17422 "VARIABLE_USE" 17423 "\n" 17424 " fs_out += result;\n" 17425 "}\n" 17426 "\n"; 17427 static const GLchar* gs = "#version 430 core\n" 17428 "#extension GL_ARB_enhanced_layouts : require\n" 17429 "\n" 17430 "layout(points) in;\n" 17431 "layout(triangle_strip, max_vertices = 4) out;\n" 17432 "\n" 17433 "in vec4 tes_gs[];\n" 17434 "out vec4 gs_fs;\n" 17435 "\n" 17436 "void main()\n" 17437 "{\n" 17438 " gs_fs = tes_gs[0];\n" 17439 " gl_Position = vec4(-1, -1, 0, 1);\n" 17440 " EmitVertex();\n" 17441 " gs_fs = tes_gs[0];\n" 17442 " gl_Position = vec4(-1, 1, 0, 1);\n" 17443 " EmitVertex();\n" 17444 " gs_fs = tes_gs[0];\n" 17445 " gl_Position = vec4(1, -1, 0, 1);\n" 17446 " EmitVertex();\n" 17447 " gs_fs = tes_gs[0];\n" 17448 " gl_Position = vec4(1, 1, 0, 1);\n" 17449 " EmitVertex();\n" 17450 "}\n" 17451 "\n"; 17452 static const GLchar* gs_tested = "#version 430 core\n" 17453 "#extension GL_ARB_enhanced_layouts : require\n" 17454 "\n" 17455 "layout(points) in;\n" 17456 "layout(triangle_strip, max_vertices = 4) out;\n" 17457 "\n" 17458 "VAR_DEFINITION" 17459 "\n" 17460 "in vec4 tes_gs[];\n" 17461 "out vec4 gs_fs;\n" 17462 "\n" 17463 "void main()\n" 17464 "{\n" 17465 " vec4 result = tes_gs[0];\n" 17466 "\n" 17467 "VARIABLE_USE" 17468 "\n" 17469 " gs_fs = result;\n" 17470 " gl_Position = vec4(-1, -1, 0, 1);\n" 17471 " EmitVertex();\n" 17472 " gs_fs = result;\n" 17473 " gl_Position = vec4(-1, 1, 0, 1);\n" 17474 " EmitVertex();\n" 17475 " gs_fs = result;\n" 17476 " gl_Position = vec4(1, -1, 0, 1);\n" 17477 " EmitVertex();\n" 17478 " gs_fs = result;\n" 17479 " gl_Position = vec4(1, 1, 0, 1);\n" 17480 " EmitVertex();\n" 17481 "}\n" 17482 "\n"; 17483 static const GLchar* tcs = "#version 430 core\n" 17484 "#extension GL_ARB_enhanced_layouts : require\n" 17485 "\n" 17486 "layout(vertices = 1) out;\n" 17487 "\n" 17488 "in vec4 vs_tcs[];\n" 17489 "out vec4 tcs_tes[];\n" 17490 "\n" 17491 "void main()\n" 17492 "{\n" 17493 "\n" 17494 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 17495 "\n" 17496 " gl_TessLevelOuter[0] = 1.0;\n" 17497 " gl_TessLevelOuter[1] = 1.0;\n" 17498 " gl_TessLevelOuter[2] = 1.0;\n" 17499 " gl_TessLevelOuter[3] = 1.0;\n" 17500 " gl_TessLevelInner[0] = 1.0;\n" 17501 " gl_TessLevelInner[1] = 1.0;\n" 17502 "}\n" 17503 "\n"; 17504 static const GLchar* tcs_tested = "#version 430 core\n" 17505 "#extension GL_ARB_enhanced_layouts : require\n" 17506 "\n" 17507 "layout(vertices = 1) out;\n" 17508 "\n" 17509 "VAR_DEFINITION" 17510 "\n" 17511 "in vec4 vs_tcs[];\n" 17512 "out vec4 tcs_tes[];\n" 17513 "\n" 17514 "void main()\n" 17515 "{\n" 17516 " vec4 result = vs_tcs[gl_InvocationID];\n" 17517 "\n" 17518 "VARIABLE_USE" 17519 "\n" 17520 " tcs_tes[gl_InvocationID] = result;\n" 17521 "\n" 17522 " gl_TessLevelOuter[0] = 1.0;\n" 17523 " gl_TessLevelOuter[1] = 1.0;\n" 17524 " gl_TessLevelOuter[2] = 1.0;\n" 17525 " gl_TessLevelOuter[3] = 1.0;\n" 17526 " gl_TessLevelInner[0] = 1.0;\n" 17527 " gl_TessLevelInner[1] = 1.0;\n" 17528 "}\n" 17529 "\n"; 17530 static const GLchar* tes = "#version 430 core\n" 17531 "#extension GL_ARB_enhanced_layouts : require\n" 17532 "\n" 17533 "layout(isolines, point_mode) in;\n" 17534 "\n" 17535 "in vec4 tcs_tes[];\n" 17536 "out vec4 tes_gs;\n" 17537 "\n" 17538 "void main()\n" 17539 "{\n" 17540 " tes_gs = tcs_tes[0];\n" 17541 "}\n" 17542 "\n"; 17543 static const GLchar* tes_tested = "#version 430 core\n" 17544 "#extension GL_ARB_enhanced_layouts : require\n" 17545 "\n" 17546 "layout(isolines, point_mode) in;\n" 17547 "\n" 17548 "VAR_DEFINITION" 17549 "\n" 17550 "in vec4 tcs_tes[];\n" 17551 "out vec4 tes_gs;\n" 17552 "\n" 17553 "void main()\n" 17554 "{\n" 17555 " vec4 result = tcs_tes[0];\n" 17556 "\n" 17557 "VARIABLE_USE" 17558 "\n" 17559 " tes_gs += result;\n" 17560 "}\n" 17561 "\n"; 17562 static const GLchar* vs = "#version 430 core\n" 17563 "#extension GL_ARB_enhanced_layouts : require\n" 17564 "\n" 17565 "in vec4 in_vs;\n" 17566 "out vec4 vs_tcs;\n" 17567 "\n" 17568 "void main()\n" 17569 "{\n" 17570 " vs_tcs = in_vs;\n" 17571 "}\n" 17572 "\n"; 17573 static const GLchar* vs_tested = "#version 430 core\n" 17574 "#extension GL_ARB_enhanced_layouts : require\n" 17575 "\n" 17576 "VAR_DEFINITION" 17577 "\n" 17578 "in vec4 in_vs;\n" 17579 "out vec4 vs_tcs;\n" 17580 "\n" 17581 "void main()\n" 17582 "{\n" 17583 " vec4 result = in_vs;\n" 17584 "\n" 17585 "VARIABLE_USE" 17586 "\n" 17587 " vs_tcs += result;\n" 17588 "}\n" 17589 "\n"; 17590 17591 std::string source; 17592 testCase& test_case = m_test_cases[test_case_index]; 17593 17594 if (test_case.m_stage == stage) 17595 { 17596 const GLchar* array = ""; 17597 GLchar buffer_gohan[16]; 17598 GLchar buffer_goten[16]; 17599 const GLchar* direction = "in "; 17600 const GLchar* flat_gohan = ""; 17601 const GLchar* flat_goten = ""; 17602 const GLchar* index = ""; 17603 size_t position = 0; 17604 size_t temp; 17605 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName(); 17606 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName(); 17607 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT; 17608 const GLchar* var_use = input_use; 17609 17610 if (false == test_case.m_is_input) 17611 { 17612 direction = "out"; 17613 storage = Utils::Variable::VARYING_OUTPUT; 17614 var_use = output_use; 17615 } 17616 17617 if (true == isFlatRequired(stage, test_case.m_type_gohan, storage)) 17618 { 17619 flat_gohan = "flat"; 17620 } 17621 17622 if (true == isFlatRequired(stage, test_case.m_type_goten, storage)) 17623 { 17624 flat_goten = "flat"; 17625 } 17626 17627 sprintf(buffer_gohan, "%d", test_case.m_component_gohan); 17628 sprintf(buffer_goten, "%d", test_case.m_component_goten); 17629 17630 switch (stage) 17631 { 17632 case Utils::Shader::FRAGMENT: 17633 source = fs_tested; 17634 break; 17635 case Utils::Shader::GEOMETRY: 17636 source = gs_tested; 17637 array = "[]"; 17638 index = "[0]"; 17639 break; 17640 case Utils::Shader::TESS_CTRL: 17641 source = tcs_tested; 17642 array = "[]"; 17643 index = "[gl_InvocationID]"; 17644 break; 17645 case Utils::Shader::TESS_EVAL: 17646 source = tes_tested; 17647 array = "[]"; 17648 index = "[0]"; 17649 break; 17650 case Utils::Shader::VERTEX: 17651 source = vs_tested; 17652 break; 17653 default: 17654 TCU_FAIL("Invalid enum"); 17655 } 17656 17657 temp = position; 17658 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 17659 position = temp; 17660 Utils::replaceToken("COMPONENT", position, buffer_gohan, source); 17661 Utils::replaceToken("FLAT", position, flat_gohan, source); 17662 Utils::replaceToken("DIRECTION", position, direction, source); 17663 Utils::replaceToken("TYPE", position, type_gohan_name, source); 17664 Utils::replaceToken("ARRAY", position, array, source); 17665 Utils::replaceToken("COMPONENT", position, buffer_goten, source); 17666 Utils::replaceToken("FLAT", position, flat_goten, source); 17667 Utils::replaceToken("DIRECTION", position, direction, source); 17668 Utils::replaceToken("TYPE", position, type_goten_name, source); 17669 Utils::replaceToken("ARRAY", position, array, source); 17670 17671 temp = position; 17672 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 17673 position = temp; 17674 if (true == test_case.m_is_input) 17675 { 17676 Utils::replaceToken("TYPE", position, type_gohan_name, source); 17677 Utils::replaceToken("TYPE", position, type_goten_name, source); 17678 } 17679 else 17680 { 17681 Utils::replaceToken("TYPE", position, type_gohan_name, source); 17682 Utils::replaceToken("TYPE", position, type_goten_name, source); 17683 Utils::replaceToken("TYPE", position, type_gohan_name, source); 17684 Utils::replaceToken("TYPE", position, type_goten_name, source); 17685 } 17686 17687 Utils::replaceAllTokens("INDEX", index, source); 17688 } 17689 else 17690 { 17691 switch (stage) 17692 { 17693 case Utils::Shader::FRAGMENT: 17694 source = fs; 17695 break; 17696 case Utils::Shader::GEOMETRY: 17697 source = gs; 17698 break; 17699 case Utils::Shader::TESS_CTRL: 17700 source = tcs; 17701 break; 17702 case Utils::Shader::TESS_EVAL: 17703 source = tes; 17704 break; 17705 case Utils::Shader::VERTEX: 17706 source = vs; 17707 break; 17708 default: 17709 TCU_FAIL("Invalid enum"); 17710 } 17711 } 17712 17713 return source; 17714 } 17715 17716 /** Get description of test case 17717 * 17718 * @param test_case_index Index of test case 17719 * 17720 * @return Test case description 17721 **/ 17722 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index) 17723 { 17724 std::stringstream stream; 17725 testCase& test_case = m_test_cases[test_case_index]; 17726 17727 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", " 17728 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", " 17729 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: "; 17730 17731 if (true == test_case.m_is_input) 17732 { 17733 stream << "input"; 17734 } 17735 else 17736 { 17737 stream << "output"; 17738 } 17739 17740 return stream.str(); 17741 } 17742 17743 /** Get number of test cases 17744 * 17745 * @return Number of test cases 17746 **/ 17747 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber() 17748 { 17749 return static_cast<GLuint>(m_test_cases.size()); 17750 } 17751 17752 /** Selects if "compute" stage is relevant for test 17753 * 17754 * @param ignored 17755 * 17756 * @return false 17757 **/ 17758 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */) 17759 { 17760 return false; 17761 } 17762 17763 /** Prepare all test cases 17764 * 17765 **/ 17766 void VaryingLocationAliasingWithMixedTypesTest::testInit() 17767 { 17768 static const GLuint n_components_per_location = 4; 17769 const GLuint n_types = getTypesNumber(); 17770 17771 for (GLuint i = 0; i < n_types; ++i) 17772 { 17773 const Utils::Type& type_gohan = getType(i); 17774 const bool is_float_type_gohan = isFloatType(type_gohan); 17775 17776 /* Skip matrices */ 17777 if (1 != type_gohan.m_n_columns) 17778 { 17779 continue; 17780 } 17781 17782 for (GLuint j = 0; j < n_types; ++j) 17783 { 17784 const Utils::Type& type_goten = getType(j); 17785 const bool is_float_type_goten = isFloatType(type_goten); 17786 17787 /* Skip matrices */ 17788 if (1 != type_goten.m_n_columns) 17789 { 17790 continue; 17791 } 17792 17793 /* Skip valid combinations */ 17794 if (is_float_type_gohan == is_float_type_goten) 17795 { 17796 continue; 17797 } 17798 17799 const GLuint n_req_components_gohan = type_gohan.m_n_rows; 17800 const GLuint n_req_components_goten = type_goten.m_n_rows; 17801 const GLuint valid_component_gohan = n_components_per_location - n_req_components_gohan; 17802 const GLuint valid_component_goten = n_components_per_location - n_req_components_goten; 17803 17804 /* Skip pairs that cannot fit into one location */ 17805 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten)) 17806 { 17807 continue; 17808 } 17809 17810 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 17811 { 17812 /* Skip compute shader */ 17813 if (Utils::Shader::COMPUTE == stage) 17814 { 17815 continue; 17816 } 17817 17818 for (GLuint gohan = 0; gohan <= valid_component_gohan; ++gohan) 17819 { 17820 const GLint first_aliasing = gohan - n_req_components_goten + 1; 17821 const GLint last_aliasing = gohan + n_req_components_gohan - 1; 17822 17823 const GLuint goten_lower_limit = std::max(0, first_aliasing); 17824 const GLuint goten_upper_limit = last_aliasing + 1; 17825 17826 /* Compoennets before gohan */ 17827 for (GLuint goten = 0; goten < goten_lower_limit; ++goten) 17828 { 17829 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage, 17830 type_gohan, type_goten }; 17831 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage, 17832 type_gohan, type_goten }; 17833 17834 m_test_cases.push_back(test_case_in); 17835 17836 /* Skip double outputs in fragment shader */ 17837 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) && 17838 (Utils::Type::Double != type_goten.m_basic_type))) 17839 { 17840 m_test_cases.push_back(test_case_out); 17841 } 17842 } 17843 17844 /* Components after gohan */ 17845 for (GLuint goten = goten_upper_limit; goten <= valid_component_goten; ++goten) 17846 { 17847 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage, 17848 type_gohan, type_goten }; 17849 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage, 17850 type_gohan, type_goten }; 17851 17852 m_test_cases.push_back(test_case_in); 17853 17854 /* Skip double outputs in fragment shader */ 17855 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) && 17856 (Utils::Type::Double != type_goten.m_basic_type))) 17857 { 17858 m_test_cases.push_back(test_case_out); 17859 } 17860 } 17861 } 17862 } 17863 } 17864 } 17865 } 17866 17867 /** Check if given type is float 17868 * 17869 * @param type Type in question 17870 * 17871 * @return true if tpye is float, false otherwise 17872 **/ 17873 bool VaryingLocationAliasingWithMixedTypesTest::isFloatType(const Utils::Type& type) 17874 { 17875 bool is_float = false; 17876 17877 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type)) 17878 { 17879 is_float = true; 17880 } 17881 17882 return is_float; 17883 } 17884 17885 /** Constructor 17886 * 17887 * @param context Test framework context 17888 **/ 17889 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest( 17890 deqp::Context& context) 17891 : NegativeTestBase( 17892 context, "varying_location_aliasing_with_mixed_interpolation", 17893 "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location") 17894 { 17895 } 17896 17897 /** Source for given test case and stage 17898 * 17899 * @param test_case_index Index of test case 17900 * @param stage Shader stage 17901 * 17902 * @return Shader source 17903 **/ 17904 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint test_case_index, 17905 Utils::Shader::STAGES stage) 17906 { 17907 static const GLchar* var_definition = 17908 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n" 17909 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n"; 17910 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n" 17911 " (TYPE(1) == gotenINDEX) )\n" 17912 " {\n" 17913 " result += vec4(1, 0.5, 0.25, 0.125);\n" 17914 " }\n"; 17915 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n" 17916 " gotenINDEX = TYPE(1);\n" 17917 " if (vec4(0) == result)\n" 17918 " {\n" 17919 " gohanINDEX = TYPE(1);\n" 17920 " gotenINDEX = TYPE(0);\n" 17921 " }\n"; 17922 static const GLchar* fs = "#version 430 core\n" 17923 "#extension GL_ARB_enhanced_layouts : require\n" 17924 "\n" 17925 "in vec4 gs_fs;\n" 17926 "out vec4 fs_out;\n" 17927 "\n" 17928 "void main()\n" 17929 "{\n" 17930 " fs_out = gs_fs;\n" 17931 "}\n" 17932 "\n"; 17933 static const GLchar* fs_tested = "#version 430 core\n" 17934 "#extension GL_ARB_enhanced_layouts : require\n" 17935 "\n" 17936 "VAR_DEFINITION" 17937 "\n" 17938 "in vec4 gs_fs;\n" 17939 "out vec4 fs_out;\n" 17940 "\n" 17941 "void main()\n" 17942 "{\n" 17943 " vec4 result = gs_fs;\n" 17944 "\n" 17945 "VARIABLE_USE" 17946 "\n" 17947 " fs_out = result;\n" 17948 "}\n" 17949 "\n"; 17950 static const GLchar* gs = "#version 430 core\n" 17951 "#extension GL_ARB_enhanced_layouts : require\n" 17952 "\n" 17953 "layout(points) in;\n" 17954 "layout(triangle_strip, max_vertices = 4) out;\n" 17955 "\n" 17956 "in vec4 tes_gs[];\n" 17957 "out vec4 gs_fs;\n" 17958 "\n" 17959 "void main()\n" 17960 "{\n" 17961 " gs_fs = tes_gs[0];\n" 17962 " gl_Position = vec4(-1, -1, 0, 1);\n" 17963 " EmitVertex();\n" 17964 " gs_fs = tes_gs[0];\n" 17965 " gl_Position = vec4(-1, 1, 0, 1);\n" 17966 " EmitVertex();\n" 17967 " gs_fs = tes_gs[0];\n" 17968 " gl_Position = vec4(1, -1, 0, 1);\n" 17969 " EmitVertex();\n" 17970 " gs_fs = tes_gs[0];\n" 17971 " gl_Position = vec4(1, 1, 0, 1);\n" 17972 " EmitVertex();\n" 17973 "}\n" 17974 "\n"; 17975 static const GLchar* gs_tested = "#version 430 core\n" 17976 "#extension GL_ARB_enhanced_layouts : require\n" 17977 "\n" 17978 "layout(points) in;\n" 17979 "layout(triangle_strip, max_vertices = 4) out;\n" 17980 "\n" 17981 "VAR_DEFINITION" 17982 "\n" 17983 "in vec4 tes_gs[];\n" 17984 "out vec4 gs_fs;\n" 17985 "\n" 17986 "void main()\n" 17987 "{\n" 17988 " vec4 result = tes_gs[0];\n" 17989 "\n" 17990 "VARIABLE_USE" 17991 "\n" 17992 " gs_fs = result;\n" 17993 " gl_Position = vec4(-1, -1, 0, 1);\n" 17994 " EmitVertex();\n" 17995 " gs_fs = result;\n" 17996 " gl_Position = vec4(-1, 1, 0, 1);\n" 17997 " EmitVertex();\n" 17998 " gs_fs = result;\n" 17999 " gl_Position = vec4(1, -1, 0, 1);\n" 18000 " EmitVertex();\n" 18001 " gs_fs = result;\n" 18002 " gl_Position = vec4(1, 1, 0, 1);\n" 18003 " EmitVertex();\n" 18004 "}\n" 18005 "\n"; 18006 static const GLchar* tcs = "#version 430 core\n" 18007 "#extension GL_ARB_enhanced_layouts : require\n" 18008 "\n" 18009 "layout(vertices = 1) out;\n" 18010 "\n" 18011 "in vec4 vs_tcs[];\n" 18012 "out vec4 tcs_tes[];\n" 18013 "\n" 18014 "void main()\n" 18015 "{\n" 18016 "\n" 18017 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 18018 "\n" 18019 " gl_TessLevelOuter[0] = 1.0;\n" 18020 " gl_TessLevelOuter[1] = 1.0;\n" 18021 " gl_TessLevelOuter[2] = 1.0;\n" 18022 " gl_TessLevelOuter[3] = 1.0;\n" 18023 " gl_TessLevelInner[0] = 1.0;\n" 18024 " gl_TessLevelInner[1] = 1.0;\n" 18025 "}\n" 18026 "\n"; 18027 static const GLchar* tcs_tested = "#version 430 core\n" 18028 "#extension GL_ARB_enhanced_layouts : require\n" 18029 "\n" 18030 "layout(vertices = 1) out;\n" 18031 "\n" 18032 "VAR_DEFINITION" 18033 "\n" 18034 "in vec4 vs_tcs[];\n" 18035 "out vec4 tcs_tes[];\n" 18036 "\n" 18037 "void main()\n" 18038 "{\n" 18039 " vec4 result = vs_tcs[gl_InvocationID];\n" 18040 "\n" 18041 "VARIABLE_USE" 18042 "\n" 18043 " tcs_tes[gl_InvocationID] = result;\n" 18044 "\n" 18045 " gl_TessLevelOuter[0] = 1.0;\n" 18046 " gl_TessLevelOuter[1] = 1.0;\n" 18047 " gl_TessLevelOuter[2] = 1.0;\n" 18048 " gl_TessLevelOuter[3] = 1.0;\n" 18049 " gl_TessLevelInner[0] = 1.0;\n" 18050 " gl_TessLevelInner[1] = 1.0;\n" 18051 "}\n" 18052 "\n"; 18053 static const GLchar* tes = "#version 430 core\n" 18054 "#extension GL_ARB_enhanced_layouts : require\n" 18055 "\n" 18056 "layout(isolines, point_mode) in;\n" 18057 "\n" 18058 "in vec4 tcs_tes[];\n" 18059 "out vec4 tes_gs;\n" 18060 "\n" 18061 "void main()\n" 18062 "{\n" 18063 " tes_gs = tcs_tes[0];\n" 18064 "}\n" 18065 "\n"; 18066 static const GLchar* tes_tested = "#version 430 core\n" 18067 "#extension GL_ARB_enhanced_layouts : require\n" 18068 "\n" 18069 "layout(isolines, point_mode) in;\n" 18070 "\n" 18071 "VAR_DEFINITION" 18072 "\n" 18073 "in vec4 tcs_tes[];\n" 18074 "out vec4 tes_gs;\n" 18075 "\n" 18076 "void main()\n" 18077 "{\n" 18078 " vec4 result = tcs_tes[0];\n" 18079 "\n" 18080 "VARIABLE_USE" 18081 "\n" 18082 " tes_gs += result;\n" 18083 "}\n" 18084 "\n"; 18085 static const GLchar* vs = "#version 430 core\n" 18086 "#extension GL_ARB_enhanced_layouts : require\n" 18087 "\n" 18088 "in vec4 in_vs;\n" 18089 "out vec4 vs_tcs;\n" 18090 "\n" 18091 "void main()\n" 18092 "{\n" 18093 " vs_tcs = in_vs;\n" 18094 "}\n" 18095 "\n"; 18096 static const GLchar* vs_tested = "#version 430 core\n" 18097 "#extension GL_ARB_enhanced_layouts : require\n" 18098 "\n" 18099 "VAR_DEFINITION" 18100 "\n" 18101 "in vec4 in_vs;\n" 18102 "out vec4 vs_tcs;\n" 18103 "\n" 18104 "void main()\n" 18105 "{\n" 18106 " vec4 result = in_vs;\n" 18107 "\n" 18108 "VARIABLE_USE" 18109 "\n" 18110 " vs_tcs += result;\n" 18111 "}\n" 18112 "\n"; 18113 18114 std::string source; 18115 testCase& test_case = m_test_cases[test_case_index]; 18116 18117 if (test_case.m_stage == stage) 18118 { 18119 const GLchar* array = ""; 18120 GLchar buffer_gohan[16]; 18121 GLchar buffer_goten[16]; 18122 const GLchar* direction = "in "; 18123 const GLchar* index = ""; 18124 const GLchar* int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan); 18125 const GLchar* int_goten = getInterpolationQualifier(test_case.m_interpolation_goten); 18126 size_t position = 0; 18127 size_t temp; 18128 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName(); 18129 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName(); 18130 const GLchar* var_use = input_use; 18131 18132 if (false == test_case.m_is_input) 18133 { 18134 direction = "out"; 18135 18136 var_use = output_use; 18137 } 18138 18139 sprintf(buffer_gohan, "%d", test_case.m_component_gohan); 18140 sprintf(buffer_goten, "%d", test_case.m_component_goten); 18141 18142 switch (stage) 18143 { 18144 case Utils::Shader::FRAGMENT: 18145 source = fs_tested; 18146 break; 18147 case Utils::Shader::GEOMETRY: 18148 source = gs_tested; 18149 array = "[]"; 18150 index = "[0]"; 18151 break; 18152 case Utils::Shader::TESS_CTRL: 18153 source = tcs_tested; 18154 array = "[]"; 18155 index = "[gl_InvocationID]"; 18156 break; 18157 case Utils::Shader::TESS_EVAL: 18158 source = tes_tested; 18159 array = "[]"; 18160 index = "[0]"; 18161 break; 18162 case Utils::Shader::VERTEX: 18163 source = vs_tested; 18164 break; 18165 default: 18166 TCU_FAIL("Invalid enum"); 18167 } 18168 18169 temp = position; 18170 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 18171 position = temp; 18172 Utils::replaceToken("COMPONENT", position, buffer_gohan, source); 18173 Utils::replaceToken("INTERPOLATION", position, int_gohan, source); 18174 Utils::replaceToken("DIRECTION", position, direction, source); 18175 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18176 Utils::replaceToken("ARRAY", position, array, source); 18177 Utils::replaceToken("COMPONENT", position, buffer_goten, source); 18178 Utils::replaceToken("INTERPOLATION", position, int_goten, source); 18179 Utils::replaceToken("DIRECTION", position, direction, source); 18180 Utils::replaceToken("TYPE", position, type_goten_name, source); 18181 Utils::replaceToken("ARRAY", position, array, source); 18182 18183 temp = position; 18184 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 18185 position = temp; 18186 if (true == test_case.m_is_input) 18187 { 18188 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18189 Utils::replaceToken("TYPE", position, type_goten_name, source); 18190 } 18191 else 18192 { 18193 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18194 Utils::replaceToken("TYPE", position, type_goten_name, source); 18195 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18196 Utils::replaceToken("TYPE", position, type_goten_name, source); 18197 } 18198 18199 Utils::replaceAllTokens("INDEX", index, source); 18200 } 18201 else 18202 { 18203 switch (stage) 18204 { 18205 case Utils::Shader::FRAGMENT: 18206 source = fs; 18207 break; 18208 case Utils::Shader::GEOMETRY: 18209 source = gs; 18210 break; 18211 case Utils::Shader::TESS_CTRL: 18212 source = tcs; 18213 break; 18214 case Utils::Shader::TESS_EVAL: 18215 source = tes; 18216 break; 18217 case Utils::Shader::VERTEX: 18218 source = vs; 18219 break; 18220 default: 18221 TCU_FAIL("Invalid enum"); 18222 } 18223 } 18224 18225 return source; 18226 } 18227 18228 /** Get description of test case 18229 * 18230 * @param test_case_index Index of test case 18231 * 18232 * @return Test case description 18233 **/ 18234 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index) 18235 { 18236 std::stringstream stream; 18237 testCase& test_case = m_test_cases[test_case_index]; 18238 18239 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", " 18240 << getInterpolationQualifier(test_case.m_interpolation_gohan) << " " 18241 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", " 18242 << getInterpolationQualifier(test_case.m_interpolation_goten) << " " 18243 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: "; 18244 18245 if (true == test_case.m_is_input) 18246 { 18247 stream << "input"; 18248 } 18249 else 18250 { 18251 stream << "output"; 18252 } 18253 18254 return stream.str(); 18255 } 18256 18257 /** Get number of test cases 18258 * 18259 * @return Number of test cases 18260 **/ 18261 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber() 18262 { 18263 return static_cast<GLuint>(m_test_cases.size()); 18264 } 18265 18266 /** Selects if "compute" stage is relevant for test 18267 * 18268 * @param ignored 18269 * 18270 * @return false 18271 **/ 18272 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */) 18273 { 18274 return false; 18275 } 18276 18277 /** Prepare all test cases 18278 * 18279 **/ 18280 void VaryingLocationAliasingWithMixedInterpolationTest::testInit() 18281 { 18282 static const GLuint n_components_per_location = 4; 18283 const GLuint n_types = getTypesNumber(); 18284 18285 for (GLuint i = 0; i < n_types; ++i) 18286 { 18287 const Utils::Type& type_gohan = getType(i); 18288 const bool is_float_type_gohan = isFloatType(type_gohan); 18289 18290 /* Skip matrices */ 18291 if (1 != type_gohan.m_n_columns) 18292 { 18293 continue; 18294 } 18295 18296 for (GLuint j = 0; j < n_types; ++j) 18297 { 18298 const Utils::Type& type_goten = getType(j); 18299 const bool is_float_type_goten = isFloatType(type_goten); 18300 18301 /* Skip matrices */ 18302 if (1 != type_goten.m_n_columns) 18303 { 18304 continue; 18305 } 18306 18307 /* Skip invalid combinations */ 18308 if (is_float_type_gohan != is_float_type_goten) 18309 { 18310 continue; 18311 } 18312 18313 const GLuint n_req_components_gohan = type_gohan.m_n_rows; 18314 const GLuint n_req_components_goten = type_goten.m_n_rows; 18315 18316 /* Skip pairs that cannot fit into one location */ 18317 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten)) 18318 { 18319 continue; 18320 } 18321 18322 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 18323 { 18324 /* Skip compute shader */ 18325 if (Utils::Shader::COMPUTE == stage) 18326 { 18327 continue; 18328 } 18329 18330 const GLuint gohan = 0; 18331 const GLuint goten = gohan + n_req_components_gohan; 18332 18333 for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan) 18334 { 18335 for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten) 18336 { 18337 const bool is_gohan_double = (Utils::Type::Double == type_gohan.m_basic_type) ? true : false; 18338 const bool is_goten_double = (Utils::Type::Double == type_goten.m_basic_type) ? true : false; 18339 const bool is_gohan_flat = (FLAT == int_gohan) ? true : false; 18340 const bool is_goten_flat = (FLAT == int_goten) ? true : false; 18341 const bool is_gohan_accepted_as_fs_in = 18342 (is_gohan_double && is_gohan_flat) || (!is_gohan_double); 18343 const bool is_goten_accepted_as_fs_in = 18344 (is_goten_double && is_goten_flat) || (!is_goten_double); 18345 const bool is_comb_accepted_as_fs_in = is_gohan_accepted_as_fs_in && is_goten_accepted_as_fs_in; 18346 18347 /* Skip when both are the same */ 18348 if (int_gohan == int_goten) 18349 { 18350 continue; 18351 } 18352 18353 testCase test_case_in = { gohan, 18354 goten, 18355 (INTERPOLATIONS)int_gohan, 18356 (INTERPOLATIONS)int_goten, 18357 true, 18358 (Utils::Shader::STAGES)stage, 18359 type_gohan, 18360 type_goten }; 18361 18362 testCase test_case_out = { gohan, 18363 goten, 18364 (INTERPOLATIONS)int_gohan, 18365 (INTERPOLATIONS)int_goten, 18366 false, 18367 (Utils::Shader::STAGES)stage, 18368 type_gohan, 18369 type_goten }; 18370 18371 /* Skip inputs in: 18372 * vertex shader, 18373 * fragment shader when not flat double is used 18374 */ 18375 if ((Utils::Shader::VERTEX != stage) && 18376 ((Utils::Shader::FRAGMENT != stage) || (true == is_comb_accepted_as_fs_in))) 18377 { 18378 m_test_cases.push_back(test_case_in); 18379 } 18380 18381 /* Skip outputs in fragment shader */ 18382 if (Utils::Shader::FRAGMENT != stage) 18383 { 18384 m_test_cases.push_back(test_case_out); 18385 } 18386 } 18387 } 18388 } 18389 } 18390 } 18391 } 18392 18393 /** Get interpolation qualifier 18394 * 18395 * @param interpolation Enumeration 18396 * 18397 * @return GLSL qualifier 18398 **/ 18399 const GLchar* VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation) 18400 { 18401 const GLchar* result = 0; 18402 18403 switch (interpolation) 18404 { 18405 case SMOOTH: 18406 result = "smooth"; 18407 break; 18408 case FLAT: 18409 result = "flat"; 18410 break; 18411 case NO_PERSPECTIVE: 18412 result = "noperspective"; 18413 break; 18414 default: 18415 TCU_FAIL("Invalid enum"); 18416 } 18417 18418 return result; 18419 } 18420 18421 /** Check if given type is float 18422 * 18423 * @param type Type in question 18424 * 18425 * @return true if tpye is float, false otherwise 18426 **/ 18427 bool VaryingLocationAliasingWithMixedInterpolationTest::isFloatType(const Utils::Type& type) 18428 { 18429 bool is_float = false; 18430 18431 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type)) 18432 { 18433 is_float = true; 18434 } 18435 18436 return is_float; 18437 } 18438 18439 /** Constructor 18440 * 18441 * @param context Test framework context 18442 **/ 18443 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest( 18444 deqp::Context& context) 18445 : NegativeTestBase( 18446 context, "varying_location_aliasing_with_mixed_auxiliary_storage", 18447 "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location") 18448 { 18449 } 18450 18451 /** Source for given test case and stage 18452 * 18453 * @param test_case_index Index of test case 18454 * @param stage Shader stage 18455 * 18456 * @return Shader source 18457 **/ 18458 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint test_case_index, 18459 Utils::Shader::STAGES stage) 18460 { 18461 static const GLchar* var_definition = 18462 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n" 18463 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n"; 18464 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX_GOHAN) &&\n" 18465 " (TYPE(1) == gotenINDEX_GOTEN) )\n" 18466 " {\n" 18467 " result += vec4(1, 0.5, 0.25, 0.125);\n" 18468 " }\n"; 18469 static const GLchar* output_use = " gohanINDEX_GOHAN = TYPE(0);\n" 18470 " gotenINDEX_GOTEN = TYPE(1);\n" 18471 " if (vec4(0) == result)\n" 18472 " {\n" 18473 " gohanINDEX_GOHAN = TYPE(1);\n" 18474 " gotenINDEX_GOTEN = TYPE(0);\n" 18475 " }\n"; 18476 static const GLchar* fs = "#version 430 core\n" 18477 "#extension GL_ARB_enhanced_layouts : require\n" 18478 "\n" 18479 "in vec4 gs_fs;\n" 18480 "out vec4 fs_out;\n" 18481 "\n" 18482 "void main()\n" 18483 "{\n" 18484 " fs_out = gs_fs;\n" 18485 "}\n" 18486 "\n"; 18487 static const GLchar* fs_tested = "#version 430 core\n" 18488 "#extension GL_ARB_enhanced_layouts : require\n" 18489 "\n" 18490 "VAR_DEFINITION" 18491 "\n" 18492 "in vec4 gs_fs;\n" 18493 "out vec4 fs_out;\n" 18494 "\n" 18495 "void main()\n" 18496 "{\n" 18497 " vec4 result = gs_fs;\n" 18498 "\n" 18499 "VARIABLE_USE" 18500 "\n" 18501 " fs_out = result;\n" 18502 "}\n" 18503 "\n"; 18504 static const GLchar* gs = "#version 430 core\n" 18505 "#extension GL_ARB_enhanced_layouts : require\n" 18506 "\n" 18507 "layout(points) in;\n" 18508 "layout(triangle_strip, max_vertices = 4) out;\n" 18509 "\n" 18510 "in vec4 tes_gs[];\n" 18511 "out vec4 gs_fs;\n" 18512 "\n" 18513 "void main()\n" 18514 "{\n" 18515 " gs_fs = tes_gs[0];\n" 18516 " gl_Position = vec4(-1, -1, 0, 1);\n" 18517 " EmitVertex();\n" 18518 " gs_fs = tes_gs[0];\n" 18519 " gl_Position = vec4(-1, 1, 0, 1);\n" 18520 " EmitVertex();\n" 18521 " gs_fs = tes_gs[0];\n" 18522 " gl_Position = vec4(1, -1, 0, 1);\n" 18523 " EmitVertex();\n" 18524 " gs_fs = tes_gs[0];\n" 18525 " gl_Position = vec4(1, 1, 0, 1);\n" 18526 " EmitVertex();\n" 18527 "}\n" 18528 "\n"; 18529 static const GLchar* gs_tested = "#version 430 core\n" 18530 "#extension GL_ARB_enhanced_layouts : require\n" 18531 "\n" 18532 "layout(points) in;\n" 18533 "layout(triangle_strip, max_vertices = 4) out;\n" 18534 "\n" 18535 "VAR_DEFINITION" 18536 "\n" 18537 "in vec4 tes_gs[];\n" 18538 "out vec4 gs_fs;\n" 18539 "\n" 18540 "void main()\n" 18541 "{\n" 18542 " vec4 result = tes_gs[0];\n" 18543 "\n" 18544 "VARIABLE_USE" 18545 "\n" 18546 " gs_fs = result;\n" 18547 " gl_Position = vec4(-1, -1, 0, 1);\n" 18548 " EmitVertex();\n" 18549 " gs_fs = result;\n" 18550 " gl_Position = vec4(-1, 1, 0, 1);\n" 18551 " EmitVertex();\n" 18552 " gs_fs = result;\n" 18553 " gl_Position = vec4(1, -1, 0, 1);\n" 18554 " EmitVertex();\n" 18555 " gs_fs = result;\n" 18556 " gl_Position = vec4(1, 1, 0, 1);\n" 18557 " EmitVertex();\n" 18558 "}\n" 18559 "\n"; 18560 static const GLchar* tcs = "#version 430 core\n" 18561 "#extension GL_ARB_enhanced_layouts : require\n" 18562 "\n" 18563 "layout(vertices = 1) out;\n" 18564 "\n" 18565 "in vec4 vs_tcs[];\n" 18566 "out vec4 tcs_tes[];\n" 18567 "\n" 18568 "void main()\n" 18569 "{\n" 18570 "\n" 18571 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 18572 "\n" 18573 " gl_TessLevelOuter[0] = 1.0;\n" 18574 " gl_TessLevelOuter[1] = 1.0;\n" 18575 " gl_TessLevelOuter[2] = 1.0;\n" 18576 " gl_TessLevelOuter[3] = 1.0;\n" 18577 " gl_TessLevelInner[0] = 1.0;\n" 18578 " gl_TessLevelInner[1] = 1.0;\n" 18579 "}\n" 18580 "\n"; 18581 static const GLchar* tcs_tested = "#version 430 core\n" 18582 "#extension GL_ARB_enhanced_layouts : require\n" 18583 "\n" 18584 "layout(vertices = 1) out;\n" 18585 "\n" 18586 "VAR_DEFINITION" 18587 "\n" 18588 "in vec4 vs_tcs[];\n" 18589 "out vec4 tcs_tes[];\n" 18590 "\n" 18591 "void main()\n" 18592 "{\n" 18593 " vec4 result = vs_tcs[gl_InvocationID];\n" 18594 "\n" 18595 "VARIABLE_USE" 18596 "\n" 18597 " tcs_tes[gl_InvocationID] = result;\n" 18598 "\n" 18599 " gl_TessLevelOuter[0] = 1.0;\n" 18600 " gl_TessLevelOuter[1] = 1.0;\n" 18601 " gl_TessLevelOuter[2] = 1.0;\n" 18602 " gl_TessLevelOuter[3] = 1.0;\n" 18603 " gl_TessLevelInner[0] = 1.0;\n" 18604 " gl_TessLevelInner[1] = 1.0;\n" 18605 "}\n" 18606 "\n"; 18607 static const GLchar* tes = "#version 430 core\n" 18608 "#extension GL_ARB_enhanced_layouts : require\n" 18609 "\n" 18610 "layout(isolines, point_mode) in;\n" 18611 "\n" 18612 "in vec4 tcs_tes[];\n" 18613 "out vec4 tes_gs;\n" 18614 "\n" 18615 "void main()\n" 18616 "{\n" 18617 " tes_gs = tcs_tes[0];\n" 18618 "}\n" 18619 "\n"; 18620 static const GLchar* tes_tested = "#version 430 core\n" 18621 "#extension GL_ARB_enhanced_layouts : require\n" 18622 "\n" 18623 "layout(isolines, point_mode) in;\n" 18624 "\n" 18625 "VAR_DEFINITION" 18626 "\n" 18627 "in vec4 tcs_tes[];\n" 18628 "out vec4 tes_gs;\n" 18629 "\n" 18630 "void main()\n" 18631 "{\n" 18632 " vec4 result = tcs_tes[0];\n" 18633 "\n" 18634 "VARIABLE_USE" 18635 "\n" 18636 " tes_gs += result;\n" 18637 "}\n" 18638 "\n"; 18639 static const GLchar* vs = "#version 430 core\n" 18640 "#extension GL_ARB_enhanced_layouts : require\n" 18641 "\n" 18642 "in vec4 in_vs;\n" 18643 "out vec4 vs_tcs;\n" 18644 "\n" 18645 "void main()\n" 18646 "{\n" 18647 " vs_tcs = in_vs;\n" 18648 "}\n" 18649 "\n"; 18650 static const GLchar* vs_tested = "#version 430 core\n" 18651 "#extension GL_ARB_enhanced_layouts : require\n" 18652 "\n" 18653 "VAR_DEFINITION" 18654 "\n" 18655 "in vec4 in_vs;\n" 18656 "out vec4 vs_tcs;\n" 18657 "\n" 18658 "void main()\n" 18659 "{\n" 18660 " vec4 result = in_vs;\n" 18661 "\n" 18662 "VARIABLE_USE" 18663 "\n" 18664 " vs_tcs += result;\n" 18665 "}\n" 18666 "\n"; 18667 18668 std::string source; 18669 testCase& test_case = m_test_cases[test_case_index]; 18670 18671 if (test_case.m_stage == stage) 18672 { 18673 const GLchar* array_gohan = ""; 18674 const GLchar* array_goten = ""; 18675 const GLchar* aux_gohan = getAuxiliaryQualifier(test_case.m_aux_gohan); 18676 const GLchar* aux_goten = getAuxiliaryQualifier(test_case.m_aux_goten); 18677 GLchar buffer_gohan[16]; 18678 GLchar buffer_goten[16]; 18679 const GLchar* direction = "in "; 18680 const GLchar* index_gohan = ""; 18681 const GLchar* index_goten = ""; 18682 const GLchar* int_gohan = test_case.m_int_gohan; 18683 const GLchar* int_goten = test_case.m_int_goten; 18684 size_t position = 0; 18685 size_t temp; 18686 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName(); 18687 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName(); 18688 const GLchar* var_use = input_use; 18689 18690 if (false == test_case.m_is_input) 18691 { 18692 direction = "out"; 18693 18694 var_use = output_use; 18695 } 18696 18697 sprintf(buffer_gohan, "%d", test_case.m_component_gohan); 18698 sprintf(buffer_goten, "%d", test_case.m_component_goten); 18699 18700 switch (stage) 18701 { 18702 case Utils::Shader::FRAGMENT: 18703 source = fs_tested; 18704 break; 18705 case Utils::Shader::GEOMETRY: 18706 source = gs_tested; 18707 array_gohan = "[]"; 18708 index_gohan = "[0]"; 18709 array_goten = "[]"; 18710 index_goten = "[0]"; 18711 break; 18712 case Utils::Shader::TESS_CTRL: 18713 source = tcs_tested; 18714 if (PATCH != test_case.m_aux_gohan) 18715 { 18716 array_gohan = "[]"; 18717 index_gohan = "[gl_InvocationID]"; 18718 } 18719 if (PATCH != test_case.m_aux_goten) 18720 { 18721 array_goten = "[]"; 18722 index_goten = "[gl_InvocationID]"; 18723 } 18724 break; 18725 case Utils::Shader::TESS_EVAL: 18726 source = tes_tested; 18727 array_gohan = "[]"; 18728 index_gohan = "[0]"; 18729 array_goten = "[]"; 18730 index_goten = "[0]"; 18731 break; 18732 case Utils::Shader::VERTEX: 18733 source = vs_tested; 18734 break; 18735 default: 18736 TCU_FAIL("Invalid enum"); 18737 } 18738 18739 temp = position; 18740 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 18741 position = temp; 18742 Utils::replaceToken("COMPONENT", position, buffer_gohan, source); 18743 Utils::replaceToken("AUX", position, aux_gohan, source); 18744 Utils::replaceToken("INTERPOLATION", position, int_gohan, source); 18745 Utils::replaceToken("DIRECTION", position, direction, source); 18746 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18747 Utils::replaceToken("ARRAY", position, array_gohan, source); 18748 Utils::replaceToken("COMPONENT", position, buffer_goten, source); 18749 Utils::replaceToken("AUX", position, aux_goten, source); 18750 Utils::replaceToken("INTERPOLATION", position, int_goten, source); 18751 Utils::replaceToken("DIRECTION", position, direction, source); 18752 Utils::replaceToken("TYPE", position, type_goten_name, source); 18753 Utils::replaceToken("ARRAY", position, array_goten, source); 18754 18755 temp = position; 18756 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 18757 position = temp; 18758 if (true == test_case.m_is_input) 18759 { 18760 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18761 Utils::replaceToken("TYPE", position, type_goten_name, source); 18762 } 18763 else 18764 { 18765 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18766 Utils::replaceToken("TYPE", position, type_goten_name, source); 18767 Utils::replaceToken("TYPE", position, type_gohan_name, source); 18768 Utils::replaceToken("TYPE", position, type_goten_name, source); 18769 } 18770 18771 Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source); 18772 Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source); 18773 } 18774 else 18775 { 18776 switch (stage) 18777 { 18778 case Utils::Shader::FRAGMENT: 18779 source = fs; 18780 break; 18781 case Utils::Shader::GEOMETRY: 18782 source = gs; 18783 break; 18784 case Utils::Shader::TESS_CTRL: 18785 source = tcs; 18786 break; 18787 case Utils::Shader::TESS_EVAL: 18788 source = tes; 18789 break; 18790 case Utils::Shader::VERTEX: 18791 source = vs; 18792 break; 18793 default: 18794 TCU_FAIL("Invalid enum"); 18795 } 18796 } 18797 18798 return source; 18799 } 18800 18801 /** Get description of test case 18802 * 18803 * @param test_case_index Index of test case 18804 * 18805 * @return Test case description 18806 **/ 18807 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index) 18808 { 18809 std::stringstream stream; 18810 testCase& test_case = m_test_cases[test_case_index]; 18811 18812 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", " 18813 << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at " 18814 << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " " 18815 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: "; 18816 18817 if (true == test_case.m_is_input) 18818 { 18819 stream << "input"; 18820 } 18821 else 18822 { 18823 stream << "output"; 18824 } 18825 18826 return stream.str(); 18827 } 18828 18829 /** Get number of test cases 18830 * 18831 * @return Number of test cases 18832 **/ 18833 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber() 18834 { 18835 return static_cast<GLuint>(m_test_cases.size()); 18836 } 18837 18838 /** Selects if "compute" stage is relevant for test 18839 * 18840 * @param ignored 18841 * 18842 * @return false 18843 **/ 18844 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */) 18845 { 18846 return false; 18847 } 18848 18849 /** Prepare all test cases 18850 * 18851 **/ 18852 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit() 18853 { 18854 static const GLuint n_components_per_location = 4; 18855 const GLuint n_types = getTypesNumber(); 18856 18857 for (GLuint i = 0; i < n_types; ++i) 18858 { 18859 const Utils::Type& type_gohan = getType(i); 18860 const bool is_float_type_gohan = isFloatType(type_gohan); 18861 18862 /* Skip matrices */ 18863 if (1 != type_gohan.m_n_columns) 18864 { 18865 continue; 18866 } 18867 18868 for (GLuint j = 0; j < n_types; ++j) 18869 { 18870 const Utils::Type& type_goten = getType(j); 18871 const bool is_flat_req_gohan = (Utils::Type::Float == type_gohan.m_basic_type) ? false : true; 18872 const bool is_flat_req_goten = (Utils::Type::Float == type_goten.m_basic_type) ? false : true; 18873 const bool is_float_type_goten = isFloatType(type_goten); 18874 18875 /* Skip matrices */ 18876 if (1 != type_goten.m_n_columns) 18877 { 18878 continue; 18879 } 18880 18881 /* Skip invalid combinations */ 18882 if (is_float_type_gohan != is_float_type_goten) 18883 { 18884 continue; 18885 } 18886 18887 const GLuint n_req_components_gohan = type_gohan.m_n_rows; 18888 const GLuint n_req_components_goten = type_goten.m_n_rows; 18889 18890 /* Skip pairs that cannot fit into one location */ 18891 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten)) 18892 { 18893 continue; 18894 } 18895 18896 const GLuint gohan = 0; 18897 const GLuint goten = gohan + n_req_components_gohan; 18898 18899 const GLchar* fs_int_gohan = is_flat_req_gohan ? "flat" : ""; 18900 const GLchar* fs_int_goten = is_flat_req_goten ? "flat" : ""; 18901 18902 testCase test_case_tcs_np = { gohan, goten, NONE, PATCH, "", "", false, Utils::Shader::TESS_CTRL, 18903 type_gohan, type_goten }; 18904 18905 testCase test_case_tcs_pn = { gohan, goten, PATCH, NONE, "", "", false, Utils::Shader::TESS_CTRL, 18906 type_gohan, type_goten }; 18907 18908 testCase test_case_tes_np = { gohan, goten, NONE, PATCH, "", "", true, Utils::Shader::TESS_EVAL, 18909 type_gohan, type_goten }; 18910 18911 testCase test_case_tes_pn = { gohan, goten, PATCH, NONE, "", "", true, Utils::Shader::TESS_EVAL, 18912 type_gohan, type_goten }; 18913 18914 testCase test_case_fs_nc = { gohan, goten, NONE, CENTROID, 18915 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT, 18916 type_gohan, type_goten }; 18917 18918 testCase test_case_fs_cn = { gohan, goten, CENTROID, NONE, 18919 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT, 18920 type_gohan, type_goten }; 18921 18922 testCase test_case_fs_ns = { gohan, goten, NONE, SAMPLE, 18923 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT, 18924 type_gohan, type_goten }; 18925 18926 testCase test_case_fs_sn = { gohan, goten, SAMPLE, NONE, 18927 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT, 18928 type_gohan, type_goten }; 18929 18930 testCase test_case_fs_cs = { gohan, goten, CENTROID, SAMPLE, 18931 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT, 18932 type_gohan, type_goten }; 18933 18934 testCase test_case_fs_sc = { gohan, goten, SAMPLE, CENTROID, 18935 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT, 18936 type_gohan, type_goten }; 18937 18938 m_test_cases.push_back(test_case_tcs_np); 18939 m_test_cases.push_back(test_case_tcs_pn); 18940 m_test_cases.push_back(test_case_tes_np); 18941 m_test_cases.push_back(test_case_tes_pn); 18942 m_test_cases.push_back(test_case_fs_nc); 18943 m_test_cases.push_back(test_case_fs_cn); 18944 m_test_cases.push_back(test_case_fs_ns); 18945 m_test_cases.push_back(test_case_fs_sn); 18946 m_test_cases.push_back(test_case_fs_cs); 18947 m_test_cases.push_back(test_case_fs_sc); 18948 } 18949 } 18950 } 18951 18952 /** Get auxiliary storage qualifier 18953 * 18954 * @param aux Enumeration 18955 * 18956 * @return GLSL qualifier 18957 **/ 18958 const GLchar* VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux) 18959 { 18960 const GLchar* result = 0; 18961 18962 switch (aux) 18963 { 18964 case NONE: 18965 result = ""; 18966 break; 18967 case PATCH: 18968 result = "patch"; 18969 break; 18970 case CENTROID: 18971 result = "centroid"; 18972 break; 18973 case SAMPLE: 18974 result = "sample"; 18975 break; 18976 default: 18977 TCU_FAIL("Invalid enum"); 18978 } 18979 18980 return result; 18981 } 18982 18983 /** Check if given type is float 18984 * 18985 * @param type Type in question 18986 * 18987 * @return true if tpye is float, false otherwise 18988 **/ 18989 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isFloatType(const Utils::Type& type) 18990 { 18991 bool is_float = false; 18992 18993 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type)) 18994 { 18995 is_float = true; 18996 } 18997 18998 return is_float; 18999 } 19000 19001 /* Constants used by VertexAttribLocationAPITest */ 19002 const GLuint VertexAttribLocationAPITest::m_goten_location = 6; 19003 19004 /** Constructor 19005 * 19006 * @param context Test framework context 19007 **/ 19008 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context& context) 19009 : TextureTestBase(context, "vertex_attrib_location_api", 19010 "Test verifies that attribute locations API works as expected") 19011 { 19012 } 19013 19014 /** Does BindAttribLocation for "goten" and relink program 19015 * 19016 * @param program Program object 19017 * @param program_interface Interface of program 19018 **/ 19019 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program& program, 19020 Utils::ProgramInterface& program_interface) 19021 { 19022 const Functions& gl = m_context.getRenderContext().getFunctions(); 19023 19024 gl.bindAttribLocation(program.m_id, m_goten_location, "goten"); 19025 GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation"); 19026 19027 program.Link(gl, program.m_id); 19028 19029 /* We still need to get locations for gohan and chichi */ 19030 TextureTestBase::prepareAttribLocation(program, program_interface); 19031 } 19032 19033 /** Get interface of program 19034 * 19035 * @param ignored 19036 * @param program_interface Interface of program 19037 * @param ignored 19038 **/ 19039 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */, 19040 Utils::ProgramInterface& program_interface, 19041 Utils::VaryingPassthrough& /* varying_passthrough */) 19042 { 19043 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX); 19044 const Utils::Type& type = Utils::Type::vec4; 19045 const GLuint type_size = type.GetSize(); 19046 19047 /* Offsets */ 19048 const GLuint chichi_offset = 0; 19049 const GLuint goten_offset = chichi_offset + type_size; 19050 const GLuint gohan_offset = goten_offset + type_size; 19051 const GLuint goku_offset = gohan_offset + type_size; 19052 19053 /* Locations */ 19054 const GLuint goku_location = 2; 19055 const GLuint goten_location = m_goten_location; 19056 19057 /* Generate data */ 19058 m_goku_data = type.GenerateDataPacked(); 19059 m_gohan_data = type.GenerateDataPacked(); 19060 m_goten_data = type.GenerateDataPacked(); 19061 m_chichi_data = type.GenerateDataPacked(); 19062 19063 /* Globals */ 19064 si.m_globals = "const uint GOKU_LOCATION = 2;\n"; 19065 19066 /* Attributes */ 19067 si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */, 19068 goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19069 0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid*)&m_goku_data[0] /* data */, 19070 m_goku_data.size() /* data_size */); 19071 19072 si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */, 19073 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19074 0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */, 19075 (GLvoid*)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */); 19076 19077 si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */, 19078 goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19079 0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */, 19080 (GLvoid*)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */); 19081 19082 si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */, 19083 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19084 0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */, 19085 (GLvoid*)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */); 19086 } 19087 19088 /** Selects if "compute" stage is relevant for test 19089 * 19090 * @param ignored 19091 * 19092 * @return false 19093 **/ 19094 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */) 19095 { 19096 return false; 19097 } 19098 19099 /* Constants used by FragmentDataLocationAPITest */ 19100 const GLuint FragmentDataLocationAPITest::m_goten_location = 6; 19101 19102 /** Constructor 19103 * 19104 * @param context Test framework context 19105 **/ 19106 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context& context) 19107 : TextureTestBase(context, "fragment_data_location_api", 19108 "Test verifies that fragment data locations API works as expected") 19109 , m_goku(context) 19110 , m_gohan(context) 19111 , m_goten(context) 19112 , m_chichi(context) 19113 { 19114 } 19115 19116 /** Verifies contents of drawn images 19117 * 19118 * @param ignored 19119 * @param ignored 19120 * 19121 * @return true if images are filled with expected values, false otherwise 19122 **/ 19123 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& /* color_0 */) 19124 { 19125 static const GLuint size = m_width * m_height; 19126 static const GLuint expected_goku = 0xff000000; 19127 static const GLuint expected_gohan = 0xff0000ff; 19128 static const GLuint expected_goten = 0xff00ff00; 19129 static const GLuint expected_chichi = 0xffff0000; 19130 19131 std::vector<GLuint> data; 19132 data.resize(size); 19133 19134 m_goku.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 19135 19136 for (GLuint i = 0; i < size; ++i) 19137 { 19138 const GLuint color = data[i]; 19139 19140 if (expected_goku != color) 19141 { 19142 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color 19143 << tcu::TestLog::EndMessage; 19144 return false; 19145 } 19146 } 19147 19148 m_gohan.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 19149 19150 for (GLuint i = 0; i < size; ++i) 19151 { 19152 const GLuint color = data[i]; 19153 19154 if (expected_gohan != color) 19155 { 19156 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color 19157 << tcu::TestLog::EndMessage; 19158 return false; 19159 } 19160 } 19161 19162 m_goten.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 19163 19164 for (GLuint i = 0; i < size; ++i) 19165 { 19166 const GLuint color = data[i]; 19167 19168 if (expected_goten != color) 19169 { 19170 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color 19171 << tcu::TestLog::EndMessage; 19172 return false; 19173 } 19174 } 19175 19176 m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 19177 19178 for (GLuint i = 0; i < size; ++i) 19179 { 19180 const GLuint color = data[i]; 19181 19182 if (expected_chichi != color) 19183 { 19184 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color 19185 << tcu::TestLog::EndMessage; 19186 return false; 19187 } 19188 } 19189 19190 return true; 19191 } 19192 19193 /** Prepare code snippet that will set out variables 19194 * 19195 * @param ignored 19196 * @param ignored 19197 * @param stage Shader stage 19198 * 19199 * @return Code that pass in variables to next stage 19200 **/ 19201 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */, 19202 Utils::VaryingPassthrough& /* varying_passthrough */, 19203 Utils::Shader::STAGES stage) 19204 { 19205 std::string result; 19206 19207 /* Skip for compute shader */ 19208 if (Utils::Shader::FRAGMENT != stage) 19209 { 19210 result = ""; 19211 } 19212 else 19213 { 19214 result = "chichi = vec4(0, 0, 1, 1);\n" 19215 " goku = vec4(0, 0, 0, 1);\n" 19216 " goten = vec4(0, 1, 0, 1);\n" 19217 " gohan = vec4(1, 0, 0, 1);\n"; 19218 } 19219 19220 return result; 19221 } 19222 19223 /** Get interface of program 19224 * 19225 * @param ignored 19226 * @param program_interface Interface of program 19227 * @param ignored 19228 **/ 19229 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */, 19230 Utils::ProgramInterface& program_interface, 19231 Utils::VaryingPassthrough& /* varying_passthrough */) 19232 { 19233 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT); 19234 const Utils::Type& type = Utils::Type::vec4; 19235 19236 /* Locations */ 19237 m_goku_location = 2; 19238 19239 /* Globals */ 19240 si.m_globals = "const uint GOKU_LOCATION = 2;\n"; 19241 19242 /* Attributes */ 19243 si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */, 19244 m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19245 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */); 19246 19247 si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */, 19248 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19249 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */); 19250 19251 si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */, 19252 m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19253 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */); 19254 19255 si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */, 19256 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */, 19257 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */); 19258 } 19259 19260 /** Selects if "compute" stage is relevant for test 19261 * 19262 * @param ignored 19263 * 19264 * @return false 19265 **/ 19266 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */) 19267 { 19268 return false; 19269 } 19270 19271 /** Get locations for all outputs with automatic_location 19272 * 19273 * @param program Program object 19274 * @param program_interface Interface of program 19275 **/ 19276 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program& program, 19277 Utils::ProgramInterface& program_interface) 19278 { 19279 /* Bind location of goten */ 19280 const Functions& gl = m_context.getRenderContext().getFunctions(); 19281 19282 gl.bindFragDataLocation(program.m_id, m_goten_location, "goten"); 19283 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation"); 19284 19285 program.Link(gl, program.m_id); 19286 19287 /* Prepare locations for gohan and chichi */ 19288 TextureTestBase::prepareFragmentDataLoc(program, program_interface); 19289 19290 /* Get all locations */ 19291 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT); 19292 19293 Utils::Variable::PtrVector& outputs = si.m_outputs; 19294 19295 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it) 19296 { 19297 const Utils::Variable::Descriptor& desc = (*it)->m_descriptor; 19298 19299 if (0 == desc.m_name.compare("gohan")) 19300 { 19301 m_gohan_location = desc.m_expected_location; 19302 } 19303 else if (0 == desc.m_name.compare("chichi")) 19304 { 19305 m_chichi_location = desc.m_expected_location; 19306 } 19307 19308 /* Locations of goku and goten are fixed */ 19309 } 19310 } 19311 19312 /** Prepare framebuffer with single texture as color attachment 19313 * 19314 * @param framebuffer Framebuffer 19315 * @param color_0_texture Texture that will used as color attachment 19316 **/ 19317 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture) 19318 { 19319 /* Let parent prepare its stuff */ 19320 TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture); 19321 19322 /* Prepare data */ 19323 std::vector<GLuint> texture_data; 19324 texture_data.resize(m_width * m_height); 19325 19326 for (GLuint i = 0; i < texture_data.size(); ++i) 19327 { 19328 texture_data[i] = 0x20406080; 19329 } 19330 19331 /* Prepare textures */ 19332 m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]); 19333 19334 m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]); 19335 19336 m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]); 19337 19338 m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]); 19339 19340 /* Attach textures to framebuffer */ 19341 framebuffer.Bind(); 19342 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height); 19343 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height); 19344 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height); 19345 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height); 19346 19347 /* Set up drawbuffers */ 19348 const Functions& gl = m_context.getRenderContext().getFunctions(); 19349 // The fragment shader can have more than 4 color outputs, but it only care about 4 (goku, gohan, goten, chichi). 19350 // We will first initialize all draw buffers to NONE and then set the real value for the 4 outputs we care about 19351 GLint maxDrawBuffers = 0; 19352 gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); 19353 19354 std::vector<GLenum> buffers(maxDrawBuffers, GL_NONE); 19355 buffers[m_chichi_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location); 19356 buffers[m_goten_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location); 19357 buffers[m_goku_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location); 19358 buffers[m_gohan_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location); 19359 19360 gl.drawBuffers(maxDrawBuffers, buffers.data()); 19361 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers"); 19362 } 19363 19364 /** Constructor 19365 * 19366 * @param context Test framework context 19367 **/ 19368 XFBInputTest::XFBInputTest(deqp::Context& context) 19369 : NegativeTestBase(context, "xfb_input", 19370 "Test verifies that compiler reports error when xfb qualifiers are used with input") 19371 { 19372 } 19373 19374 /** Source for given test case and stage 19375 * 19376 * @param test_case_index Index of test case 19377 * @param stage Shader stage 19378 * 19379 * @return Shader source 19380 **/ 19381 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 19382 { 19383 static const GLchar* buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n"; 19384 static const GLchar* offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n"; 19385 static const GLchar* stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n"; 19386 static const GLchar* input_use = " result += gohanINDEX;\n"; 19387 static const GLchar* fs = "#version 430 core\n" 19388 "#extension GL_ARB_enhanced_layouts : require\n" 19389 "\n" 19390 "in vec4 gs_fs;\n" 19391 "out vec4 fs_out;\n" 19392 "\n" 19393 "void main()\n" 19394 "{\n" 19395 " fs_out = gs_fs;\n" 19396 "}\n" 19397 "\n"; 19398 static const GLchar* fs_tested = "#version 430 core\n" 19399 "#extension GL_ARB_enhanced_layouts : require\n" 19400 "\n" 19401 "VAR_DEFINITION" 19402 "\n" 19403 "in vec4 gs_fs;\n" 19404 "out vec4 fs_out;\n" 19405 "\n" 19406 "void main()\n" 19407 "{\n" 19408 " vec4 result = gs_fs;\n" 19409 "\n" 19410 "VARIABLE_USE" 19411 "\n" 19412 " fs_out = result;\n" 19413 "}\n" 19414 "\n"; 19415 static const GLchar* gs = "#version 430 core\n" 19416 "#extension GL_ARB_enhanced_layouts : require\n" 19417 "\n" 19418 "layout(points) in;\n" 19419 "layout(triangle_strip, max_vertices = 4) out;\n" 19420 "\n" 19421 "in vec4 tes_gs[];\n" 19422 "out vec4 gs_fs;\n" 19423 "\n" 19424 "void main()\n" 19425 "{\n" 19426 " gs_fs = tes_gs[0];\n" 19427 " gl_Position = vec4(-1, -1, 0, 1);\n" 19428 " EmitVertex();\n" 19429 " gs_fs = tes_gs[0];\n" 19430 " gl_Position = vec4(-1, 1, 0, 1);\n" 19431 " EmitVertex();\n" 19432 " gs_fs = tes_gs[0];\n" 19433 " gl_Position = vec4(1, -1, 0, 1);\n" 19434 " EmitVertex();\n" 19435 " gs_fs = tes_gs[0];\n" 19436 " gl_Position = vec4(1, 1, 0, 1);\n" 19437 " EmitVertex();\n" 19438 "}\n" 19439 "\n"; 19440 static const GLchar* gs_tested = "#version 430 core\n" 19441 "#extension GL_ARB_enhanced_layouts : require\n" 19442 "\n" 19443 "layout(points) in;\n" 19444 "layout(triangle_strip, max_vertices = 4) out;\n" 19445 "\n" 19446 "VAR_DEFINITION" 19447 "\n" 19448 "in vec4 tes_gs[];\n" 19449 "out vec4 gs_fs;\n" 19450 "\n" 19451 "void main()\n" 19452 "{\n" 19453 " vec4 result = tes_gs[0];\n" 19454 "\n" 19455 "VARIABLE_USE" 19456 "\n" 19457 " gs_fs = result;\n" 19458 " gl_Position = vec4(-1, -1, 0, 1);\n" 19459 " EmitVertex();\n" 19460 " gs_fs = result;\n" 19461 " gl_Position = vec4(-1, 1, 0, 1);\n" 19462 " EmitVertex();\n" 19463 " gs_fs = result;\n" 19464 " gl_Position = vec4(1, -1, 0, 1);\n" 19465 " EmitVertex();\n" 19466 " gs_fs = result;\n" 19467 " gl_Position = vec4(1, 1, 0, 1);\n" 19468 " EmitVertex();\n" 19469 "}\n" 19470 "\n"; 19471 static const GLchar* tcs = "#version 430 core\n" 19472 "#extension GL_ARB_enhanced_layouts : require\n" 19473 "\n" 19474 "layout(vertices = 1) out;\n" 19475 "\n" 19476 "in vec4 vs_tcs[];\n" 19477 "out vec4 tcs_tes[];\n" 19478 "\n" 19479 "void main()\n" 19480 "{\n" 19481 "\n" 19482 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 19483 "\n" 19484 " gl_TessLevelOuter[0] = 1.0;\n" 19485 " gl_TessLevelOuter[1] = 1.0;\n" 19486 " gl_TessLevelOuter[2] = 1.0;\n" 19487 " gl_TessLevelOuter[3] = 1.0;\n" 19488 " gl_TessLevelInner[0] = 1.0;\n" 19489 " gl_TessLevelInner[1] = 1.0;\n" 19490 "}\n" 19491 "\n"; 19492 static const GLchar* tcs_tested = "#version 430 core\n" 19493 "#extension GL_ARB_enhanced_layouts : require\n" 19494 "\n" 19495 "layout(vertices = 1) out;\n" 19496 "\n" 19497 "VAR_DEFINITION" 19498 "\n" 19499 "in vec4 vs_tcs[];\n" 19500 "out vec4 tcs_tes[];\n" 19501 "\n" 19502 "void main()\n" 19503 "{\n" 19504 " vec4 result = vs_tcs[gl_InvocationID];\n" 19505 "\n" 19506 "VARIABLE_USE" 19507 "\n" 19508 " tcs_tes[gl_InvocationID] = result;\n" 19509 "\n" 19510 " gl_TessLevelOuter[0] = 1.0;\n" 19511 " gl_TessLevelOuter[1] = 1.0;\n" 19512 " gl_TessLevelOuter[2] = 1.0;\n" 19513 " gl_TessLevelOuter[3] = 1.0;\n" 19514 " gl_TessLevelInner[0] = 1.0;\n" 19515 " gl_TessLevelInner[1] = 1.0;\n" 19516 "}\n" 19517 "\n"; 19518 static const GLchar* tes = "#version 430 core\n" 19519 "#extension GL_ARB_enhanced_layouts : require\n" 19520 "\n" 19521 "layout(isolines, point_mode) in;\n" 19522 "\n" 19523 "in vec4 tcs_tes[];\n" 19524 "out vec4 tes_gs;\n" 19525 "\n" 19526 "void main()\n" 19527 "{\n" 19528 " tes_gs = tcs_tes[0];\n" 19529 "}\n" 19530 "\n"; 19531 static const GLchar* tes_tested = "#version 430 core\n" 19532 "#extension GL_ARB_enhanced_layouts : require\n" 19533 "\n" 19534 "layout(isolines, point_mode) in;\n" 19535 "\n" 19536 "VAR_DEFINITION" 19537 "\n" 19538 "in vec4 tcs_tes[];\n" 19539 "out vec4 tes_gs;\n" 19540 "\n" 19541 "void main()\n" 19542 "{\n" 19543 " vec4 result = tcs_tes[0];\n" 19544 "\n" 19545 "VARIABLE_USE" 19546 "\n" 19547 " tes_gs += result;\n" 19548 "}\n" 19549 "\n"; 19550 static const GLchar* vs = "#version 430 core\n" 19551 "#extension GL_ARB_enhanced_layouts : require\n" 19552 "\n" 19553 "in vec4 in_vs;\n" 19554 "out vec4 vs_tcs;\n" 19555 "\n" 19556 "void main()\n" 19557 "{\n" 19558 " vs_tcs = in_vs;\n" 19559 "}\n" 19560 "\n"; 19561 static const GLchar* vs_tested = "#version 430 core\n" 19562 "#extension GL_ARB_enhanced_layouts : require\n" 19563 "\n" 19564 "VAR_DEFINITION" 19565 "\n" 19566 "in vec4 in_vs;\n" 19567 "out vec4 vs_tcs;\n" 19568 "\n" 19569 "void main()\n" 19570 "{\n" 19571 " vec4 result = in_vs;\n" 19572 "\n" 19573 "VARIABLE_USE" 19574 "\n" 19575 " vs_tcs += result;\n" 19576 "}\n" 19577 "\n"; 19578 19579 std::string source; 19580 testCase& test_case = m_test_cases[test_case_index]; 19581 19582 if (test_case.m_stage == stage) 19583 { 19584 const GLchar* array = ""; 19585 const GLchar* index = ""; 19586 size_t position = 0; 19587 size_t temp; 19588 const GLchar* var_definition = 0; 19589 const GLchar* var_use = input_use; 19590 19591 switch (test_case.m_qualifier) 19592 { 19593 case BUFFER: 19594 var_definition = buffer_var_definition; 19595 break; 19596 case OFFSET: 19597 var_definition = offset_var_definition; 19598 break; 19599 case STRIDE: 19600 var_definition = stride_var_definition; 19601 break; 19602 default: 19603 TCU_FAIL("Invalid enum"); 19604 } 19605 19606 switch (stage) 19607 { 19608 case Utils::Shader::FRAGMENT: 19609 source = fs_tested; 19610 break; 19611 case Utils::Shader::GEOMETRY: 19612 source = gs_tested; 19613 array = "[]"; 19614 index = "[0]"; 19615 break; 19616 case Utils::Shader::TESS_CTRL: 19617 source = tcs_tested; 19618 array = "[]"; 19619 index = "[gl_InvocationID]"; 19620 break; 19621 case Utils::Shader::TESS_EVAL: 19622 source = tes_tested; 19623 array = "[]"; 19624 index = "[0]"; 19625 break; 19626 case Utils::Shader::VERTEX: 19627 source = vs_tested; 19628 break; 19629 default: 19630 TCU_FAIL("Invalid enum"); 19631 } 19632 19633 temp = position; 19634 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 19635 position = temp; 19636 Utils::replaceToken("ARRAY", position, array, source); 19637 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 19638 19639 Utils::replaceAllTokens("INDEX", index, source); 19640 } 19641 else 19642 { 19643 switch (stage) 19644 { 19645 case Utils::Shader::FRAGMENT: 19646 source = fs; 19647 break; 19648 case Utils::Shader::GEOMETRY: 19649 source = gs; 19650 break; 19651 case Utils::Shader::TESS_CTRL: 19652 source = tcs; 19653 break; 19654 case Utils::Shader::TESS_EVAL: 19655 source = tes; 19656 break; 19657 case Utils::Shader::VERTEX: 19658 source = vs; 19659 break; 19660 default: 19661 TCU_FAIL("Invalid enum"); 19662 } 19663 } 19664 19665 return source; 19666 } 19667 19668 /** Get description of test case 19669 * 19670 * @param test_case_index Index of test case 19671 * 19672 * @return Test case description 19673 **/ 19674 std::string XFBInputTest::getTestCaseName(GLuint test_case_index) 19675 { 19676 std::stringstream stream; 19677 testCase& test_case = m_test_cases[test_case_index]; 19678 19679 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: "; 19680 19681 switch (test_case.m_qualifier) 19682 { 19683 case BUFFER: 19684 stream << "xfb_buffer"; 19685 break; 19686 case OFFSET: 19687 stream << "xfb_offset"; 19688 break; 19689 case STRIDE: 19690 stream << "xfb_stride"; 19691 break; 19692 default: 19693 TCU_FAIL("Invalid enum"); 19694 } 19695 19696 return stream.str(); 19697 } 19698 19699 /** Get number of test cases 19700 * 19701 * @return Number of test cases 19702 **/ 19703 GLuint XFBInputTest::getTestCaseNumber() 19704 { 19705 return static_cast<GLuint>(m_test_cases.size()); 19706 } 19707 19708 /** Selects if "compute" stage is relevant for test 19709 * 19710 * @param ignored 19711 * 19712 * @return false 19713 **/ 19714 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */) 19715 { 19716 return false; 19717 } 19718 19719 /** Prepare all test cases 19720 * 19721 **/ 19722 void XFBInputTest::testInit() 19723 { 19724 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier) 19725 { 19726 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 19727 { 19728 if (Utils::Shader::COMPUTE == stage) 19729 { 19730 continue; 19731 } 19732 19733 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage }; 19734 19735 m_test_cases.push_back(test_case); 19736 } 19737 } 19738 } 19739 19740 /* Constants used by XFBAllStagesTest */ 19741 const GLuint XFBAllStagesTest::m_gs_index = 3; 19742 19743 /** Constructor 19744 * 19745 * @param context Test context 19746 **/ 19747 XFBAllStagesTest::XFBAllStagesTest(deqp::Context& context) 19748 : BufferTestBase(context, "xfb_all_stages", 19749 "Test verifies that only last stage in vertex processing can output to transform feedback") 19750 { 19751 /* Nothing to be done here */ 19752 } 19753 19754 /** Get descriptors of buffers necessary for test 19755 * 19756 * @param ignored 19757 * @param out_descriptors Descriptors of buffers used by test 19758 **/ 19759 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 19760 bufferDescriptor::Vector& out_descriptors) 19761 { 19762 static const GLuint n_stages = 4; 19763 const Utils::Type& vec4 = Utils::Type::vec4; 19764 19765 /* Data */ 19766 tcu::Vec4 sum; 19767 19768 /* Test uses single uniform and xfb per stage + uniform for fragment shader */ 19769 out_descriptors.resize(n_stages * 2 + 1); 19770 19771 /* */ 19772 for (GLuint i = 0; i < n_stages; ++i) 19773 { 19774 /* Get references */ 19775 bufferDescriptor& uniform = out_descriptors[i + 0]; 19776 bufferDescriptor& xfb = out_descriptors[i + n_stages]; 19777 19778 /* Index */ 19779 uniform.m_index = i; 19780 xfb.m_index = i; 19781 19782 /* Target */ 19783 uniform.m_target = Utils::Buffer::Uniform; 19784 xfb.m_target = Utils::Buffer::Transform_feedback; 19785 19786 /* Data */ 19787 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat()); 19788 19789 sum += var; 19790 19791 uniform.m_initial_data.resize(vec4.GetSize()); 19792 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize()); 19793 19794 xfb.m_initial_data = vec4.GenerateDataPacked(); 19795 19796 if (m_gs_index != i) 19797 { 19798 xfb.m_expected_data = xfb.m_initial_data; 19799 } 19800 else 19801 { 19802 xfb.m_expected_data.resize(vec4.GetSize()); 19803 memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize()); 19804 } 19805 } 19806 19807 /* FS */ 19808 { 19809 /* Get reference */ 19810 bufferDescriptor& uniform = out_descriptors[n_stages * 2]; 19811 19812 /* Index */ 19813 uniform.m_index = n_stages; 19814 19815 /* Target */ 19816 uniform.m_target = Utils::Buffer::Uniform; 19817 19818 /* Data */ 19819 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat()); 19820 19821 uniform.m_initial_data.resize(vec4.GetSize()); 19822 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize()); 19823 } 19824 } 19825 19826 /** Get body of main function for given shader stage 19827 * 19828 * @param ignored 19829 * @param stage Shader stage 19830 * @param out_assignments Set to empty 19831 * @param out_calculations Set to empty 19832 **/ 19833 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage, 19834 std::string& out_assignments, std::string& out_calculations) 19835 { 19836 out_calculations = ""; 19837 19838 static const GLchar* vs = " vs_tcs = uni_vs;\n"; 19839 static const GLchar* tcs = " tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n"; 19840 static const GLchar* tes = " tes_gs = uni_tes + tcs_tes[0];\n"; 19841 static const GLchar* gs = " gs_fs = uni_gs + tes_gs[0];\n"; 19842 static const GLchar* fs = " fs_out = uni_fs + gs_fs;\n"; 19843 19844 const GLchar* assignments = 0; 19845 switch (stage) 19846 { 19847 case Utils::Shader::FRAGMENT: 19848 assignments = fs; 19849 break; 19850 case Utils::Shader::GEOMETRY: 19851 assignments = gs; 19852 break; 19853 case Utils::Shader::TESS_CTRL: 19854 assignments = tcs; 19855 break; 19856 case Utils::Shader::TESS_EVAL: 19857 assignments = tes; 19858 break; 19859 case Utils::Shader::VERTEX: 19860 assignments = vs; 19861 break; 19862 default: 19863 TCU_FAIL("Invalid enum"); 19864 } 19865 19866 out_assignments = assignments; 19867 } 19868 19869 /** Get interface of shader 19870 * 19871 * @param ignored 19872 * @param stage Shader stage 19873 * @param out_interface Set to "" 19874 **/ 19875 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage, 19876 std::string& out_interface) 19877 { 19878 static const GLchar* vs = "layout(xfb_buffer = 0, xfb_offset = 0) out vec4 vs_tcs;\n" 19879 "layout(binding = 0) uniform vs_block {\n" 19880 " vec4 uni_vs;\n" 19881 "};\n"; 19882 static const GLchar* tcs = " in vec4 vs_tcs[];\n" 19883 "layout(xfb_buffer = 1, xfb_offset = 0) out vec4 tcs_tes[1];\n" 19884 "layout(binding = 1) uniform tcs_block {\n" 19885 " vec4 uni_tcs;\n" 19886 "};\n"; 19887 static const GLchar* tes = " in vec4 tcs_tes[];\n" 19888 "layout(xfb_buffer = 2, xfb_offset = 0) out vec4 tes_gs;\n" 19889 "layout(binding = 2) uniform tes_block {\n" 19890 " vec4 uni_tes;\n" 19891 "};\n"; 19892 static const GLchar* gs = " in vec4 tes_gs[];\n" 19893 "layout(xfb_buffer = 3, xfb_offset = 0) out vec4 gs_fs;\n" 19894 "layout(binding = 3) uniform gs_block {\n" 19895 " vec4 uni_gs;\n" 19896 "};\n"; 19897 static const GLchar* fs = " in vec4 gs_fs;\n" 19898 " out vec4 fs_out;\n" 19899 "layout(binding = 4) uniform fs_block {\n" 19900 " vec4 uni_fs;\n" 19901 "};\n"; 19902 19903 const GLchar* interface = 0; 19904 switch (stage) 19905 { 19906 case Utils::Shader::FRAGMENT: 19907 interface = fs; 19908 break; 19909 case Utils::Shader::GEOMETRY: 19910 interface = gs; 19911 break; 19912 case Utils::Shader::TESS_CTRL: 19913 interface = tcs; 19914 break; 19915 case Utils::Shader::TESS_EVAL: 19916 interface = tes; 19917 break; 19918 case Utils::Shader::VERTEX: 19919 interface = vs; 19920 break; 19921 default: 19922 TCU_FAIL("Invalid enum"); 19923 } 19924 19925 out_interface = interface; 19926 } 19927 19928 /* Constants used by XFBStrideOfEmptyListTest */ 19929 const GLuint XFBStrideOfEmptyListTest::m_stride = 64; 19930 19931 /** Constructor 19932 * 19933 * @param context Test context 19934 **/ 19935 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context& context) 19936 : BufferTestBase(context, "xfb_stride_of_empty_list", 19937 "Test verifies that xfb_stride qualifier is respected when no xfb_offset is specified") 19938 { 19939 /* Nothing to be done here */ 19940 } 19941 19942 /** Execute drawArrays for single vertex 19943 * 19944 * @param test_case_index Index of test case 19945 * 19946 * @return true if proper error is reported 19947 **/ 19948 bool XFBStrideOfEmptyListTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 19949 { 19950 const Functions& gl = m_context.getRenderContext().getFunctions(); 19951 bool result = true; 19952 19953 /* Draw */ 19954 gl.disable(GL_RASTERIZER_DISCARD); 19955 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 19956 19957 gl.beginTransformFeedback(GL_POINTS); 19958 GLenum error = gl.getError(); 19959 switch (test_case_index) 19960 { 19961 case VALID: 19962 if (GL_NO_ERROR != error) 19963 { 19964 gl.endTransformFeedback(); 19965 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback"); 19966 } 19967 19968 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 19969 error = gl.getError(); 19970 19971 gl.endTransformFeedback(); 19972 GLU_EXPECT_NO_ERROR(error, "DrawArrays"); 19973 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 19974 19975 break; 19976 19977 case FIRST_MISSING: 19978 if (GL_NO_ERROR == error) 19979 { 19980 gl.endTransformFeedback(); 19981 } 19982 19983 if (GL_INVALID_OPERATION != error) 19984 { 19985 m_context.getTestContext().getLog() 19986 << tcu::TestLog::Message << "XFB at index 0, that is written by GS, is missing. It was expected that " 19987 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: " 19988 << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 19989 19990 result = false; 19991 } 19992 19993 break; 19994 19995 case SECOND_MISSING: 19996 if (GL_NO_ERROR == error) 19997 { 19998 gl.endTransformFeedback(); 19999 } 20000 20001 if (GL_INVALID_OPERATION != error) 20002 { 20003 m_context.getTestContext().getLog() 20004 << tcu::TestLog::Message << "XFB at index 1, that is declared as empty, is missing. It was expected " 20005 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: " 20006 << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 20007 20008 result = false; 20009 } 20010 20011 break; 20012 } 20013 20014 /* Done */ 20015 return result; 20016 } 20017 20018 /** Get descriptors of buffers necessary for test 20019 * 20020 * @param test_case_index Index of test case 20021 * @param out_descriptors Descriptors of buffers used by test 20022 **/ 20023 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint test_case_index, 20024 bufferDescriptor::Vector& out_descriptors) 20025 { 20026 switch (test_case_index) 20027 { 20028 case VALID: 20029 { 20030 /* Test needs single uniform and two xfbs */ 20031 out_descriptors.resize(3); 20032 20033 /* Get references */ 20034 bufferDescriptor& uniform = out_descriptors[0]; 20035 bufferDescriptor& xfb_0 = out_descriptors[1]; 20036 bufferDescriptor& xfb_1 = out_descriptors[2]; 20037 20038 /* Index */ 20039 uniform.m_index = 0; 20040 xfb_0.m_index = 0; 20041 xfb_1.m_index = 1; 20042 20043 /* Target */ 20044 uniform.m_target = Utils::Buffer::Uniform; 20045 xfb_0.m_target = Utils::Buffer::Transform_feedback; 20046 xfb_1.m_target = Utils::Buffer::Transform_feedback; 20047 20048 /* Data */ 20049 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20050 20051 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20052 xfb_0.m_expected_data = uniform.m_initial_data; 20053 20054 /* Data, contents are the same as no modification is expected */ 20055 xfb_1.m_initial_data.resize(m_stride); 20056 xfb_1.m_expected_data.resize(m_stride); 20057 20058 for (GLuint i = 0; i < m_stride; ++i) 20059 { 20060 xfb_1.m_initial_data[0] = (glw::GLubyte)i; 20061 xfb_1.m_expected_data[0] = (glw::GLubyte)i; 20062 } 20063 } 20064 20065 break; 20066 20067 case FIRST_MISSING: 20068 { 20069 /* Test needs single uniform and two xfbs */ 20070 out_descriptors.resize(2); 20071 20072 /* Get references */ 20073 bufferDescriptor& uniform = out_descriptors[0]; 20074 bufferDescriptor& xfb_1 = out_descriptors[1]; 20075 20076 /* Index */ 20077 uniform.m_index = 0; 20078 xfb_1.m_index = 1; 20079 20080 /* Target */ 20081 uniform.m_target = Utils::Buffer::Uniform; 20082 xfb_1.m_target = Utils::Buffer::Transform_feedback; 20083 20084 /* Data */ 20085 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20086 20087 /* Draw call will not be executed, contents does not matter */ 20088 xfb_1.m_initial_data.resize(m_stride); 20089 } 20090 20091 break; 20092 20093 case SECOND_MISSING: 20094 { 20095 /* Test needs single uniform and two xfbs */ 20096 out_descriptors.resize(2); 20097 20098 /* Get references */ 20099 bufferDescriptor& uniform = out_descriptors[0]; 20100 bufferDescriptor& xfb_0 = out_descriptors[1]; 20101 20102 /* Index */ 20103 uniform.m_index = 0; 20104 xfb_0.m_index = 0; 20105 20106 /* Target */ 20107 uniform.m_target = Utils::Buffer::Uniform; 20108 xfb_0.m_target = Utils::Buffer::Transform_feedback; 20109 20110 /* Data */ 20111 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20112 20113 /* Draw call will not be executed, contents does not matter */ 20114 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20115 } 20116 20117 break; 20118 } 20119 } 20120 20121 /** Get body of main function for given shader stage 20122 * 20123 * @param ignored 20124 * @param stage Shader stage 20125 * @param out_assignments Set to empty 20126 * @param out_calculations Set to empty 20127 **/ 20128 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 20129 std::string& out_assignments, std::string& out_calculations) 20130 { 20131 out_calculations = ""; 20132 20133 static const GLchar* gs = " gs_fs = uni_gs;\n"; 20134 static const GLchar* fs = " fs_out = vec4(gs_fs);\n"; 20135 20136 const GLchar* assignments = ""; 20137 switch (stage) 20138 { 20139 case Utils::Shader::FRAGMENT: 20140 assignments = fs; 20141 break; 20142 case Utils::Shader::GEOMETRY: 20143 assignments = gs; 20144 break; 20145 default: 20146 break; 20147 } 20148 20149 out_assignments = assignments; 20150 } 20151 20152 /** Get interface of shader 20153 * 20154 * @param ignored 20155 * @param stage Shader stage 20156 * @param out_interface Set to "" 20157 **/ 20158 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 20159 std::string& out_interface) 20160 { 20161 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 gs_fs;\n" 20162 "layout (xfb_buffer = 1, xfb_stride = 64) out;\n" 20163 "\n" 20164 "layout (binding = 0) uniform gs_block {\n" 20165 " vec4 uni_gs;\n" 20166 "};\n"; 20167 static const GLchar* fs = "in vec4 gs_fs;\n" 20168 "out vec4 fs_out;\n"; 20169 20170 switch (stage) 20171 { 20172 case Utils::Shader::FRAGMENT: 20173 out_interface = fs; 20174 break; 20175 case Utils::Shader::GEOMETRY: 20176 out_interface = gs; 20177 break; 20178 default: 20179 out_interface = ""; 20180 return; 20181 } 20182 } 20183 20184 /** Returns buffer details in human readable form. 20185 * 20186 * @param test_case_index Index of test case 20187 * 20188 * @return Case description 20189 **/ 20190 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index) 20191 { 20192 std::string result; 20193 20194 switch (test_case_index) 20195 { 20196 case VALID: 20197 result = "Valid case"; 20198 break; 20199 case FIRST_MISSING: 20200 result = "Missing xfb at index 0"; 20201 break; 20202 case SECOND_MISSING: 20203 result = "Missing xfb at index 1"; 20204 break; 20205 default: 20206 TCU_FAIL("Invalid enum"); 20207 } 20208 20209 return result; 20210 } 20211 20212 /** Get number of test cases 20213 * 20214 * @return 3 20215 **/ 20216 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber() 20217 { 20218 return 3; 20219 } 20220 20221 /* Constants used by XFBStrideOfEmptyListTest */ 20222 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64; 20223 20224 /** Constructor 20225 * 20226 * @param context Test context 20227 **/ 20228 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context& context) 20229 : BufferTestBase(context, "xfb_stride_of_empty_list_and_api", 20230 "Test verifies that xfb_stride qualifier is not overriden by API") 20231 { 20232 /* Nothing to be done here */ 20233 } 20234 20235 /** Execute drawArrays for single vertex 20236 * 20237 * @param test_case_index Index of test case 20238 * 20239 * @return true if proper error is reported 20240 **/ 20241 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 20242 { 20243 const Functions& gl = m_context.getRenderContext().getFunctions(); 20244 bool result = true; 20245 20246 /* Draw */ 20247 gl.disable(GL_RASTERIZER_DISCARD); 20248 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 20249 20250 gl.beginTransformFeedback(GL_POINTS); 20251 GLenum error = gl.getError(); 20252 switch (test_case_index) 20253 { 20254 case VALID: 20255 if (GL_NO_ERROR != error) 20256 { 20257 gl.endTransformFeedback(); 20258 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback"); 20259 } 20260 20261 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 20262 error = gl.getError(); 20263 20264 gl.endTransformFeedback(); 20265 GLU_EXPECT_NO_ERROR(error, "DrawArrays"); 20266 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 20267 20268 break; 20269 20270 case FIRST_MISSING: 20271 if (GL_NO_ERROR == error) 20272 { 20273 gl.endTransformFeedback(); 20274 } 20275 20276 if (GL_INVALID_OPERATION != error) 20277 { 20278 m_context.getTestContext().getLog() 20279 << tcu::TestLog::Message << "XFB at index 0, that is declared as empty, is missing. It was expected " 20280 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: " 20281 << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 20282 20283 result = false; 20284 } 20285 20286 break; 20287 20288 case SECOND_MISSING: 20289 if (GL_NO_ERROR == error) 20290 { 20291 gl.endTransformFeedback(); 20292 } 20293 20294 if (GL_INVALID_OPERATION != error) 20295 { 20296 m_context.getTestContext().getLog() 20297 << tcu::TestLog::Message << "XFB at index 1, that is written by GS, is missing. It was expected that " 20298 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: " 20299 << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 20300 20301 result = false; 20302 } 20303 20304 break; 20305 } 20306 20307 /* Done */ 20308 return result; 20309 } 20310 20311 /** Get descriptors of buffers necessary for test 20312 * 20313 * @param test_case_index Index of test case 20314 * @param out_descriptors Descriptors of buffers used by test 20315 **/ 20316 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint test_case_index, 20317 bufferDescriptor::Vector& out_descriptors) 20318 { 20319 switch (test_case_index) 20320 { 20321 case VALID: 20322 { 20323 /* Test needs single uniform and two xfbs */ 20324 out_descriptors.resize(3); 20325 20326 /* Get references */ 20327 bufferDescriptor& uniform = out_descriptors[0]; 20328 bufferDescriptor& xfb_0 = out_descriptors[1]; 20329 bufferDescriptor& xfb_1 = out_descriptors[2]; 20330 20331 /* Index */ 20332 uniform.m_index = 0; 20333 xfb_0.m_index = 0; 20334 xfb_1.m_index = 1; 20335 20336 /* Target */ 20337 uniform.m_target = Utils::Buffer::Uniform; 20338 xfb_0.m_target = Utils::Buffer::Transform_feedback; 20339 xfb_1.m_target = Utils::Buffer::Transform_feedback; 20340 20341 /* Data */ 20342 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20343 20344 /* Data, contents are the same as no modification is expected */ 20345 xfb_0.m_initial_data.resize(m_stride); 20346 xfb_0.m_expected_data.resize(m_stride); 20347 20348 for (GLuint i = 0; i < m_stride; ++i) 20349 { 20350 xfb_0.m_initial_data[0] = (glw::GLubyte)i; 20351 xfb_0.m_expected_data[0] = (glw::GLubyte)i; 20352 } 20353 20354 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20355 xfb_1.m_expected_data = uniform.m_initial_data; 20356 } 20357 20358 break; 20359 20360 case FIRST_MISSING: 20361 { 20362 /* Test needs single uniform and two xfbs */ 20363 out_descriptors.resize(2); 20364 20365 /* Get references */ 20366 bufferDescriptor& uniform = out_descriptors[0]; 20367 bufferDescriptor& xfb_1 = out_descriptors[1]; 20368 20369 /* Index */ 20370 uniform.m_index = 0; 20371 xfb_1.m_index = 1; 20372 20373 /* Target */ 20374 uniform.m_target = Utils::Buffer::Uniform; 20375 xfb_1.m_target = Utils::Buffer::Transform_feedback; 20376 20377 /* Data */ 20378 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20379 20380 /* Draw call will not be executed, contents does not matter */ 20381 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20382 } 20383 20384 break; 20385 20386 case SECOND_MISSING: 20387 { 20388 /* Test needs single uniform and two xfbs */ 20389 out_descriptors.resize(2); 20390 20391 /* Get references */ 20392 bufferDescriptor& uniform = out_descriptors[0]; 20393 bufferDescriptor& xfb_0 = out_descriptors[1]; 20394 20395 /* Index */ 20396 uniform.m_index = 0; 20397 xfb_0.m_index = 0; 20398 20399 /* Target */ 20400 uniform.m_target = Utils::Buffer::Uniform; 20401 xfb_0.m_target = Utils::Buffer::Transform_feedback; 20402 20403 /* Data */ 20404 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked(); 20405 20406 /* Draw call will not be executed, contents does not matter */ 20407 xfb_0.m_initial_data.resize(m_stride); 20408 } 20409 20410 break; 20411 } 20412 } 20413 20414 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings 20415 * 20416 * @param ignored 20417 * @param captured_varyings Vector of varying names to be captured 20418 **/ 20419 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */, 20420 Utils::Program::NameVector& captured_varyings) 20421 { 20422 captured_varyings.push_back("gs_fs"); 20423 } 20424 20425 /** Get body of main function for given shader stage 20426 * 20427 * @param ignored 20428 * @param stage Shader stage 20429 * @param out_assignments Set to empty 20430 * @param out_calculations Set to empty 20431 **/ 20432 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 20433 std::string& out_assignments, std::string& out_calculations) 20434 { 20435 out_calculations = ""; 20436 20437 static const GLchar* gs = " gs_fs = uni_gs;\n"; 20438 static const GLchar* fs = " fs_out = vec4(gs_fs);\n"; 20439 20440 const GLchar* assignments = ""; 20441 switch (stage) 20442 { 20443 case Utils::Shader::FRAGMENT: 20444 assignments = fs; 20445 break; 20446 case Utils::Shader::GEOMETRY: 20447 assignments = gs; 20448 break; 20449 default: 20450 break; 20451 } 20452 20453 out_assignments = assignments; 20454 } 20455 20456 /** Get interface of shader 20457 * 20458 * @param ignored 20459 * @param stage Shader stage 20460 * @param out_interface Set to "" 20461 **/ 20462 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 20463 std::string& out_interface) 20464 { 20465 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_stride = 64) out;\n" 20466 "layout (xfb_buffer = 1, xfb_offset = 0) out vec4 gs_fs;\n" 20467 "\n" 20468 "layout(binding = 0) uniform gs_block {\n" 20469 " vec4 uni_gs;\n" 20470 "};\n"; 20471 static const GLchar* fs = "in vec4 gs_fs;\n" 20472 "out vec4 fs_out;\n"; 20473 20474 switch (stage) 20475 { 20476 case Utils::Shader::FRAGMENT: 20477 out_interface = fs; 20478 break; 20479 case Utils::Shader::GEOMETRY: 20480 out_interface = gs; 20481 break; 20482 default: 20483 out_interface = ""; 20484 return; 20485 } 20486 } 20487 20488 /** Returns buffer details in human readable form. 20489 * 20490 * @param test_case_index Index of test case 20491 * 20492 * @return Case description 20493 **/ 20494 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index) 20495 { 20496 std::string result; 20497 20498 switch (test_case_index) 20499 { 20500 case VALID: 20501 result = "Valid case"; 20502 break; 20503 case FIRST_MISSING: 20504 result = "Missing xfb at index 0"; 20505 break; 20506 case SECOND_MISSING: 20507 result = "Missing xfb at index 1"; 20508 break; 20509 default: 20510 TCU_FAIL("Invalid enum"); 20511 } 20512 20513 return result; 20514 } 20515 20516 /** Get number of test cases 20517 * 20518 * @return 2 20519 **/ 20520 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber() 20521 { 20522 return 3; 20523 } 20524 20525 /** Constructor 20526 * 20527 * @param context Test framework context 20528 **/ 20529 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context& context) 20530 : NegativeTestBase(context, "xfb_too_small_stride", 20531 "Test verifies that compiler reports error when xfb_stride sets not enough space") 20532 { 20533 } 20534 20535 /** Source for given test case and stage 20536 * 20537 * @param test_case_index Index of test case 20538 * @param stage Shader stage 20539 * 20540 * @return Shader source 20541 **/ 20542 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 20543 { 20544 static const GLchar* array_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n" 20545 "\n" 20546 "layout (xfb_offset = 16) out vec4 gohanARRAY[4];\n"; 20547 static const GLchar* block_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n" 20548 "\n" 20549 "layout (xfb_offset = 0) out Goku {\n" 20550 " vec4 gohan;\n" 20551 " vec4 goten;\n" 20552 " vec4 chichi;\n" 20553 "} gokuARRAY;\n"; 20554 static const GLchar* offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n" 20555 "\n" 20556 "layout (xfb_offset = 32) out vec4 gohanARRAY;\n"; 20557 // 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;" 20558 // To make the shader failed to compile, change xfb_stride to a value that is smaller than 32 20559 static const GLchar* stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n" 20560 "\n" 20561 "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohanARRAY;\n"; 20562 static const GLchar* array_use = " gohanINDEX[0] = result / 2;\n" 20563 " gohanINDEX[1] = result / 4;\n" 20564 " gohanINDEX[2] = result / 6;\n" 20565 " gohanINDEX[3] = result / 8;\n"; 20566 static const GLchar* block_use = " gokuINDEX.gohan = result / 2;\n" 20567 " gokuINDEX.goten = result / 4;\n" 20568 " gokuINDEX.chichi = result / 6;\n"; 20569 static const GLchar* output_use = "gohanINDEX = result / 4;\n"; 20570 static const GLchar* fs = "#version 430 core\n" 20571 "#extension GL_ARB_enhanced_layouts : require\n" 20572 "\n" 20573 "in vec4 gs_fs;\n" 20574 "out vec4 fs_out;\n" 20575 "\n" 20576 "void main()\n" 20577 "{\n" 20578 " fs_out = gs_fs;\n" 20579 "}\n" 20580 "\n"; 20581 static const GLchar* gs_tested = "#version 430 core\n" 20582 "#extension GL_ARB_enhanced_layouts : require\n" 20583 "\n" 20584 "layout(points) in;\n" 20585 "layout(triangle_strip, max_vertices = 4) out;\n" 20586 "\n" 20587 "VAR_DEFINITION" 20588 "\n" 20589 "in vec4 tes_gs[];\n" 20590 "out vec4 gs_fs;\n" 20591 "\n" 20592 "void main()\n" 20593 "{\n" 20594 " vec4 result = tes_gs[0];\n" 20595 "\n" 20596 "VARIABLE_USE" 20597 "\n" 20598 " gs_fs = result;\n" 20599 " gl_Position = vec4(-1, -1, 0, 1);\n" 20600 " EmitVertex();\n" 20601 " gs_fs = result;\n" 20602 " gl_Position = vec4(-1, 1, 0, 1);\n" 20603 " EmitVertex();\n" 20604 " gs_fs = result;\n" 20605 " gl_Position = vec4(1, -1, 0, 1);\n" 20606 " EmitVertex();\n" 20607 " gs_fs = result;\n" 20608 " gl_Position = vec4(1, 1, 0, 1);\n" 20609 " EmitVertex();\n" 20610 "}\n" 20611 "\n"; 20612 static const GLchar* tcs = "#version 430 core\n" 20613 "#extension GL_ARB_enhanced_layouts : require\n" 20614 "\n" 20615 "layout(vertices = 1) out;\n" 20616 "\n" 20617 "in vec4 vs_tcs[];\n" 20618 "out vec4 tcs_tes[];\n" 20619 "\n" 20620 "void main()\n" 20621 "{\n" 20622 "\n" 20623 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 20624 "\n" 20625 " gl_TessLevelOuter[0] = 1.0;\n" 20626 " gl_TessLevelOuter[1] = 1.0;\n" 20627 " gl_TessLevelOuter[2] = 1.0;\n" 20628 " gl_TessLevelOuter[3] = 1.0;\n" 20629 " gl_TessLevelInner[0] = 1.0;\n" 20630 " gl_TessLevelInner[1] = 1.0;\n" 20631 "}\n" 20632 "\n"; 20633 static const GLchar* tcs_tested = "#version 430 core\n" 20634 "#extension GL_ARB_enhanced_layouts : require\n" 20635 "\n" 20636 "layout(vertices = 1) out;\n" 20637 "\n" 20638 "VAR_DEFINITION" 20639 "\n" 20640 "in vec4 vs_tcs[];\n" 20641 "out vec4 tcs_tes[];\n" 20642 "\n" 20643 "void main()\n" 20644 "{\n" 20645 " vec4 result = vs_tcs[gl_InvocationID];\n" 20646 "\n" 20647 "VARIABLE_USE" 20648 "\n" 20649 " tcs_tes[gl_InvocationID] = result;\n" 20650 "\n" 20651 " gl_TessLevelOuter[0] = 1.0;\n" 20652 " gl_TessLevelOuter[1] = 1.0;\n" 20653 " gl_TessLevelOuter[2] = 1.0;\n" 20654 " gl_TessLevelOuter[3] = 1.0;\n" 20655 " gl_TessLevelInner[0] = 1.0;\n" 20656 " gl_TessLevelInner[1] = 1.0;\n" 20657 "}\n" 20658 "\n"; 20659 static const GLchar* tes_tested = "#version 430 core\n" 20660 "#extension GL_ARB_enhanced_layouts : require\n" 20661 "\n" 20662 "layout(isolines, point_mode) in;\n" 20663 "\n" 20664 "VAR_DEFINITION" 20665 "\n" 20666 "in vec4 tcs_tes[];\n" 20667 "out vec4 tes_gs;\n" 20668 "\n" 20669 "void main()\n" 20670 "{\n" 20671 " vec4 result = tcs_tes[0];\n" 20672 "\n" 20673 "VARIABLE_USE" 20674 "\n" 20675 " tes_gs += result;\n" 20676 "}\n" 20677 "\n"; 20678 static const GLchar* vs = "#version 430 core\n" 20679 "#extension GL_ARB_enhanced_layouts : require\n" 20680 "\n" 20681 "in vec4 in_vs;\n" 20682 "out vec4 vs_tcs;\n" 20683 "\n" 20684 "void main()\n" 20685 "{\n" 20686 " vs_tcs = in_vs;\n" 20687 "}\n" 20688 "\n"; 20689 static const GLchar* vs_tested = "#version 430 core\n" 20690 "#extension GL_ARB_enhanced_layouts : require\n" 20691 "\n" 20692 "VAR_DEFINITION" 20693 "\n" 20694 "in vec4 in_vs;\n" 20695 "out vec4 vs_tcs;\n" 20696 "\n" 20697 "void main()\n" 20698 "{\n" 20699 " vec4 result = in_vs;\n" 20700 "\n" 20701 "VARIABLE_USE" 20702 "\n" 20703 " vs_tcs += result;\n" 20704 "}\n" 20705 "\n"; 20706 20707 std::string source; 20708 testCase& test_case = m_test_cases[test_case_index]; 20709 20710 if (test_case.m_stage == stage) 20711 { 20712 const GLchar* array = ""; 20713 const GLchar* index = ""; 20714 size_t position = 0; 20715 size_t temp; 20716 const GLchar* var_definition = 0; 20717 const GLchar* var_use = 0; 20718 20719 switch (test_case.m_case) 20720 { 20721 case OFFSET: 20722 var_definition = offset_var_definition; 20723 var_use = output_use; 20724 break; 20725 case STRIDE: 20726 var_definition = stride_var_definition; 20727 var_use = output_use; 20728 break; 20729 case BLOCK: 20730 var_definition = block_var_definition; 20731 var_use = block_use; 20732 break; 20733 case ARRAY: 20734 var_definition = array_var_definition; 20735 var_use = array_use; 20736 break; 20737 default: 20738 TCU_FAIL("Invalid enum"); 20739 } 20740 20741 switch (stage) 20742 { 20743 case Utils::Shader::GEOMETRY: 20744 source = gs_tested; 20745 array = "[]"; 20746 index = "[0]"; 20747 break; 20748 case Utils::Shader::TESS_CTRL: 20749 source = tcs_tested; 20750 array = "[]"; 20751 index = "[gl_InvocationID]"; 20752 break; 20753 case Utils::Shader::TESS_EVAL: 20754 source = tes_tested; 20755 array = "[]"; 20756 index = "[0]"; 20757 break; 20758 case Utils::Shader::VERTEX: 20759 source = vs_tested; 20760 break; 20761 default: 20762 TCU_FAIL("Invalid enum"); 20763 } 20764 20765 temp = position; 20766 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 20767 position = temp; 20768 Utils::replaceToken("ARRAY", position, array, source); 20769 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 20770 20771 Utils::replaceAllTokens("INDEX", index, source); 20772 } 20773 else 20774 { 20775 switch (test_case.m_stage) 20776 { 20777 case Utils::Shader::GEOMETRY: 20778 switch (stage) 20779 { 20780 case Utils::Shader::FRAGMENT: 20781 source = fs; 20782 break; 20783 case Utils::Shader::VERTEX: 20784 source = vs; 20785 break; 20786 default: 20787 source = ""; 20788 } 20789 break; 20790 case Utils::Shader::TESS_CTRL: 20791 switch (stage) 20792 { 20793 case Utils::Shader::FRAGMENT: 20794 source = fs; 20795 break; 20796 case Utils::Shader::VERTEX: 20797 source = vs; 20798 break; 20799 default: 20800 source = ""; 20801 } 20802 break; 20803 case Utils::Shader::TESS_EVAL: 20804 switch (stage) 20805 { 20806 case Utils::Shader::FRAGMENT: 20807 source = fs; 20808 break; 20809 case Utils::Shader::TESS_CTRL: 20810 source = tcs; 20811 break; 20812 case Utils::Shader::VERTEX: 20813 source = vs; 20814 break; 20815 default: 20816 source = ""; 20817 } 20818 break; 20819 case Utils::Shader::VERTEX: 20820 switch (stage) 20821 { 20822 case Utils::Shader::FRAGMENT: 20823 source = fs; 20824 break; 20825 default: 20826 source = ""; 20827 } 20828 break; 20829 default: 20830 TCU_FAIL("Invalid enum"); 20831 break; 20832 } 20833 } 20834 20835 return source; 20836 } 20837 20838 /** Get description of test case 20839 * 20840 * @param test_case_index Index of test case 20841 * 20842 * @return Test case description 20843 **/ 20844 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index) 20845 { 20846 std::stringstream stream; 20847 testCase& test_case = m_test_cases[test_case_index]; 20848 20849 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: "; 20850 20851 switch (test_case.m_case) 20852 { 20853 case OFFSET: 20854 stream << "buffer stride: 40, vec4 offset: 32"; 20855 break; 20856 case STRIDE: 20857 stream << "buffer stride: 32, vec4 off 16 stride: 32"; 20858 break; 20859 case BLOCK: 20860 stream << "buffer stride: 32, block 3xvec4 offset 0"; 20861 break; 20862 case ARRAY: 20863 stream << "buffer stride: 32, vec4[4] offset 16"; 20864 break; 20865 default: 20866 TCU_FAIL("Invalid enum"); 20867 } 20868 20869 return stream.str(); 20870 } 20871 20872 /** Get number of test cases 20873 * 20874 * @return Number of test cases 20875 **/ 20876 GLuint XFBTooSmallStrideTest::getTestCaseNumber() 20877 { 20878 return static_cast<GLuint>(m_test_cases.size()); 20879 } 20880 20881 /** Selects if "compute" stage is relevant for test 20882 * 20883 * @param ignored 20884 * 20885 * @return false 20886 **/ 20887 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */) 20888 { 20889 return false; 20890 } 20891 20892 /** Prepare all test cases 20893 * 20894 **/ 20895 void XFBTooSmallStrideTest::testInit() 20896 { 20897 for (GLuint c = 0; c < CASE_MAX; ++c) 20898 { 20899 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 20900 { 20901 /* 20902 It is invalid to define transform feedback output in TCS, according to spec: 20903 The data captured in transform feedback mode depends on the active programs on each of the shader stages. 20904 If a program is active for the geometry shader stage, transform feedback captures the vertices of each 20905 primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation 20906 shader stage, transform feedback captures each primitive produced by the tessellation primitive generator, 20907 whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures 20908 each primitive processed by the vertex shader. 20909 */ 20910 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 20911 (Utils::Shader::FRAGMENT == stage)) 20912 { 20913 continue; 20914 } 20915 20916 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage }; 20917 20918 m_test_cases.push_back(test_case); 20919 } 20920 } 20921 } 20922 20923 /** Constructor 20924 * 20925 * @param context Test framework context 20926 **/ 20927 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context& context) 20928 : NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected") 20929 { 20930 } 20931 20932 /** Source for given test case and stage 20933 * 20934 * @param test_case_index Index of test case 20935 * @param stage Shader stage 20936 * 20937 * @return Shader source 20938 **/ 20939 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 20940 { 20941 static const GLchar* invalid_var_definition = 20942 "const uint type_size = SIZE;\n" 20943 "\n" 20944 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n" 20945 "layout (xfb_offset = type_size) out TYPE vegetaARRAY;\n"; 20946 static const GLchar* valid_var_definition = 20947 "const uint type_size = SIZE;\n" 20948 "\n" 20949 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n"; 20950 static const GLchar* invalid_use = " gokuINDEX = TYPE(1);\n" 20951 " vegetaINDEX = TYPE(0);\n" 20952 " if (vec4(0) == result)\n" 20953 " {\n" 20954 " gokuINDEX = TYPE(0);\n" 20955 " vegetaINDEX = TYPE(1);\n" 20956 " }\n"; 20957 static const GLchar* valid_use = " gokuINDEX = TYPE(1);\n" 20958 " if (vec4(0) == result)\n" 20959 " {\n" 20960 " gokuINDEX = TYPE(0);\n" 20961 " }\n"; 20962 static const GLchar* fs = "#version 430 core\n" 20963 "#extension GL_ARB_enhanced_layouts : require\n" 20964 "\n" 20965 "in vec4 any_fs;\n" 20966 "out vec4 fs_out;\n" 20967 "\n" 20968 "void main()\n" 20969 "{\n" 20970 " fs_out = any_fs;\n" 20971 "}\n" 20972 "\n"; 20973 static const GLchar* gs_tested = "#version 430 core\n" 20974 "#extension GL_ARB_enhanced_layouts : require\n" 20975 "\n" 20976 "layout(points) in;\n" 20977 "layout(triangle_strip, max_vertices = 4) out;\n" 20978 "\n" 20979 "VAR_DEFINITION" 20980 "\n" 20981 "in vec4 vs_any[];\n" 20982 "out vec4 any_fs;\n" 20983 "\n" 20984 "void main()\n" 20985 "{\n" 20986 " vec4 result = vs_any[0];\n" 20987 "\n" 20988 "VARIABLE_USE" 20989 "\n" 20990 " any_fs = result;\n" 20991 " gl_Position = vec4(-1, -1, 0, 1);\n" 20992 " EmitVertex();\n" 20993 " any_fs = result;\n" 20994 " gl_Position = vec4(-1, 1, 0, 1);\n" 20995 " EmitVertex();\n" 20996 " any_fs = result;\n" 20997 " gl_Position = vec4(1, -1, 0, 1);\n" 20998 " EmitVertex();\n" 20999 " any_fs = result;\n" 21000 " gl_Position = vec4(1, 1, 0, 1);\n" 21001 " EmitVertex();\n" 21002 "}\n" 21003 "\n"; 21004 static const GLchar* tcs = "#version 430 core\n" 21005 "#extension GL_ARB_enhanced_layouts : require\n" 21006 "\n" 21007 "layout(vertices = 1) out;\n" 21008 "\n" 21009 "in vec4 vs_any[];\n" 21010 "out vec4 tcs_tes[];\n" 21011 "\n" 21012 "void main()\n" 21013 "{\n" 21014 "\n" 21015 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n" 21016 "\n" 21017 " gl_TessLevelOuter[0] = 1.0;\n" 21018 " gl_TessLevelOuter[1] = 1.0;\n" 21019 " gl_TessLevelOuter[2] = 1.0;\n" 21020 " gl_TessLevelOuter[3] = 1.0;\n" 21021 " gl_TessLevelInner[0] = 1.0;\n" 21022 " gl_TessLevelInner[1] = 1.0;\n" 21023 "}\n" 21024 "\n"; 21025 static const GLchar* tcs_tested = "#version 430 core\n" 21026 "#extension GL_ARB_enhanced_layouts : require\n" 21027 "\n" 21028 "layout(vertices = 1) out;\n" 21029 "\n" 21030 "VAR_DEFINITION" 21031 "\n" 21032 "in vec4 vs_any[];\n" 21033 "out vec4 any_fs[];\n" 21034 "\n" 21035 "void main()\n" 21036 "{\n" 21037 " vec4 result = vs_any[gl_InvocationID];\n" 21038 "\n" 21039 "VARIABLE_USE" 21040 "\n" 21041 " any_fs[gl_InvocationID] = result;\n" 21042 "\n" 21043 " gl_TessLevelOuter[0] = 1.0;\n" 21044 " gl_TessLevelOuter[1] = 1.0;\n" 21045 " gl_TessLevelOuter[2] = 1.0;\n" 21046 " gl_TessLevelOuter[3] = 1.0;\n" 21047 " gl_TessLevelInner[0] = 1.0;\n" 21048 " gl_TessLevelInner[1] = 1.0;\n" 21049 "}\n" 21050 "\n"; 21051 static const GLchar* tes_tested = "#version 430 core\n" 21052 "#extension GL_ARB_enhanced_layouts : require\n" 21053 "\n" 21054 "layout(isolines, point_mode) in;\n" 21055 "\n" 21056 "VAR_DEFINITION" 21057 "\n" 21058 "in vec4 tcs_tes[];\n" 21059 "out vec4 any_fs;\n" 21060 "\n" 21061 "void main()\n" 21062 "{\n" 21063 " vec4 result = tcs_tes[0];\n" 21064 "\n" 21065 "VARIABLE_USE" 21066 "\n" 21067 " any_fs = result;\n" 21068 "}\n" 21069 "\n"; 21070 static const GLchar* vs = "#version 430 core\n" 21071 "#extension GL_ARB_enhanced_layouts : require\n" 21072 "\n" 21073 "in vec4 in_vs;\n" 21074 "out vec4 vs_any;\n" 21075 "\n" 21076 "void main()\n" 21077 "{\n" 21078 " vs_any = in_vs;\n" 21079 "}\n" 21080 "\n"; 21081 static const GLchar* vs_tested = "#version 430 core\n" 21082 "#extension GL_ARB_enhanced_layouts : require\n" 21083 "\n" 21084 "VAR_DEFINITION" 21085 "\n" 21086 "in vec4 in_vs;\n" 21087 "out vec4 any_fs;\n" 21088 "\n" 21089 "void main()\n" 21090 "{\n" 21091 " vec4 result = in_vs;\n" 21092 "\n" 21093 "VARIABLE_USE" 21094 "\n" 21095 " any_fs = result;\n" 21096 "}\n" 21097 "\n"; 21098 21099 std::string source; 21100 testCase& test_case = m_test_cases[test_case_index]; 21101 21102 if (test_case.m_stage == stage) 21103 { 21104 const GLchar* array = ""; 21105 GLchar buffer[16]; 21106 const GLchar* index = ""; 21107 size_t position = 0; 21108 size_t temp; 21109 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 21110 const GLchar* var_definition = 0; 21111 const GLchar* var_use = 0; 21112 21113 sprintf(buffer, "%d", test_case.m_type.GetSize()); 21114 21115 switch (test_case.m_case) 21116 { 21117 case VALID: 21118 var_definition = valid_var_definition; 21119 var_use = valid_use; 21120 break; 21121 case INVALID: 21122 var_definition = invalid_var_definition; 21123 var_use = invalid_use; 21124 break; 21125 default: 21126 TCU_FAIL("Invalid enum"); 21127 } 21128 21129 switch (stage) 21130 { 21131 case Utils::Shader::GEOMETRY: 21132 source = gs_tested; 21133 array = "[1]"; 21134 index = "[0]"; 21135 break; 21136 case Utils::Shader::TESS_CTRL: 21137 source = tcs_tested; 21138 array = "[1]"; 21139 index = "[gl_InvocationID]"; 21140 break; 21141 case Utils::Shader::TESS_EVAL: 21142 source = tes_tested; 21143 array = "[1]"; 21144 index = "[0]"; 21145 break; 21146 case Utils::Shader::VERTEX: 21147 source = vs_tested; 21148 break; 21149 default: 21150 TCU_FAIL("Invalid enum"); 21151 } 21152 21153 temp = position; 21154 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 21155 position = temp; 21156 Utils::replaceToken("SIZE", position, buffer, source); 21157 Utils::replaceToken("ARRAY", position, array, source); 21158 if (INVALID == test_case.m_case) 21159 { 21160 Utils::replaceToken("ARRAY", position, array, source); 21161 } 21162 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 21163 21164 Utils::replaceAllTokens("TYPE", type_name, source); 21165 Utils::replaceAllTokens("INDEX", index, source); 21166 } 21167 else 21168 { 21169 switch (test_case.m_stage) 21170 { 21171 case Utils::Shader::GEOMETRY: 21172 switch (stage) 21173 { 21174 case Utils::Shader::FRAGMENT: 21175 source = fs; 21176 break; 21177 case Utils::Shader::VERTEX: 21178 source = vs; 21179 break; 21180 default: 21181 source = ""; 21182 } 21183 break; 21184 case Utils::Shader::TESS_CTRL: 21185 switch (stage) 21186 { 21187 case Utils::Shader::FRAGMENT: 21188 source = fs; 21189 break; 21190 case Utils::Shader::VERTEX: 21191 source = vs; 21192 break; 21193 default: 21194 source = ""; 21195 } 21196 break; 21197 case Utils::Shader::TESS_EVAL: 21198 switch (stage) 21199 { 21200 case Utils::Shader::FRAGMENT: 21201 source = fs; 21202 break; 21203 case Utils::Shader::TESS_CTRL: 21204 source = tcs; 21205 break; 21206 case Utils::Shader::VERTEX: 21207 source = vs; 21208 break; 21209 default: 21210 source = ""; 21211 } 21212 break; 21213 case Utils::Shader::VERTEX: 21214 switch (stage) 21215 { 21216 case Utils::Shader::FRAGMENT: 21217 source = fs; 21218 break; 21219 default: 21220 source = ""; 21221 } 21222 break; 21223 default: 21224 TCU_FAIL("Invalid enum"); 21225 break; 21226 } 21227 } 21228 21229 return source; 21230 } 21231 21232 /** Get description of test case 21233 * 21234 * @param test_case_index Index of test case 21235 * 21236 * @return Test case description 21237 **/ 21238 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index) 21239 { 21240 std::stringstream stream; 21241 testCase& test_case = m_test_cases[test_case_index]; 21242 21243 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 21244 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: "; 21245 21246 switch (test_case.m_case) 21247 { 21248 case VALID: 21249 stream << "valid"; 21250 break; 21251 case INVALID: 21252 stream << "invalid"; 21253 break; 21254 default: 21255 TCU_FAIL("Invalid enum"); 21256 } 21257 21258 return stream.str(); 21259 } 21260 21261 /** Get number of test cases 21262 * 21263 * @return Number of test cases 21264 **/ 21265 GLuint XFBVariableStrideTest::getTestCaseNumber() 21266 { 21267 return static_cast<GLuint>(m_test_cases.size()); 21268 } 21269 21270 /** Selects if "compute" stage is relevant for test 21271 * 21272 * @param ignored 21273 * 21274 * @return false 21275 **/ 21276 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */) 21277 { 21278 return false; 21279 } 21280 21281 /** Selects if compilation failure is expected result 21282 * 21283 * @param test_case_index Index of test case 21284 * 21285 * @return true 21286 **/ 21287 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index) 21288 { 21289 testCase& test_case = m_test_cases[test_case_index]; 21290 21291 return (INVALID == test_case.m_case); 21292 } 21293 21294 /** Prepare all test cases 21295 * 21296 **/ 21297 void XFBVariableStrideTest::testInit() 21298 { 21299 const GLuint n_types = getTypesNumber(); 21300 21301 for (GLuint i = 0; i < n_types; ++i) 21302 { 21303 const Utils::Type& type = getType(i); 21304 21305 /* 21306 Some of the cases are declared as following are considered as invalid, 21307 but accoring to spec, the following declaration is valid: shaders in the 21308 transform feedback capturing mode have an initial global default of layout(xfb_buffer=0) out, 21309 so for the first variable's declaration, the xfb_stride = 16 is applied on buffer 0, for the 21310 second variable, its buffer is also inherited from global buffer 0, and its offset does not overflows 21311 the stride. 21312 21313 The xfb_stride is the memory width of given buffer, not for variable even though xfb_stride 21314 is declared on the variable. It seems that the writter of this case misunderstand the concept of 21315 xfb_stride, because spec describes that xfb_stride can be declared multiple times for the same buffer, 21316 it is a compile or link-time error to have different values specified for the stride for the same buffer. 21317 21318 int type_size = 8; 21319 layout (xfb_offset = 0, xfb_stride = 2 * type_size) out double goku; 21320 layout (xfb_offset = type_size) out double vegeta; 21321 */ 21322 // all the shaders are valid, so remove the following loop(it contains CASE_MAX is enum of valid and invalid) 21323 // for (GLuint c = 0; c < CASE_MAX; ++c) 21324 { 21325 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 21326 { 21327 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 21328 (Utils::Shader::FRAGMENT == stage)) 21329 { 21330 continue; 21331 } 21332 21333 testCase test_case = { (CASES)VALID, (Utils::Shader::STAGES)stage, type }; 21334 21335 m_test_cases.push_back(test_case); 21336 } 21337 } 21338 } 21339 } 21340 21341 /** Constructor 21342 * 21343 * @param context Test framework context 21344 **/ 21345 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context& context) 21346 : TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks") 21347 { 21348 } 21349 21350 /** Source for given test case and stage 21351 * 21352 * @param test_case_index Index of test case 21353 * @param stage Shader stage 21354 * 21355 * @return Shader source 21356 **/ 21357 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 21358 { 21359 static const GLchar* var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n" 21360 " vec4 gohan;\n" 21361 " vec4 goten;\n" 21362 " vec4 chichi;\n" 21363 "} gokuARRAY;\n"; 21364 static const GLchar* var_use = " gokuINDEX.gohan = vec4(1, 0, 0, 0);\n" 21365 " gokuINDEX.goten = vec4(0, 0, 1, 0);\n" 21366 " gokuINDEX.chichi = vec4(0, 1, 0, 0);\n" 21367 " if (vec4(0) == result)\n" 21368 " {\n" 21369 " gokuINDEX.gohan = vec4(0, 1, 1, 1);\n" 21370 " gokuINDEX.goten = vec4(1, 1, 0, 1);\n" 21371 " gokuINDEX.chichi = vec4(1, 0, 1, 1);\n" 21372 " }\n"; 21373 static const GLchar* gs_tested = 21374 "#version 430 core\n" 21375 "#extension GL_ARB_enhanced_layouts : require\n" 21376 "\n" 21377 "layout(points) in;\n" 21378 "layout(triangle_strip, max_vertices = 4) out;\n" 21379 "\n" 21380 "VAR_DEFINITION" 21381 "\n" 21382 "out gl_PerVertex \n" 21383 "{ \n" 21384 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode 21385 "}; \n" 21386 "in vec4 tes_gs[];\n" 21387 "out vec4 gs_fs;\n" 21388 "\n" 21389 "void main()\n" 21390 "{\n" 21391 " vec4 result = tes_gs[0];\n" 21392 "\n" 21393 "VARIABLE_USE" 21394 "\n" 21395 " gs_fs = result;\n" 21396 " gl_Position = vec4(-1, -1, 0, 1);\n" 21397 " EmitVertex();\n" 21398 " gs_fs = result;\n" 21399 " gl_Position = vec4(-1, 1, 0, 1);\n" 21400 " EmitVertex();\n" 21401 " gs_fs = result;\n" 21402 " gl_Position = vec4(1, -1, 0, 1);\n" 21403 " EmitVertex();\n" 21404 " gs_fs = result;\n" 21405 " gl_Position = vec4(1, 1, 0, 1);\n" 21406 " EmitVertex();\n" 21407 "}\n" 21408 "\n"; 21409 static const GLchar* tcs = "#version 430 core\n" 21410 "#extension GL_ARB_enhanced_layouts : require\n" 21411 "\n" 21412 "layout(vertices = 1) out;\n" 21413 "\n" 21414 "in vec4 vs_tcs[];\n" 21415 "out vec4 tcs_tes[];\n" 21416 "\n" 21417 "void main()\n" 21418 "{\n" 21419 "\n" 21420 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 21421 "\n" 21422 " gl_TessLevelOuter[0] = 1.0;\n" 21423 " gl_TessLevelOuter[1] = 1.0;\n" 21424 " gl_TessLevelOuter[2] = 1.0;\n" 21425 " gl_TessLevelOuter[3] = 1.0;\n" 21426 " gl_TessLevelInner[0] = 1.0;\n" 21427 " gl_TessLevelInner[1] = 1.0;\n" 21428 "}\n" 21429 "\n"; 21430 #if 0 21431 static const GLchar* tcs_tested = 21432 "#version 430 core\n" 21433 "#extension GL_ARB_enhanced_layouts : require\n" 21434 "\n" 21435 "layout(vertices = 1) out;\n" 21436 "\n" 21437 "VAR_DEFINITION" 21438 "\n" 21439 "in vec4 vs_tcs[];\n" 21440 "out vec4 tcs_tes[];\n" 21441 "\n" 21442 "void main()\n" 21443 "{\n" 21444 " vec4 result = vs_tcs[gl_InvocationID];\n" 21445 "\n" 21446 "VARIABLE_USE" 21447 "\n" 21448 " tcs_tes[gl_InvocationID] = result;\n" 21449 "\n" 21450 " gl_TessLevelOuter[0] = 1.0;\n" 21451 " gl_TessLevelOuter[1] = 1.0;\n" 21452 " gl_TessLevelOuter[2] = 1.0;\n" 21453 " gl_TessLevelOuter[3] = 1.0;\n" 21454 " gl_TessLevelInner[0] = 1.0;\n" 21455 " gl_TessLevelInner[1] = 1.0;\n" 21456 "}\n" 21457 "\n"; 21458 #endif 21459 static const GLchar* tes_tested = "#version 430 core\n" 21460 "#extension GL_ARB_enhanced_layouts : require\n" 21461 "\n" 21462 "layout(isolines, point_mode) in;\n" 21463 "\n" 21464 "VAR_DEFINITION" 21465 "\n" 21466 "in vec4 tcs_tes[];\n" 21467 "out vec4 tes_gs;\n" 21468 "\n" 21469 "void main()\n" 21470 "{\n" 21471 " vec4 result = tcs_tes[0];\n" 21472 "\n" 21473 "VARIABLE_USE" 21474 "\n" 21475 " tes_gs += result;\n" 21476 "}\n" 21477 "\n"; 21478 static const GLchar* vs = "#version 430 core\n" 21479 "#extension GL_ARB_enhanced_layouts : require\n" 21480 "\n" 21481 "in vec4 in_vs;\n" 21482 "out vec4 vs_tcs;\n" 21483 "\n" 21484 "void main()\n" 21485 "{\n" 21486 " vs_tcs = in_vs;\n" 21487 "}\n" 21488 "\n"; 21489 static const GLchar* vs_tested = "#version 430 core\n" 21490 "#extension GL_ARB_enhanced_layouts : require\n" 21491 "\n" 21492 "VAR_DEFINITION" 21493 "\n" 21494 "in vec4 in_vs;\n" 21495 "out vec4 vs_tcs;\n" 21496 "\n" 21497 "void main()\n" 21498 "{\n" 21499 " vec4 result = in_vs;\n" 21500 "\n" 21501 "VARIABLE_USE" 21502 "\n" 21503 " vs_tcs += result;\n" 21504 "}\n" 21505 "\n"; 21506 21507 std::string source; 21508 Utils::Shader::STAGES test_case = m_test_cases[test_case_index]; 21509 21510 if (test_case == stage) 21511 { 21512 const GLchar* array = ""; 21513 const GLchar* index = ""; 21514 size_t position = 0; 21515 size_t temp; 21516 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73) 21517 // change array = "[]" to "[1]" 21518 switch (stage) 21519 { 21520 case Utils::Shader::GEOMETRY: 21521 source = gs_tested; 21522 array = "[1]"; 21523 index = "[0]"; 21524 break; 21525 /* 21526 It is invalid to define transform feedback output in HS 21527 */ 21528 #if 0 21529 case Utils::Shader::TESS_CTRL: 21530 source = tcs_tested; 21531 array = "[]"; 21532 index = "[gl_InvocationID]"; 21533 break; 21534 #endif 21535 case Utils::Shader::TESS_EVAL: 21536 source = tes_tested; 21537 array = "[1]"; 21538 index = "[0]"; 21539 break; 21540 case Utils::Shader::VERTEX: 21541 source = vs_tested; 21542 break; 21543 default: 21544 TCU_FAIL("Invalid enum"); 21545 } 21546 21547 temp = position; 21548 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 21549 position = temp; 21550 Utils::replaceToken("ARRAY", position, array, source); 21551 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 21552 21553 Utils::replaceAllTokens("INDEX", index, source); 21554 } 21555 else 21556 { 21557 switch (test_case) 21558 { 21559 case Utils::Shader::GEOMETRY: 21560 switch (stage) 21561 { 21562 case Utils::Shader::VERTEX: 21563 source = vs; 21564 break; 21565 default: 21566 source = ""; 21567 } 21568 break; 21569 case Utils::Shader::TESS_CTRL: 21570 switch (stage) 21571 { 21572 case Utils::Shader::VERTEX: 21573 source = vs; 21574 break; 21575 default: 21576 source = ""; 21577 } 21578 break; 21579 case Utils::Shader::TESS_EVAL: 21580 switch (stage) 21581 { 21582 case Utils::Shader::TESS_CTRL: 21583 source = tcs; 21584 break; 21585 case Utils::Shader::VERTEX: 21586 source = vs; 21587 break; 21588 default: 21589 source = ""; 21590 } 21591 break; 21592 case Utils::Shader::VERTEX: 21593 source = ""; 21594 break; 21595 default: 21596 TCU_FAIL("Invalid enum"); 21597 break; 21598 } 21599 } 21600 21601 return source; 21602 } 21603 21604 /** Get description of test case 21605 * 21606 * @param test_case_index Index of test case 21607 * 21608 * @return Test case description 21609 **/ 21610 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index) 21611 { 21612 std::stringstream stream; 21613 21614 stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]); 21615 21616 return stream.str(); 21617 } 21618 21619 /** Get number of test cases 21620 * 21621 * @return Number of test cases 21622 **/ 21623 GLuint XFBBlockStrideTest::getTestCaseNumber() 21624 { 21625 return static_cast<GLuint>(m_test_cases.size()); 21626 } 21627 21628 /** Inspects program for xfb stride 21629 * 21630 * @param program Program to query 21631 * 21632 * @return true if query results match expected values, false otherwise 21633 **/ 21634 bool XFBBlockStrideTest::inspectProgram(Utils::Program& program) 21635 { 21636 GLint stride = 0; 21637 21638 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 21639 1 /* buf_size */, &stride); 21640 21641 return (128 == stride); 21642 } 21643 21644 /** Runs test case 21645 * 21646 * @param test_case_index Id of test case 21647 * 21648 * @return true if test case pass, false otherwise 21649 **/ 21650 bool XFBBlockStrideTest::testCase(GLuint test_case_index) 21651 { 21652 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY); 21653 Utils::Program program(m_context); 21654 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL); 21655 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL); 21656 bool test_case_result = true; 21657 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX); 21658 21659 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */); 21660 21661 test_case_result = inspectProgram(program); 21662 21663 return test_case_result; 21664 } 21665 21666 /** Prepare all test cases 21667 * 21668 **/ 21669 void XFBBlockStrideTest::testInit() 21670 { 21671 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 21672 { 21673 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 21674 (Utils::Shader::FRAGMENT == stage)) 21675 { 21676 continue; 21677 } 21678 21679 m_test_cases.push_back((Utils::Shader::STAGES)stage); 21680 } 21681 } 21682 21683 /** Constructor 21684 * 21685 * @param context Test context 21686 **/ 21687 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context& context) 21688 : BufferTestBase(context, "xfb_block_member_stride", 21689 "Test verifies that xfb_stride qualifier is respected for block member") 21690 { 21691 /* Nothing to be done here */ 21692 } 21693 21694 /** Get descriptors of buffers necessary for test 21695 * 21696 * @param ignored 21697 * @param out_descriptors Descriptors of buffers used by test 21698 **/ 21699 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 21700 bufferDescriptor::Vector& out_descriptors) 21701 { 21702 const Utils::Type& vec4 = Utils::Type::vec4; 21703 21704 /* Test needs single uniform and xfb */ 21705 out_descriptors.resize(2); 21706 21707 /* Get references */ 21708 bufferDescriptor& uniform = out_descriptors[0]; 21709 bufferDescriptor& xfb = out_descriptors[1]; 21710 21711 /* Index */ 21712 uniform.m_index = 0; 21713 xfb.m_index = 0; 21714 21715 /* Target */ 21716 uniform.m_target = Utils::Buffer::Uniform; 21717 xfb.m_target = Utils::Buffer::Transform_feedback; 21718 21719 /* Data */ 21720 static const GLuint vec4_size = 16; 21721 const std::vector<GLubyte>& gohan_data = vec4.GenerateDataPacked(); 21722 const std::vector<GLubyte>& goten_data = vec4.GenerateDataPacked(); 21723 const std::vector<GLubyte>& chichi_data = vec4.GenerateDataPacked(); 21724 21725 /* Uniform data */ 21726 uniform.m_initial_data.resize(3 * vec4_size); 21727 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size); 21728 memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size); 21729 memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size); 21730 21731 /* XFB data */ 21732 xfb.m_initial_data.resize(4 * vec4_size); 21733 xfb.m_expected_data.resize(4 * vec4_size); 21734 21735 for (GLuint i = 0; i < 4 * vec4_size; ++i) 21736 { 21737 xfb.m_initial_data[i] = (glw::GLubyte)i; 21738 xfb.m_expected_data[i] = (glw::GLubyte)i; 21739 } 21740 21741 // the xfb_offset of "chichi" should be 32 21742 memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size); 21743 memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size); 21744 memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size); 21745 } 21746 21747 /** Get body of main function for given shader stage 21748 * 21749 * @param ignored 21750 * @param stage Shader stage 21751 * @param out_assignments Set to empty 21752 * @param out_calculations Set to empty 21753 **/ 21754 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 21755 std::string& out_assignments, std::string& out_calculations) 21756 { 21757 out_calculations = ""; 21758 21759 static const GLchar* gs = " gohan = uni_gohan;\n" 21760 " goten = uni_goten;\n" 21761 " chichi = uni_chichi;\n"; 21762 static const GLchar* fs = " fs_out = gohan + goten + chichi;\n"; 21763 21764 const GLchar* assignments = ""; 21765 switch (stage) 21766 { 21767 case Utils::Shader::FRAGMENT: 21768 assignments = fs; 21769 break; 21770 case Utils::Shader::GEOMETRY: 21771 assignments = gs; 21772 break; 21773 default: 21774 break; 21775 } 21776 21777 out_assignments = assignments; 21778 } 21779 21780 /** Get interface of shader 21781 * 21782 * @param ignored 21783 * @param stage Shader stage 21784 * @param out_interface Set to "" 21785 **/ 21786 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 21787 std::string& out_interface) 21788 { 21789 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n" 21790 " vec4 gohan;\n" 21791 " layout (xfb_stride = 48) vec4 goten;\n" 21792 " vec4 chichi;\n" 21793 "};\n" 21794 "layout(binding = 0) uniform gs_block {\n" 21795 " vec4 uni_gohan;\n" 21796 " vec4 uni_goten;\n" 21797 " vec4 uni_chichi;\n" 21798 "};\n"; 21799 static const GLchar* fs = "in Goku {\n" 21800 " vec4 gohan;\n" 21801 " vec4 goten;\n" 21802 " vec4 chichi;\n" 21803 "};\n" 21804 "out vec4 fs_out;\n"; 21805 21806 switch (stage) 21807 { 21808 case Utils::Shader::FRAGMENT: 21809 out_interface = fs; 21810 break; 21811 case Utils::Shader::GEOMETRY: 21812 out_interface = gs; 21813 break; 21814 default: 21815 out_interface = ""; 21816 return; 21817 } 21818 } 21819 21820 /** Inspects program to check if all resources are as expected 21821 * 21822 * @param ignored 21823 * @param program Program instance 21824 * @param out_stream Error message 21825 * 21826 * @return true if everything is ok, false otherwise 21827 **/ 21828 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program& program, 21829 std::stringstream& out_stream) 21830 { 21831 const GLuint gohan_id = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING); 21832 const GLuint goten_id = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING); 21833 const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING); 21834 21835 GLint gohan_offset = 0; 21836 GLint goten_offset = 0; 21837 GLint chichi_offset = 0; 21838 21839 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset); 21840 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset); 21841 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset); 21842 21843 // the xfb_offset of "chichi" should be 32 21844 if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset)) 21845 { 21846 out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset 21847 << "] expected: [0, 16, 32]"; 21848 return false; 21849 } 21850 21851 return true; 21852 } 21853 21854 /** Constructor 21855 * 21856 * @param context Test framework context 21857 **/ 21858 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context& context) 21859 : NegativeTestBase(context, "xfb_duplicated_stride", 21860 "Test verifies that compiler reports error when conflicting stride qualifiers are used") 21861 { 21862 } 21863 21864 /** Source for given test case and stage 21865 * 21866 * @param test_case_index Index of test case 21867 * @param stage Shader stage 21868 * 21869 * @return Shader source 21870 **/ 21871 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 21872 { 21873 static const GLchar* invalid_var_definition = "const uint valid_stride = 64;\n" 21874 "const uint conflicting_stride = 128;\n" 21875 "\n" 21876 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n" 21877 "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n"; 21878 static const GLchar* valid_var_definition = "const uint valid_stride = 64;\n" 21879 "\n" 21880 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n" 21881 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"; 21882 static const GLchar* fs = "#version 430 core\n" 21883 "#extension GL_ARB_enhanced_layouts : require\n" 21884 "\n" 21885 "in vec4 any_fs;\n" 21886 "out vec4 fs_out;\n" 21887 "\n" 21888 "void main()\n" 21889 "{\n" 21890 " fs_out = any_fs;\n" 21891 "}\n" 21892 "\n"; 21893 static const GLchar* gs_tested = "#version 430 core\n" 21894 "#extension GL_ARB_enhanced_layouts : require\n" 21895 "\n" 21896 "layout(points) in;\n" 21897 "layout(triangle_strip, max_vertices = 4) out;\n" 21898 "\n" 21899 "VAR_DEFINITION" 21900 "\n" 21901 "in vec4 vs_any[];\n" 21902 "out vec4 any_fs;\n" 21903 "\n" 21904 "void main()\n" 21905 "{\n" 21906 " vec4 result = vs_any[0];\n" 21907 "\n" 21908 "VARIABLE_USE" 21909 "\n" 21910 " any_fs = result;\n" 21911 " gl_Position = vec4(-1, -1, 0, 1);\n" 21912 " EmitVertex();\n" 21913 " any_fs = result;\n" 21914 " gl_Position = vec4(-1, 1, 0, 1);\n" 21915 " EmitVertex();\n" 21916 " any_fs = result;\n" 21917 " gl_Position = vec4(1, -1, 0, 1);\n" 21918 " EmitVertex();\n" 21919 " any_fs = result;\n" 21920 " gl_Position = vec4(1, 1, 0, 1);\n" 21921 " EmitVertex();\n" 21922 "}\n" 21923 "\n"; 21924 static const GLchar* tcs = "#version 430 core\n" 21925 "#extension GL_ARB_enhanced_layouts : require\n" 21926 "\n" 21927 "layout(vertices = 1) out;\n" 21928 "\n" 21929 "in vec4 vs_any[];\n" 21930 "out vec4 tcs_tes[];\n" 21931 "\n" 21932 "void main()\n" 21933 "{\n" 21934 "\n" 21935 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n" 21936 "\n" 21937 " gl_TessLevelOuter[0] = 1.0;\n" 21938 " gl_TessLevelOuter[1] = 1.0;\n" 21939 " gl_TessLevelOuter[2] = 1.0;\n" 21940 " gl_TessLevelOuter[3] = 1.0;\n" 21941 " gl_TessLevelInner[0] = 1.0;\n" 21942 " gl_TessLevelInner[1] = 1.0;\n" 21943 "}\n" 21944 "\n"; 21945 static const GLchar* tcs_tested = "#version 430 core\n" 21946 "#extension GL_ARB_enhanced_layouts : require\n" 21947 "\n" 21948 "layout(vertices = 1) out;\n" 21949 "\n" 21950 "VAR_DEFINITION" 21951 "\n" 21952 "in vec4 vs_any[];\n" 21953 "out vec4 any_fs[];\n" 21954 "\n" 21955 "void main()\n" 21956 "{\n" 21957 " vec4 result = vs_any[gl_InvocationID];\n" 21958 "\n" 21959 "VARIABLE_USE" 21960 "\n" 21961 " any_fs[gl_InvocationID] = result;\n" 21962 "\n" 21963 " gl_TessLevelOuter[0] = 1.0;\n" 21964 " gl_TessLevelOuter[1] = 1.0;\n" 21965 " gl_TessLevelOuter[2] = 1.0;\n" 21966 " gl_TessLevelOuter[3] = 1.0;\n" 21967 " gl_TessLevelInner[0] = 1.0;\n" 21968 " gl_TessLevelInner[1] = 1.0;\n" 21969 "}\n" 21970 "\n"; 21971 static const GLchar* tes_tested = "#version 430 core\n" 21972 "#extension GL_ARB_enhanced_layouts : require\n" 21973 "\n" 21974 "layout(isolines, point_mode) in;\n" 21975 "\n" 21976 "VAR_DEFINITION" 21977 "\n" 21978 "in vec4 tcs_tes[];\n" 21979 "out vec4 any_fs;\n" 21980 "\n" 21981 "void main()\n" 21982 "{\n" 21983 " vec4 result = tcs_tes[0];\n" 21984 "\n" 21985 "VARIABLE_USE" 21986 "\n" 21987 " any_fs = result;\n" 21988 "}\n" 21989 "\n"; 21990 static const GLchar* vs = "#version 430 core\n" 21991 "#extension GL_ARB_enhanced_layouts : require\n" 21992 "\n" 21993 "in vec4 in_vs;\n" 21994 "out vec4 vs_any;\n" 21995 "\n" 21996 "void main()\n" 21997 "{\n" 21998 " vs_any = in_vs;\n" 21999 "}\n" 22000 "\n"; 22001 static const GLchar* vs_tested = "#version 430 core\n" 22002 "#extension GL_ARB_enhanced_layouts : require\n" 22003 "\n" 22004 "VAR_DEFINITION" 22005 "\n" 22006 "in vec4 in_vs;\n" 22007 "out vec4 any_fs;\n" 22008 "\n" 22009 "void main()\n" 22010 "{\n" 22011 " vec4 result = in_vs;\n" 22012 "\n" 22013 "VARIABLE_USE" 22014 "\n" 22015 " any_fs += result;\n" 22016 "}\n" 22017 "\n"; 22018 22019 std::string source; 22020 testCase& test_case = m_test_cases[test_case_index]; 22021 22022 if (test_case.m_stage == stage) 22023 { 22024 size_t position = 0; 22025 const GLchar* var_definition = 0; 22026 const GLchar* var_use = ""; 22027 22028 switch (test_case.m_case) 22029 { 22030 case VALID: 22031 var_definition = valid_var_definition; 22032 break; 22033 case INVALID: 22034 var_definition = invalid_var_definition; 22035 break; 22036 default: 22037 TCU_FAIL("Invalid enum"); 22038 } 22039 22040 switch (stage) 22041 { 22042 case Utils::Shader::GEOMETRY: 22043 source = gs_tested; 22044 break; 22045 case Utils::Shader::TESS_CTRL: 22046 source = tcs_tested; 22047 break; 22048 case Utils::Shader::TESS_EVAL: 22049 source = tes_tested; 22050 break; 22051 case Utils::Shader::VERTEX: 22052 source = vs_tested; 22053 break; 22054 default: 22055 TCU_FAIL("Invalid enum"); 22056 } 22057 22058 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 22059 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 22060 } 22061 else 22062 { 22063 switch (test_case.m_stage) 22064 { 22065 case Utils::Shader::GEOMETRY: 22066 switch (stage) 22067 { 22068 case Utils::Shader::FRAGMENT: 22069 source = fs; 22070 break; 22071 case Utils::Shader::VERTEX: 22072 source = vs; 22073 break; 22074 default: 22075 source = ""; 22076 } 22077 break; 22078 case Utils::Shader::TESS_CTRL: 22079 switch (stage) 22080 { 22081 case Utils::Shader::FRAGMENT: 22082 source = fs; 22083 break; 22084 case Utils::Shader::VERTEX: 22085 source = vs; 22086 break; 22087 default: 22088 source = ""; 22089 } 22090 break; 22091 case Utils::Shader::TESS_EVAL: 22092 switch (stage) 22093 { 22094 case Utils::Shader::FRAGMENT: 22095 source = fs; 22096 break; 22097 case Utils::Shader::TESS_CTRL: 22098 source = tcs; 22099 break; 22100 case Utils::Shader::VERTEX: 22101 source = vs; 22102 break; 22103 default: 22104 source = ""; 22105 } 22106 break; 22107 case Utils::Shader::VERTEX: 22108 switch (stage) 22109 { 22110 case Utils::Shader::FRAGMENT: 22111 source = fs; 22112 break; 22113 default: 22114 source = ""; 22115 } 22116 break; 22117 default: 22118 TCU_FAIL("Invalid enum"); 22119 break; 22120 } 22121 } 22122 22123 return source; 22124 } 22125 22126 /** Get description of test case 22127 * 22128 * @param test_case_index Index of test case 22129 * 22130 * @return Test case description 22131 **/ 22132 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index) 22133 { 22134 std::stringstream stream; 22135 testCase& test_case = m_test_cases[test_case_index]; 22136 22137 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: "; 22138 22139 switch (test_case.m_case) 22140 { 22141 case VALID: 22142 stream << "valid"; 22143 break; 22144 case INVALID: 22145 stream << "invalid"; 22146 break; 22147 default: 22148 TCU_FAIL("Invalid enum"); 22149 } 22150 22151 return stream.str(); 22152 } 22153 22154 /** Get number of test cases 22155 * 22156 * @return Number of test cases 22157 **/ 22158 GLuint XFBDuplicatedStrideTest::getTestCaseNumber() 22159 { 22160 return static_cast<GLuint>(m_test_cases.size()); 22161 } 22162 22163 /** Selects if "compute" stage is relevant for test 22164 * 22165 * @param ignored 22166 * 22167 * @return false 22168 **/ 22169 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */) 22170 { 22171 return false; 22172 } 22173 22174 /** Selects if compilation failure is expected result 22175 * 22176 * @param test_case_index Index of test case 22177 * 22178 * @return true 22179 **/ 22180 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index) 22181 { 22182 testCase& test_case = m_test_cases[test_case_index]; 22183 22184 return (INVALID == test_case.m_case); 22185 } 22186 22187 /** Prepare all test cases 22188 * 22189 **/ 22190 void XFBDuplicatedStrideTest::testInit() 22191 { 22192 for (GLuint c = 0; c < CASE_MAX; ++c) 22193 { 22194 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 22195 { 22196 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 22197 (Utils::Shader::FRAGMENT == stage)) 22198 { 22199 continue; 22200 } 22201 22202 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage }; 22203 22204 m_test_cases.push_back(test_case); 22205 } 22206 } 22207 } 22208 22209 /** Constructor 22210 * 22211 * @param context Test framework context 22212 **/ 22213 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context& context) 22214 : TestBase(context, "xfb_get_program_resource_api", 22215 "Test verifies that get program resource reports correct results for XFB") 22216 { 22217 } 22218 22219 /** Source for given test case and stage 22220 * 22221 * @param test_case_index Index of test case 22222 * @param stage Shader stage 22223 * 22224 * @return Shader source 22225 **/ 22226 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 22227 { 22228 static const GLchar* api_var_definition = "out TYPE b0_v1ARRAY;\n" 22229 "out TYPE b1_v1ARRAY;\n" 22230 "out TYPE b0_v3ARRAY;\n" 22231 "out TYPE b0_v0ARRAY;\n"; 22232 static const GLchar* xfb_var_definition = 22233 "const uint type_size = SIZE;\n" 22234 "\n" 22235 "layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n" 22236 "\n" 22237 "layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n" 22238 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n" 22239 "layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n" 22240 "layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n"; 22241 static const GLchar* var_use = " b0_v1INDEX = TYPE(0);\n" 22242 " b1_v1INDEX = TYPE(1);\n" 22243 " b0_v3INDEX = TYPE(0);\n" 22244 " b0_v0INDEX = TYPE(1);\n" 22245 " if (vec4(0) == result)\n" 22246 " {\n" 22247 " b0_v1INDEX = TYPE(1);\n" 22248 " b1_v1INDEX = TYPE(0);\n" 22249 " b0_v3INDEX = TYPE(1);\n" 22250 " b0_v0INDEX = TYPE(0);\n" 22251 " }\n"; 22252 static const GLchar* gs_tested = 22253 "#version 430 core\n" 22254 "#extension GL_ARB_enhanced_layouts : require\n" 22255 "\n" 22256 "layout(points) in;\n" 22257 "layout(triangle_strip, max_vertices = 4) out;\n" 22258 "\n" 22259 "VAR_DEFINITION" 22260 "\n" 22261 "out gl_PerVertex \n" 22262 "{ \n" 22263 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode 22264 "}; \n" 22265 "in vec4 tes_gs[];\n" 22266 "out vec4 gs_fs;\n" 22267 "\n" 22268 "void main()\n" 22269 "{\n" 22270 " vec4 result = tes_gs[0];\n" 22271 "\n" 22272 "VARIABLE_USE" 22273 "\n" 22274 " gs_fs = result;\n" 22275 " gl_Position = vec4(-1, -1, 0, 1);\n" 22276 " EmitVertex();\n" 22277 " gs_fs = result;\n" 22278 " gl_Position = vec4(-1, 1, 0, 1);\n" 22279 " EmitVertex();\n" 22280 " gs_fs = result;\n" 22281 " gl_Position = vec4(1, -1, 0, 1);\n" 22282 " EmitVertex();\n" 22283 " gs_fs = result;\n" 22284 " gl_Position = vec4(1, 1, 0, 1);\n" 22285 " EmitVertex();\n" 22286 "}\n" 22287 "\n"; 22288 #if 0 22289 static const GLchar* tcs_tested = 22290 "#version 430 core\n" 22291 "#extension GL_ARB_enhanced_layouts : require\n" 22292 "\n" 22293 "layout(vertices = 1) out;\n" 22294 "\n" 22295 "VAR_DEFINITION" 22296 "\n" 22297 "in vec4 vs_tcs[];\n" 22298 "out vec4 tcs_tes[];\n" 22299 "\n" 22300 "void main()\n" 22301 "{\n" 22302 " vec4 result = vs_tcs[gl_InvocationID];\n" 22303 "\n" 22304 "VARIABLE_USE" 22305 "\n" 22306 " tcs_tes[gl_InvocationID] = result;\n" 22307 "\n" 22308 " gl_TessLevelOuter[0] = 1.0;\n" 22309 " gl_TessLevelOuter[1] = 1.0;\n" 22310 " gl_TessLevelOuter[2] = 1.0;\n" 22311 " gl_TessLevelOuter[3] = 1.0;\n" 22312 " gl_TessLevelInner[0] = 1.0;\n" 22313 " gl_TessLevelInner[1] = 1.0;\n" 22314 "}\n" 22315 "\n"; 22316 #endif 22317 static const GLchar* tes_tested = "#version 430 core\n" 22318 "#extension GL_ARB_enhanced_layouts : require\n" 22319 "\n" 22320 "layout(isolines, point_mode) in;\n" 22321 "\n" 22322 "VAR_DEFINITION" 22323 "\n" 22324 "in vec4 tcs_tes[];\n" 22325 "out vec4 tes_gs;\n" 22326 "\n" 22327 "void main()\n" 22328 "{\n" 22329 " vec4 result = tcs_tes[0];\n" 22330 "\n" 22331 "VARIABLE_USE" 22332 "\n" 22333 " tes_gs = result;\n" 22334 "}\n" 22335 "\n"; 22336 static const GLchar* vs_tested = "#version 430 core\n" 22337 "#extension GL_ARB_enhanced_layouts : require\n" 22338 "\n" 22339 "VAR_DEFINITION" 22340 "\n" 22341 "in vec4 in_vs;\n" 22342 "out vec4 vs_tcs;\n" 22343 "\n" 22344 "void main()\n" 22345 "{\n" 22346 " vec4 result = in_vs;\n" 22347 "\n" 22348 "VARIABLE_USE" 22349 "\n" 22350 " vs_tcs = result;\n" 22351 "}\n" 22352 "\n"; 22353 22354 std::string source; 22355 const test_Case& test_case = m_test_cases[test_case_index]; 22356 22357 if (test_case.m_stage == stage) 22358 { 22359 const GLchar* array = ""; 22360 GLchar buffer[16]; 22361 const GLchar* index = ""; 22362 size_t position = 0; 22363 size_t temp; 22364 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 22365 const GLchar* var_definition = 0; 22366 22367 sprintf(buffer, "%d", test_case.m_type.GetSize()); 22368 22369 if (XFB == test_case.m_case) 22370 { 22371 var_definition = xfb_var_definition; 22372 } 22373 else 22374 { 22375 var_definition = api_var_definition; 22376 } 22377 22378 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73) 22379 // change array = "[]" to "[1]" 22380 switch (stage) 22381 { 22382 case Utils::Shader::GEOMETRY: 22383 source = gs_tested; 22384 array = "[1]"; 22385 index = "[0]"; 22386 break; 22387 // It is invalid to output transform feedback varyings in tessellation control shader 22388 #if 0 22389 case Utils::Shader::TESS_CTRL: 22390 source = tcs_tested; 22391 array = "[]"; 22392 index = "[gl_InvocationID]"; 22393 break; 22394 #endif 22395 case Utils::Shader::TESS_EVAL: 22396 source = tes_tested; 22397 array = "[1]"; 22398 index = "[0]"; 22399 break; 22400 case Utils::Shader::VERTEX: 22401 source = vs_tested; 22402 break; 22403 default: 22404 TCU_FAIL("Invalid enum"); 22405 } 22406 22407 temp = position; 22408 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 22409 if (XFB == test_case.m_case) 22410 { 22411 position = temp; 22412 Utils::replaceToken("SIZE", position, buffer, source); 22413 } 22414 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 22415 22416 Utils::replaceAllTokens("ARRAY", array, source); 22417 Utils::replaceAllTokens("INDEX", index, source); 22418 Utils::replaceAllTokens("TYPE", type_name, source); 22419 } 22420 else 22421 { 22422 source = ""; 22423 } 22424 22425 return source; 22426 } 22427 22428 /** Get description of test case 22429 * 22430 * @param test_case_index Index of test case 22431 * 22432 * @return Test case description 22433 **/ 22434 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index) 22435 { 22436 std::stringstream stream; 22437 const test_Case& test_case = m_test_cases[test_case_index]; 22438 22439 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 22440 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: "; 22441 22442 switch (test_case.m_case) 22443 { 22444 case INTERLEAVED: 22445 stream << "interleaved"; 22446 break; 22447 case SEPARATED: 22448 stream << "separated"; 22449 break; 22450 case XFB: 22451 stream << "xfb"; 22452 break; 22453 default: 22454 TCU_FAIL("Invalid enum"); 22455 } 22456 22457 return stream.str(); 22458 } 22459 22460 /** Get number of test cases 22461 * 22462 * @return Number of test cases 22463 **/ 22464 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber() 22465 { 22466 return static_cast<GLuint>(m_test_cases.size()); 22467 } 22468 22469 /** Inspects program for offset, buffer index, buffer stride and type 22470 * 22471 * @param test_case_index Index of test case 22472 * @param program Program to query 22473 * 22474 * @return true if query results match expected values, false otherwise 22475 **/ 22476 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program& program) 22477 { 22478 GLint b0_stride = 0; 22479 GLint b1_stride = 0; 22480 GLint b0_v0_buf = 0; 22481 GLint b0_v0_offset = 0; 22482 GLint b0_v0_type = 0; 22483 GLint b0_v1_buf = 0; 22484 GLint b0_v1_offset = 0; 22485 GLint b0_v1_type = 0; 22486 GLint b0_v3_buf = 0; 22487 GLint b0_v3_offset = 0; 22488 GLint b0_v3_type = 0; 22489 GLint b1_v1_buf = 0; 22490 GLint b1_v1_offset = 0; 22491 GLint b1_v1_type = 0; 22492 const test_Case& test_case = m_test_cases[test_case_index]; 22493 const GLenum type_enum = test_case.m_type.GetTypeGLenum(); 22494 const GLint type_size = test_case.m_type.GetSize(); 22495 22496 GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING); 22497 GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING); 22498 GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING); 22499 GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING); 22500 22501 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset); 22502 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset); 22503 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset); 22504 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset); 22505 22506 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type); 22507 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type); 22508 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type); 22509 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type); 22510 22511 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX, 22512 1 /* buf_size */, &b0_v0_buf); 22513 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX, 22514 1 /* buf_size */, &b0_v1_buf); 22515 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX, 22516 1 /* buf_size */, &b0_v3_buf); 22517 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX, 22518 1 /* buf_size */, &b1_v1_buf); 22519 22520 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */, 22521 &b0_stride); 22522 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */, 22523 &b1_stride); 22524 22525 if (SEPARATED != test_case.m_case) 22526 { 22527 return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) && 22528 ((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) && 22529 ((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) && 22530 ((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) && 22531 ((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) && 22532 ((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) && 22533 ((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type)); 22534 } 22535 else 22536 { 22537 return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) && 22538 ((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) && 22539 ((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) && 22540 ((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) && 22541 ((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type)); 22542 } 22543 } 22544 22545 /** Insert gl_SkipComponents 22546 * 22547 * @param num_components How many gl_SkipComponents1 need to be inserted 22548 * @param varyings The transform feedback varyings string vector 22549 * 22550 **/ 22551 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector& varyings) 22552 { 22553 int num_component_4 = num_components / 4; 22554 int num_component_1 = num_components % 4; 22555 for (int i = 0; i < num_component_4; i++) 22556 { 22557 varyings.push_back("gl_SkipComponents4"); 22558 } 22559 switch (num_component_1) 22560 { 22561 case 1: 22562 varyings.push_back("gl_SkipComponents1"); 22563 break; 22564 case 2: 22565 varyings.push_back("gl_SkipComponents2"); 22566 break; 22567 case 3: 22568 varyings.push_back("gl_SkipComponents3"); 22569 break; 22570 default: 22571 break; 22572 } 22573 } 22574 22575 /** Runs test case 22576 * 22577 * @param test_case_index Id of test case 22578 * 22579 * @return true if test case pass, false otherwise 22580 **/ 22581 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index) 22582 { 22583 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY); 22584 Utils::Program program(m_context); 22585 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL); 22586 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL); 22587 const test_Case& test_case = m_test_cases[test_case_index]; 22588 bool test_case_result = true; 22589 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX); 22590 22591 // According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values. 22592 // 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. 22593 22594 if (INTERLEAVED == test_case.m_case) 22595 { 22596 /* 22597 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1; 22598 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1; 22599 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3; 22600 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0; 22601 22602 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, 22603 we need to calculate how many "gl_SkipComponents" need to be inserted. 22604 */ 22605 Utils::Program::NameVector captured_varyings; 22606 captured_varyings.push_back("b0_v0"); 22607 captured_varyings.push_back("b0_v1"); 22608 // Compute how many gl_SkipComponents to be inserted 22609 int numComponents = test_case.m_type.GetSize() / 4; 22610 insertSkipComponents(numComponents, captured_varyings); 22611 captured_varyings.push_back("b0_v3"); 22612 captured_varyings.push_back("gl_NextBuffer"); 22613 insertSkipComponents(numComponents, captured_varyings); 22614 captured_varyings.push_back("b1_v1"); 22615 insertSkipComponents(numComponents * 2, captured_varyings); 22616 22617 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true, 22618 true /* separable */); 22619 } 22620 else if (SEPARATED == test_case.m_case) 22621 { 22622 Utils::Program::NameVector captured_varyings; 22623 22624 captured_varyings.push_back("b0_v0"); 22625 captured_varyings.push_back("b0_v1"); 22626 captured_varyings.push_back("b0_v3"); 22627 captured_varyings.push_back("b1_v1"); 22628 22629 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false, 22630 true /* separable */); 22631 } 22632 else 22633 { 22634 22635 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */); 22636 } 22637 22638 test_case_result = inspectProgram(test_case_index, program); 22639 22640 return test_case_result; 22641 } 22642 22643 /** Prepare all test cases 22644 * 22645 **/ 22646 void XFBGetProgramResourceAPITest::testInit() 22647 { 22648 const Functions& gl = m_context.getRenderContext().getFunctions(); 22649 const GLuint n_types = getTypesNumber(); 22650 GLint max_xfb_int; 22651 GLint max_xfb_sep; 22652 22653 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int); 22654 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 22655 22656 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep); 22657 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 22658 22659 GLint max_varyings; 22660 gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings); 22661 22662 for (GLuint i = 0; i < n_types; ++i) 22663 { 22664 // 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, 22665 // 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 22666 // shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader 22667 // to guarantee the number of varying not exceeded. 22668 /* 22669 layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out; 22670 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1; 22671 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1; 22672 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3; 22673 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0; 22674 in vec4 in_vs; 22675 out vec4 vs_tcs; 22676 */ 22677 if (i == 7 || i == 9) 22678 continue; 22679 const Utils::Type& type = getType(i); 22680 if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings) 22681 { 22682 continue; 22683 } 22684 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 22685 { 22686 /* 22687 It is invalid to define transform feedback output in HS 22688 */ 22689 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 22690 (Utils::Shader::FRAGMENT == stage)) 22691 { 22692 continue; 22693 } 22694 22695 test_Case test_case_int = { INTERLEAVED, (Utils::Shader::STAGES)stage, type }; 22696 test_Case test_case_sep = { SEPARATED, (Utils::Shader::STAGES)stage, type }; 22697 test_Case test_case_xfb = { XFB, (Utils::Shader::STAGES)stage, type }; 22698 22699 if ((int)type.GetSize() <= max_xfb_int) 22700 { 22701 m_test_cases.push_back(test_case_xfb); 22702 m_test_cases.push_back(test_case_int); 22703 } 22704 22705 if ((int)type.GetSize() <= max_xfb_sep) 22706 { 22707 m_test_cases.push_back(test_case_sep); 22708 } 22709 } 22710 } 22711 } 22712 22713 /** Constructor 22714 * 22715 * @param context Test context 22716 **/ 22717 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context& context) 22718 : BufferTestBase(context, "xfb_override_qualifiers_with_api", 22719 "Test verifies that xfb_offset qualifier is not overriden with API") 22720 { 22721 /* Nothing to be done here */ 22722 } 22723 22724 /** Get descriptors of buffers necessary for test 22725 * 22726 * @param test_case_index Index of test case 22727 * @param out_descriptors Descriptors of buffers used by test 22728 **/ 22729 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint test_case_index, 22730 bufferDescriptor::Vector& out_descriptors) 22731 { 22732 const Utils::Type& type = getType(test_case_index); 22733 22734 /* Test needs single uniform and xfb */ 22735 out_descriptors.resize(2); 22736 22737 /* Get references */ 22738 bufferDescriptor& uniform = out_descriptors[0]; 22739 bufferDescriptor& xfb = out_descriptors[1]; 22740 22741 /* Index */ 22742 uniform.m_index = 0; 22743 xfb.m_index = 0; 22744 22745 /* Target */ 22746 uniform.m_target = Utils::Buffer::Uniform; 22747 xfb.m_target = Utils::Buffer::Transform_feedback; 22748 22749 /* Data */ 22750 const GLuint gen_start = Utils::s_rand; 22751 const std::vector<GLubyte>& vegeta_data = type.GenerateData(); 22752 const std::vector<GLubyte>& trunks_data = type.GenerateData(); 22753 const std::vector<GLubyte>& goku_data = type.GenerateData(); 22754 22755 Utils::s_rand = gen_start; 22756 const std::vector<GLubyte>& vegeta_data_pck = type.GenerateDataPacked(); 22757 type.GenerateDataPacked(); // generate the data for trunks 22758 const std::vector<GLubyte>& goku_data_pck = type.GenerateDataPacked(); 22759 22760 const GLuint type_size = static_cast<GLuint>(vegeta_data.size()); 22761 const GLuint type_size_pck = static_cast<GLuint>(vegeta_data_pck.size()); 22762 22763 /* Uniform data */ 22764 uniform.m_initial_data.resize(3 * type_size); 22765 memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size); 22766 memcpy(&uniform.m_initial_data[0] + type_size, &trunks_data[0], type_size); 22767 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goku_data[0], type_size); 22768 22769 /* XFB data */ 22770 xfb.m_initial_data.resize(3 * type_size_pck); 22771 xfb.m_expected_data.resize(3 * type_size_pck); 22772 22773 for (GLuint i = 0; i < 3 * type_size_pck; ++i) 22774 { 22775 xfb.m_initial_data[i] = (glw::GLubyte)i; 22776 xfb.m_expected_data[i] = (glw::GLubyte)i; 22777 } 22778 22779 memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck); 22780 memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck); 22781 } 22782 22783 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings 22784 * 22785 * @param ignored 22786 * @param captured_varyings List of names 22787 **/ 22788 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */, 22789 Utils::Program::NameVector& captured_varyings) 22790 { 22791 captured_varyings.resize(1); 22792 22793 captured_varyings[0] = "trunks"; 22794 } 22795 22796 /** Get body of main function for given shader stage 22797 * 22798 * @param test_case_index Index of test case 22799 * @param stage Shader stage 22800 * @param out_assignments Set to empty 22801 * @param out_calculations Set to empty 22802 **/ 22803 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, 22804 std::string& out_assignments, std::string& out_calculations) 22805 { 22806 out_calculations = ""; 22807 22808 static const GLchar* gs = " vegeta = uni_vegeta;\n" 22809 " trunks = uni_trunks;\n" 22810 " goku = uni_goku;\n"; 22811 static const GLchar* fs = " fs_out = vec4(0);\n" 22812 " if (TYPE(1) == goku + trunks + vegeta)\n" 22813 " {\n" 22814 " fs_out = vec4(1);\n" 22815 " }\n"; 22816 22817 const GLchar* assignments = ""; 22818 switch (stage) 22819 { 22820 case Utils::Shader::FRAGMENT: 22821 assignments = fs; 22822 break; 22823 case Utils::Shader::GEOMETRY: 22824 assignments = gs; 22825 break; 22826 default: 22827 break; 22828 } 22829 22830 out_assignments = assignments; 22831 22832 if (Utils::Shader::FRAGMENT == stage) 22833 { 22834 const Utils::Type& type = getType(test_case_index); 22835 22836 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments); 22837 } 22838 } 22839 22840 /** Get interface of shader 22841 * 22842 * @param test_case_index Index of test case 22843 * @param stage Shader stage 22844 * @param out_interface Set to "" 22845 **/ 22846 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, 22847 std::string& out_interface) 22848 { 22849 static const GLchar* gs = "const uint sizeof_type = SIZE;\n" 22850 "\n" 22851 "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n" 22852 " flat out TYPE trunks;\n" 22853 "layout (xfb_offset = 0) flat out TYPE goku;\n" 22854 "\n" 22855 /* 22856 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default, 22857 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will 22858 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API 22859 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the 22860 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed, 22861 we need to add the qualifier std140, and change the declaration as layout(binding=0, std140), which can make 22862 sure all the block members are packed and the application can upload the data by glBufferData() directly. 22863 */ 22864 "layout(binding = 0, std140) uniform gs_block {\n" 22865 " TYPE uni_vegeta;\n" 22866 " TYPE uni_trunks;\n" 22867 " TYPE uni_goku;\n" 22868 "};\n"; 22869 static const GLchar* fs = "flat in TYPE vegeta;\n" 22870 "flat in TYPE trunks;\n" 22871 "flat in TYPE goku;\n" 22872 "\n" 22873 "out vec4 fs_out;\n"; 22874 22875 const Utils::Type& type = getType(test_case_index); 22876 22877 switch (stage) 22878 { 22879 case Utils::Shader::FRAGMENT: 22880 out_interface = fs; 22881 break; 22882 case Utils::Shader::GEOMETRY: 22883 out_interface = gs; 22884 break; 22885 default: 22886 out_interface = ""; 22887 return; 22888 } 22889 22890 if (Utils::Shader::GEOMETRY == stage) 22891 { 22892 GLchar buffer[16]; 22893 size_t position = 0; 22894 const GLuint type_size = type.GetSize(); 22895 22896 sprintf(buffer, "%d", type_size); 22897 22898 Utils::replaceToken("SIZE", position, buffer, out_interface); 22899 } 22900 22901 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface); 22902 } 22903 22904 /** Get type name 22905 * 22906 * @param test_case_index Index of test case 22907 * 22908 * @return Name of type test in test_case_index 22909 **/ 22910 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index) 22911 { 22912 return getTypeName(test_case_index); 22913 } 22914 22915 /** Returns number of types to test 22916 * 22917 * @return Number of types, 34 22918 **/ 22919 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber() 22920 { 22921 return getTypesNumber(); 22922 } 22923 22924 /** Inspects program to check if all resources are as expected 22925 * 22926 * @param test_case_index Index of test case 22927 * @param program Program instance 22928 * @param out_stream Error message 22929 * 22930 * @return true if everything is ok, false otherwise 22931 **/ 22932 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program& program, 22933 std::stringstream& out_stream) 22934 { 22935 GLint stride = 0; 22936 const Utils::Type& type = getType(test_case_index); 22937 const GLuint type_size = type.GetSize(false); 22938 22939 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 22940 1 /* buf_size */, &stride); 22941 22942 if ((GLint)(3 * type_size) != stride) 22943 { 22944 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size); 22945 22946 return false; 22947 } 22948 22949 return true; 22950 } 22951 22952 /** Constructor 22953 * 22954 * @param context Test context 22955 **/ 22956 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context& context) 22957 : BufferTestBase(context, "xfb_vertex_streams", 22958 "Test verifies that xfb qualifier works with multiple output streams") 22959 { 22960 /* Nothing to be done here */ 22961 } 22962 22963 /** Get descriptors of buffers necessary for test 22964 * 22965 * @param ignored 22966 * @param out_descriptors Descriptors of buffers used by test 22967 **/ 22968 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 22969 bufferDescriptor::Vector& out_descriptors) 22970 { 22971 const Utils::Type& type = Utils::Type::vec4; 22972 22973 /* Test needs single uniform and three xfbs */ 22974 out_descriptors.resize(4); 22975 22976 /* Get references */ 22977 bufferDescriptor& uniform = out_descriptors[0]; 22978 bufferDescriptor& xfb_1 = out_descriptors[1]; 22979 bufferDescriptor& xfb_2 = out_descriptors[2]; 22980 bufferDescriptor& xfb_3 = out_descriptors[3]; 22981 22982 /* Index */ 22983 uniform.m_index = 0; 22984 xfb_1.m_index = 1; 22985 xfb_2.m_index = 2; 22986 xfb_3.m_index = 3; 22987 22988 /* Target */ 22989 uniform.m_target = Utils::Buffer::Uniform; 22990 xfb_1.m_target = Utils::Buffer::Transform_feedback; 22991 xfb_2.m_target = Utils::Buffer::Transform_feedback; 22992 xfb_3.m_target = Utils::Buffer::Transform_feedback; 22993 22994 /* Data */ 22995 const std::vector<GLubyte>& goku_data = type.GenerateData(); 22996 const std::vector<GLubyte>& gohan_data = type.GenerateData(); 22997 const std::vector<GLubyte>& goten_data = type.GenerateData(); 22998 const std::vector<GLubyte>& picolo_data = type.GenerateData(); 22999 const std::vector<GLubyte>& vegeta_data = type.GenerateData(); 23000 const std::vector<GLubyte>& bulma_data = type.GenerateData(); 23001 23002 const GLuint type_size = static_cast<GLuint>(vegeta_data.size()); 23003 23004 /* Uniform data */ 23005 uniform.m_initial_data.resize(6 * type_size); 23006 memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size); 23007 memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size); 23008 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size); 23009 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size); 23010 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size); 23011 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size); 23012 23013 /* XFB data */ 23014 static const GLuint xfb_stride = 64; 23015 xfb_1.m_initial_data.resize(xfb_stride); 23016 xfb_1.m_expected_data.resize(xfb_stride); 23017 xfb_2.m_initial_data.resize(xfb_stride); 23018 xfb_2.m_expected_data.resize(xfb_stride); 23019 xfb_3.m_initial_data.resize(xfb_stride); 23020 xfb_3.m_expected_data.resize(xfb_stride); 23021 23022 for (GLuint i = 0; i < xfb_stride; ++i) 23023 { 23024 xfb_1.m_initial_data[i] = (glw::GLubyte)i; 23025 xfb_1.m_expected_data[i] = (glw::GLubyte)i; 23026 xfb_2.m_initial_data[i] = (glw::GLubyte)i; 23027 xfb_2.m_expected_data[i] = (glw::GLubyte)i; 23028 xfb_3.m_initial_data[i] = (glw::GLubyte)i; 23029 xfb_3.m_expected_data[i] = (glw::GLubyte)i; 23030 } 23031 23032 memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size); 23033 memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size); 23034 memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size); 23035 memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size); 23036 memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size); 23037 memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size); 23038 } 23039 23040 /** Get body of main function for given shader stage 23041 * 23042 * @param ignored 23043 * @param stage Shader stage 23044 * @param out_assignments Set to empty 23045 * @param out_calculations Set to empty 23046 **/ 23047 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 23048 std::string& out_assignments, std::string& out_calculations) 23049 { 23050 out_calculations = ""; 23051 23052 // the shader declares the output variables with different "stream" qualifier, to make the data can export to 23053 // each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted 23054 // by the GS is assigned to specific stream. 23055 static const GLchar* gs = " goku = uni_goku;\n" 23056 " gohan = uni_gohan;\n" 23057 " goten = uni_goten;\n" 23058 " EmitStreamVertex(0);\n" 23059 " EndStreamPrimitive(0);\n" 23060 " picolo = uni_picolo;\n" 23061 " vegeta = uni_vegeta;\n" 23062 " EmitStreamVertex(1);\n" 23063 " EndStreamPrimitive(1);\n" 23064 " bulma = uni_bulma;\n" 23065 " EmitStreamVertex(2);\n" 23066 " EndStreamPrimitive(2);\n"; 23067 23068 static const GLchar* fs = " fs_out = gohan + goku + goten;\n"; 23069 23070 const GLchar* assignments = ""; 23071 switch (stage) 23072 { 23073 case Utils::Shader::FRAGMENT: 23074 assignments = fs; 23075 break; 23076 case Utils::Shader::GEOMETRY: 23077 assignments = gs; 23078 break; 23079 default: 23080 break; 23081 } 23082 23083 out_assignments = assignments; 23084 } 23085 23086 /** Get interface of shader 23087 * 23088 * @param ignored 23089 * @param stage Shader stage 23090 * @param out_interface Set to "" 23091 **/ 23092 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage, 23093 std::string& out_interface) 23094 { 23095 static const GLchar* gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n" 23096 "layout (xfb_buffer = 2, xfb_stride = 64) out;\n" 23097 "layout (xfb_buffer = 3, xfb_stride = 64) out;\n" 23098 "\n" 23099 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n" 23100 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n" 23101 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n" 23102 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n" 23103 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n" 23104 "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n" 23105 "\n" 23106 "layout(binding = 0) uniform gs_block {\n" 23107 " vec4 uni_goku;\n" 23108 " vec4 uni_gohan;\n" 23109 " vec4 uni_goten;\n" 23110 " vec4 uni_picolo;\n" 23111 " vec4 uni_vegeta;\n" 23112 " vec4 uni_bulma;\n" 23113 "};\n"; 23114 /* 23115 Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader 23116 */ 23117 static const GLchar* fs = "in vec4 goku;\n" 23118 "in vec4 gohan;\n" 23119 "in vec4 goten;\n" 23120 "\n" 23121 "out vec4 fs_out;\n"; 23122 23123 switch (stage) 23124 { 23125 case Utils::Shader::FRAGMENT: 23126 out_interface = fs; 23127 break; 23128 case Utils::Shader::GEOMETRY: 23129 out_interface = gs; 23130 break; 23131 default: 23132 out_interface = ""; 23133 return; 23134 } 23135 } 23136 23137 /** Constructor 23138 * 23139 * @param context Test framework context 23140 **/ 23141 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context& context) 23142 : NegativeTestBase( 23143 context, "xfb_multiple_vertex_streams", 23144 "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer") 23145 { 23146 } 23147 23148 /** Source for given test case and stage 23149 * 23150 * @param ignored 23151 * @param stage Shader stage 23152 * 23153 * @return Shader source 23154 **/ 23155 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage) 23156 { 23157 static const GLchar* var_definition = "const uint valid_stride = 64;\n" 23158 "\n" 23159 "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n" 23160 "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n" 23161 "\n" 23162 "\n" 23163 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n" 23164 "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n" 23165 "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"; 23166 static const GLchar* var_use = " goku = result / 2;\n" 23167 " gohan = result / 4;\n" 23168 " goten = result / 6;\n"; 23169 static const GLchar* fs = "#version 430 core\n" 23170 "#extension GL_ARB_enhanced_layouts : require\n" 23171 "\n" 23172 "in vec4 gs_fs;\n" 23173 "in vec4 goku;\n" 23174 "out vec4 fs_out;\n" 23175 "\n" 23176 "void main()\n" 23177 "{\n" 23178 " fs_out = gs_fs + goku;\n" 23179 "}\n" 23180 "\n"; 23181 static const GLchar* gs = "#version 430 core\n" 23182 "#extension GL_ARB_enhanced_layouts : require\n" 23183 "\n" 23184 "layout(points) in;\n" 23185 "layout(triangle_strip, max_vertices = 4) out;\n" 23186 "\n" 23187 "VAR_DEFINITION" 23188 "\n" 23189 "in vec4 tes_gs[];\n" 23190 "out vec4 gs_fs;\n" 23191 "\n" 23192 "void main()\n" 23193 "{\n" 23194 " vec4 result = tes_gs[0];\n" 23195 "\n" 23196 "VARIABLE_USE" 23197 "\n" 23198 " gs_fs = result;\n" 23199 " gl_Position = vec4(-1, -1, 0, 1);\n" 23200 " EmitVertex();\n" 23201 " gs_fs = result;\n" 23202 " gl_Position = vec4(-1, 1, 0, 1);\n" 23203 " EmitVertex();\n" 23204 " gs_fs = result;\n" 23205 " gl_Position = vec4(1, -1, 0, 1);\n" 23206 " EmitVertex();\n" 23207 " gs_fs = result;\n" 23208 " gl_Position = vec4(1, 1, 0, 1);\n" 23209 " EmitVertex();\n" 23210 "}\n" 23211 "\n"; 23212 static const GLchar* vs = "#version 430 core\n" 23213 "#extension GL_ARB_enhanced_layouts : require\n" 23214 "\n" 23215 "in vec4 in_vs;\n" 23216 "out vec4 vs_tcs;\n" 23217 "\n" 23218 "void main()\n" 23219 "{\n" 23220 " vs_tcs = in_vs;\n" 23221 "}\n" 23222 "\n"; 23223 23224 std::string source; 23225 23226 if (Utils::Shader::GEOMETRY == stage) 23227 { 23228 size_t position = 0; 23229 23230 source = gs; 23231 23232 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 23233 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 23234 } 23235 else 23236 { 23237 switch (stage) 23238 { 23239 case Utils::Shader::FRAGMENT: 23240 source = fs; 23241 break; 23242 case Utils::Shader::VERTEX: 23243 source = vs; 23244 break; 23245 default: 23246 source = ""; 23247 } 23248 } 23249 23250 return source; 23251 } 23252 23253 /** Selects if "compute" stage is relevant for test 23254 * 23255 * @param ignored 23256 * 23257 * @return false 23258 **/ 23259 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */) 23260 { 23261 return false; 23262 } 23263 23264 /** Constructor 23265 * 23266 * @param context Test framework context 23267 **/ 23268 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context& context) 23269 : NegativeTestBase(context, "xfb_exceed_buffer_limit", 23270 "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit") 23271 { 23272 } 23273 23274 /** Source for given test case and stage 23275 * 23276 * @param test_case_index Index of test case 23277 * @param stage Shader stage 23278 * 23279 * @return Shader source 23280 **/ 23281 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 23282 { 23283 static const GLchar* block_var_definition = "const uint buffer_index = BUFFER;\n" 23284 "\n" 23285 "layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n" 23286 " vec4 member;\n" 23287 "} gokuARRAY;\n"; 23288 static const GLchar* global_var_definition = "const uint buffer_index = BUFFER;\n" 23289 "\n" 23290 "layout (xfb_buffer = buffer_index) out;\n"; 23291 static const GLchar* vector_var_definition = "const uint buffer_index = BUFFER;\n" 23292 "\n" 23293 "layout (xfb_buffer = buffer_index) out vec4 gokuARRAY;\n"; 23294 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n"; 23295 static const GLchar* global_use = ""; 23296 static const GLchar* vector_use = " gokuINDEX = result / 2;\n"; 23297 static const GLchar* fs = "#version 430 core\n" 23298 "#extension GL_ARB_enhanced_layouts : require\n" 23299 "\n" 23300 "in vec4 gs_fs;\n" 23301 "out vec4 fs_out;\n" 23302 "\n" 23303 "void main()\n" 23304 "{\n" 23305 " fs_out = gs_fs;\n" 23306 "}\n" 23307 "\n"; 23308 static const GLchar* gs_tested = "#version 430 core\n" 23309 "#extension GL_ARB_enhanced_layouts : require\n" 23310 "\n" 23311 "layout(points) in;\n" 23312 "layout(triangle_strip, max_vertices = 4) out;\n" 23313 "\n" 23314 "VAR_DEFINITION" 23315 "\n" 23316 "in vec4 tes_gs[];\n" 23317 "out vec4 gs_fs;\n" 23318 "\n" 23319 "void main()\n" 23320 "{\n" 23321 " vec4 result = tes_gs[0];\n" 23322 "\n" 23323 "VARIABLE_USE" 23324 "\n" 23325 " gs_fs = result;\n" 23326 " gl_Position = vec4(-1, -1, 0, 1);\n" 23327 " EmitVertex();\n" 23328 " gs_fs = result;\n" 23329 " gl_Position = vec4(-1, 1, 0, 1);\n" 23330 " EmitVertex();\n" 23331 " gs_fs = result;\n" 23332 " gl_Position = vec4(1, -1, 0, 1);\n" 23333 " EmitVertex();\n" 23334 " gs_fs = result;\n" 23335 " gl_Position = vec4(1, 1, 0, 1);\n" 23336 " EmitVertex();\n" 23337 "}\n" 23338 "\n"; 23339 static const GLchar* tcs = "#version 430 core\n" 23340 "#extension GL_ARB_enhanced_layouts : require\n" 23341 "\n" 23342 "layout(vertices = 1) out;\n" 23343 "\n" 23344 "in vec4 vs_tcs[];\n" 23345 "out vec4 tcs_tes[];\n" 23346 "\n" 23347 "void main()\n" 23348 "{\n" 23349 "\n" 23350 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 23351 "\n" 23352 " gl_TessLevelOuter[0] = 1.0;\n" 23353 " gl_TessLevelOuter[1] = 1.0;\n" 23354 " gl_TessLevelOuter[2] = 1.0;\n" 23355 " gl_TessLevelOuter[3] = 1.0;\n" 23356 " gl_TessLevelInner[0] = 1.0;\n" 23357 " gl_TessLevelInner[1] = 1.0;\n" 23358 "}\n" 23359 "\n"; 23360 static const GLchar* tcs_tested = "#version 430 core\n" 23361 "#extension GL_ARB_enhanced_layouts : require\n" 23362 "\n" 23363 "layout(vertices = 1) out;\n" 23364 "\n" 23365 "VAR_DEFINITION" 23366 "\n" 23367 "in vec4 vs_tcs[];\n" 23368 "out vec4 tcs_tes[];\n" 23369 "\n" 23370 "void main()\n" 23371 "{\n" 23372 " vec4 result = vs_tcs[gl_InvocationID];\n" 23373 "\n" 23374 "VARIABLE_USE" 23375 "\n" 23376 " tcs_tes[gl_InvocationID] = result;\n" 23377 "\n" 23378 " gl_TessLevelOuter[0] = 1.0;\n" 23379 " gl_TessLevelOuter[1] = 1.0;\n" 23380 " gl_TessLevelOuter[2] = 1.0;\n" 23381 " gl_TessLevelOuter[3] = 1.0;\n" 23382 " gl_TessLevelInner[0] = 1.0;\n" 23383 " gl_TessLevelInner[1] = 1.0;\n" 23384 "}\n" 23385 "\n"; 23386 static const GLchar* tes_tested = "#version 430 core\n" 23387 "#extension GL_ARB_enhanced_layouts : require\n" 23388 "\n" 23389 "layout(isolines, point_mode) in;\n" 23390 "\n" 23391 "VAR_DEFINITION" 23392 "\n" 23393 "in vec4 tcs_tes[];\n" 23394 "out vec4 tes_gs;\n" 23395 "\n" 23396 "void main()\n" 23397 "{\n" 23398 " vec4 result = tcs_tes[0];\n" 23399 "\n" 23400 "VARIABLE_USE" 23401 "\n" 23402 " tes_gs += result;\n" 23403 "}\n" 23404 "\n"; 23405 static const GLchar* vs = "#version 430 core\n" 23406 "#extension GL_ARB_enhanced_layouts : require\n" 23407 "\n" 23408 "in vec4 in_vs;\n" 23409 "out vec4 vs_tcs;\n" 23410 "\n" 23411 "void main()\n" 23412 "{\n" 23413 " vs_tcs = in_vs;\n" 23414 "}\n" 23415 "\n"; 23416 static const GLchar* vs_tested = "#version 430 core\n" 23417 "#extension GL_ARB_enhanced_layouts : require\n" 23418 "\n" 23419 "VAR_DEFINITION" 23420 "\n" 23421 "in vec4 in_vs;\n" 23422 "out vec4 vs_tcs;\n" 23423 "\n" 23424 "void main()\n" 23425 "{\n" 23426 " vec4 result = in_vs;\n" 23427 "\n" 23428 "VARIABLE_USE" 23429 "\n" 23430 " vs_tcs = result;\n" 23431 "}\n" 23432 "\n"; 23433 23434 std::string source; 23435 testCase& test_case = m_test_cases[test_case_index]; 23436 23437 if (test_case.m_stage == stage) 23438 { 23439 const GLchar* array = ""; 23440 GLchar buffer[16]; 23441 const Functions& gl = m_context.getRenderContext().getFunctions(); 23442 const GLchar* index = ""; 23443 GLint max_n_xfb = 0; 23444 size_t position = 0; 23445 size_t temp; 23446 const GLchar* var_definition = 0; 23447 const GLchar* var_use = 0; 23448 23449 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb); 23450 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 23451 23452 sprintf(buffer, "%d", max_n_xfb); 23453 23454 switch (test_case.m_case) 23455 { 23456 case BLOCK: 23457 var_definition = block_var_definition; 23458 var_use = block_use; 23459 break; 23460 case GLOBAL: 23461 var_definition = global_var_definition; 23462 var_use = global_use; 23463 break; 23464 case VECTOR: 23465 var_definition = vector_var_definition; 23466 var_use = vector_use; 23467 break; 23468 default: 23469 TCU_FAIL("Invalid enum"); 23470 } 23471 23472 switch (stage) 23473 { 23474 case Utils::Shader::GEOMETRY: 23475 source = gs_tested; 23476 array = "[]"; 23477 index = "[0]"; 23478 break; 23479 case Utils::Shader::TESS_CTRL: 23480 source = tcs_tested; 23481 array = "[]"; 23482 index = "[gl_InvocationID]"; 23483 break; 23484 case Utils::Shader::TESS_EVAL: 23485 source = tes_tested; 23486 array = "[]"; 23487 index = "[0]"; 23488 break; 23489 case Utils::Shader::VERTEX: 23490 source = vs_tested; 23491 break; 23492 default: 23493 TCU_FAIL("Invalid enum"); 23494 } 23495 23496 temp = position; 23497 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 23498 position = temp; 23499 Utils::replaceToken("BUFFER", position, buffer, source); 23500 if (GLOBAL != test_case.m_case) 23501 { 23502 Utils::replaceToken("ARRAY", position, array, source); 23503 } 23504 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 23505 23506 Utils::replaceAllTokens("INDEX", index, source); 23507 } 23508 else 23509 { 23510 switch (test_case.m_stage) 23511 { 23512 case Utils::Shader::GEOMETRY: 23513 switch (stage) 23514 { 23515 case Utils::Shader::FRAGMENT: 23516 source = fs; 23517 break; 23518 case Utils::Shader::VERTEX: 23519 source = vs; 23520 break; 23521 default: 23522 source = ""; 23523 } 23524 break; 23525 case Utils::Shader::TESS_CTRL: 23526 switch (stage) 23527 { 23528 case Utils::Shader::FRAGMENT: 23529 source = fs; 23530 break; 23531 case Utils::Shader::VERTEX: 23532 source = vs; 23533 break; 23534 default: 23535 source = ""; 23536 } 23537 break; 23538 case Utils::Shader::TESS_EVAL: 23539 switch (stage) 23540 { 23541 case Utils::Shader::FRAGMENT: 23542 source = fs; 23543 break; 23544 case Utils::Shader::TESS_CTRL: 23545 source = tcs; 23546 break; 23547 case Utils::Shader::VERTEX: 23548 source = vs; 23549 break; 23550 default: 23551 source = ""; 23552 } 23553 break; 23554 case Utils::Shader::VERTEX: 23555 switch (stage) 23556 { 23557 case Utils::Shader::FRAGMENT: 23558 source = fs; 23559 break; 23560 default: 23561 source = ""; 23562 } 23563 break; 23564 default: 23565 TCU_FAIL("Invalid enum"); 23566 break; 23567 } 23568 } 23569 23570 return source; 23571 } 23572 23573 /** Get description of test case 23574 * 23575 * @param test_case_index Index of test case 23576 * 23577 * @return Test case description 23578 **/ 23579 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index) 23580 { 23581 std::stringstream stream; 23582 testCase& test_case = m_test_cases[test_case_index]; 23583 23584 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: "; 23585 23586 switch (test_case.m_case) 23587 { 23588 case BLOCK: 23589 stream << "BLOCK"; 23590 break; 23591 case GLOBAL: 23592 stream << "GLOBAL"; 23593 break; 23594 case VECTOR: 23595 stream << "VECTOR"; 23596 break; 23597 default: 23598 TCU_FAIL("Invalid enum"); 23599 } 23600 23601 return stream.str(); 23602 } 23603 23604 /** Get number of test cases 23605 * 23606 * @return Number of test cases 23607 **/ 23608 GLuint XFBExceedBufferLimitTest::getTestCaseNumber() 23609 { 23610 return static_cast<GLuint>(m_test_cases.size()); 23611 } 23612 23613 /** Selects if "compute" stage is relevant for test 23614 * 23615 * @param ignored 23616 * 23617 * @return false 23618 **/ 23619 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */) 23620 { 23621 return false; 23622 } 23623 23624 /** Prepare all test cases 23625 * 23626 **/ 23627 void XFBExceedBufferLimitTest::testInit() 23628 { 23629 for (GLuint c = 0; c < CASE_MAX; ++c) 23630 { 23631 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 23632 { 23633 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 23634 (Utils::Shader::FRAGMENT == stage)) 23635 { 23636 continue; 23637 } 23638 23639 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage }; 23640 23641 m_test_cases.push_back(test_case); 23642 } 23643 } 23644 } 23645 23646 /** Constructor 23647 * 23648 * @param context Test framework context 23649 **/ 23650 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context& context) 23651 : NegativeTestBase(context, "xfb_exceed_offset_limit", 23652 "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit") 23653 { 23654 } 23655 23656 /** Source for given test case and stage 23657 * 23658 * @param test_case_index Index of test case 23659 * @param stage Shader stage 23660 * 23661 * @return Shader source 23662 **/ 23663 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 23664 { 23665 static const GLchar* block_var_definition = "const uint max_size = SIZE;\n" 23666 "\n" 23667 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out Goku {\n" 23668 " vec4 member;\n" 23669 "} gokuARRAY;\n"; 23670 static const GLchar* global_var_definition = "const uint max_size = SIZE;\n" 23671 "\n" 23672 "layout (xfb_buffer = 0, xfb_stride = max_size + 16) out;\n"; 23673 static const GLchar* vector_var_definition = 23674 "const uint max_size = SIZE;\n" 23675 "\n" 23676 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out vec4 gokuARRAY;\n"; 23677 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n"; 23678 static const GLchar* global_use = ""; 23679 static const GLchar* vector_use = " gokuINDEX = result / 2;\n"; 23680 static const GLchar* fs = "#version 430 core\n" 23681 "#extension GL_ARB_enhanced_layouts : require\n" 23682 "\n" 23683 "in vec4 gs_fs;\n" 23684 "out vec4 fs_out;\n" 23685 "\n" 23686 "void main()\n" 23687 "{\n" 23688 " fs_out = gs_fs;\n" 23689 "}\n" 23690 "\n"; 23691 static const GLchar* gs_tested = "#version 430 core\n" 23692 "#extension GL_ARB_enhanced_layouts : require\n" 23693 "\n" 23694 "layout(points) in;\n" 23695 "layout(triangle_strip, max_vertices = 4) out;\n" 23696 "\n" 23697 "VAR_DEFINITION" 23698 "\n" 23699 "in vec4 tes_gs[];\n" 23700 "out vec4 gs_fs;\n" 23701 "\n" 23702 "void main()\n" 23703 "{\n" 23704 " vec4 result = tes_gs[0];\n" 23705 "\n" 23706 "VARIABLE_USE" 23707 "\n" 23708 " gs_fs = result;\n" 23709 " gl_Position = vec4(-1, -1, 0, 1);\n" 23710 " EmitVertex();\n" 23711 " gs_fs = result;\n" 23712 " gl_Position = vec4(-1, 1, 0, 1);\n" 23713 " EmitVertex();\n" 23714 " gs_fs = result;\n" 23715 " gl_Position = vec4(1, -1, 0, 1);\n" 23716 " EmitVertex();\n" 23717 " gs_fs = result;\n" 23718 " gl_Position = vec4(1, 1, 0, 1);\n" 23719 " EmitVertex();\n" 23720 "}\n" 23721 "\n"; 23722 static const GLchar* tcs = "#version 430 core\n" 23723 "#extension GL_ARB_enhanced_layouts : require\n" 23724 "\n" 23725 "layout(vertices = 1) out;\n" 23726 "\n" 23727 "in vec4 vs_tcs[];\n" 23728 "out vec4 tcs_tes[];\n" 23729 "\n" 23730 "void main()\n" 23731 "{\n" 23732 "\n" 23733 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 23734 "\n" 23735 " gl_TessLevelOuter[0] = 1.0;\n" 23736 " gl_TessLevelOuter[1] = 1.0;\n" 23737 " gl_TessLevelOuter[2] = 1.0;\n" 23738 " gl_TessLevelOuter[3] = 1.0;\n" 23739 " gl_TessLevelInner[0] = 1.0;\n" 23740 " gl_TessLevelInner[1] = 1.0;\n" 23741 "}\n" 23742 "\n"; 23743 static const GLchar* tcs_tested = "#version 430 core\n" 23744 "#extension GL_ARB_enhanced_layouts : require\n" 23745 "\n" 23746 "layout(vertices = 1) out;\n" 23747 "\n" 23748 "VAR_DEFINITION" 23749 "\n" 23750 "in vec4 vs_tcs[];\n" 23751 "out vec4 tcs_tes[];\n" 23752 "\n" 23753 "void main()\n" 23754 "{\n" 23755 " vec4 result = vs_tcs[gl_InvocationID];\n" 23756 "\n" 23757 "VARIABLE_USE" 23758 "\n" 23759 " tcs_tes[gl_InvocationID] = result;\n" 23760 "\n" 23761 " gl_TessLevelOuter[0] = 1.0;\n" 23762 " gl_TessLevelOuter[1] = 1.0;\n" 23763 " gl_TessLevelOuter[2] = 1.0;\n" 23764 " gl_TessLevelOuter[3] = 1.0;\n" 23765 " gl_TessLevelInner[0] = 1.0;\n" 23766 " gl_TessLevelInner[1] = 1.0;\n" 23767 "}\n" 23768 "\n"; 23769 static const GLchar* tes_tested = "#version 430 core\n" 23770 "#extension GL_ARB_enhanced_layouts : require\n" 23771 "\n" 23772 "layout(isolines, point_mode) in;\n" 23773 "\n" 23774 "VAR_DEFINITION" 23775 "\n" 23776 "in vec4 tcs_tes[];\n" 23777 "out vec4 tes_gs;\n" 23778 "\n" 23779 "void main()\n" 23780 "{\n" 23781 " vec4 result = tcs_tes[0];\n" 23782 "\n" 23783 "VARIABLE_USE" 23784 "\n" 23785 " tes_gs += result;\n" 23786 "}\n" 23787 "\n"; 23788 static const GLchar* vs = "#version 430 core\n" 23789 "#extension GL_ARB_enhanced_layouts : require\n" 23790 "\n" 23791 "in vec4 in_vs;\n" 23792 "out vec4 vs_tcs;\n" 23793 "\n" 23794 "void main()\n" 23795 "{\n" 23796 " vs_tcs = in_vs;\n" 23797 "}\n" 23798 "\n"; 23799 static const GLchar* vs_tested = "#version 430 core\n" 23800 "#extension GL_ARB_enhanced_layouts : require\n" 23801 "\n" 23802 "VAR_DEFINITION" 23803 "\n" 23804 "in vec4 in_vs;\n" 23805 "out vec4 vs_tcs;\n" 23806 "\n" 23807 "void main()\n" 23808 "{\n" 23809 " vec4 result = in_vs;\n" 23810 "\n" 23811 "VARIABLE_USE" 23812 "\n" 23813 " vs_tcs = result;\n" 23814 "}\n" 23815 "\n"; 23816 23817 std::string source; 23818 testCase& test_case = m_test_cases[test_case_index]; 23819 23820 if (test_case.m_stage == stage) 23821 { 23822 const GLchar* array = ""; 23823 GLchar buffer[16]; 23824 const Functions& gl = m_context.getRenderContext().getFunctions(); 23825 const GLchar* index = ""; 23826 GLint max_n_xfb_comp = 0; 23827 GLint max_n_xfb_bytes = 0; 23828 size_t position = 0; 23829 size_t temp; 23830 const GLchar* var_definition = 0; 23831 const GLchar* var_use = 0; 23832 23833 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp); 23834 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 23835 23836 max_n_xfb_bytes = max_n_xfb_comp * 4; 23837 23838 sprintf(buffer, "%d", max_n_xfb_bytes); 23839 23840 switch (test_case.m_case) 23841 { 23842 case BLOCK: 23843 var_definition = block_var_definition; 23844 var_use = block_use; 23845 break; 23846 case GLOBAL: 23847 var_definition = global_var_definition; 23848 var_use = global_use; 23849 break; 23850 case VECTOR: 23851 var_definition = vector_var_definition; 23852 var_use = vector_use; 23853 break; 23854 default: 23855 TCU_FAIL("Invalid enum"); 23856 } 23857 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73) 23858 // change array = "[]" to "[1]" 23859 switch (stage) 23860 { 23861 case Utils::Shader::GEOMETRY: 23862 source = gs_tested; 23863 array = "[1]"; 23864 index = "[0]"; 23865 break; 23866 case Utils::Shader::TESS_CTRL: 23867 source = tcs_tested; 23868 array = "[1]"; 23869 index = "[gl_InvocationID]"; 23870 break; 23871 case Utils::Shader::TESS_EVAL: 23872 source = tes_tested; 23873 array = "[1]"; 23874 index = "[0]"; 23875 break; 23876 case Utils::Shader::VERTEX: 23877 source = vs_tested; 23878 break; 23879 default: 23880 TCU_FAIL("Invalid enum"); 23881 } 23882 23883 temp = position; 23884 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 23885 position = temp; 23886 Utils::replaceToken("SIZE", position, buffer, source); 23887 if (GLOBAL != test_case.m_case) 23888 { 23889 Utils::replaceToken("ARRAY", position, array, source); 23890 } 23891 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 23892 23893 Utils::replaceAllTokens("INDEX", index, source); 23894 } 23895 else 23896 { 23897 switch (test_case.m_stage) 23898 { 23899 case Utils::Shader::GEOMETRY: 23900 switch (stage) 23901 { 23902 case Utils::Shader::FRAGMENT: 23903 source = fs; 23904 break; 23905 case Utils::Shader::VERTEX: 23906 source = vs; 23907 break; 23908 default: 23909 source = ""; 23910 } 23911 break; 23912 case Utils::Shader::TESS_CTRL: 23913 switch (stage) 23914 { 23915 case Utils::Shader::FRAGMENT: 23916 source = fs; 23917 break; 23918 case Utils::Shader::VERTEX: 23919 source = vs; 23920 break; 23921 default: 23922 source = ""; 23923 } 23924 break; 23925 case Utils::Shader::TESS_EVAL: 23926 switch (stage) 23927 { 23928 case Utils::Shader::FRAGMENT: 23929 source = fs; 23930 break; 23931 case Utils::Shader::TESS_CTRL: 23932 source = tcs; 23933 break; 23934 case Utils::Shader::VERTEX: 23935 source = vs; 23936 break; 23937 default: 23938 source = ""; 23939 } 23940 break; 23941 case Utils::Shader::VERTEX: 23942 switch (stage) 23943 { 23944 case Utils::Shader::FRAGMENT: 23945 source = fs; 23946 break; 23947 default: 23948 source = ""; 23949 } 23950 break; 23951 default: 23952 TCU_FAIL("Invalid enum"); 23953 break; 23954 } 23955 } 23956 23957 return source; 23958 } 23959 23960 /** Get description of test case 23961 * 23962 * @param test_case_index Index of test case 23963 * 23964 * @return Test case description 23965 **/ 23966 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index) 23967 { 23968 std::stringstream stream; 23969 testCase& test_case = m_test_cases[test_case_index]; 23970 23971 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: "; 23972 23973 switch (test_case.m_case) 23974 { 23975 case BLOCK: 23976 stream << "BLOCK"; 23977 break; 23978 case GLOBAL: 23979 stream << "GLOBAL"; 23980 break; 23981 case VECTOR: 23982 stream << "VECTOR"; 23983 break; 23984 default: 23985 TCU_FAIL("Invalid enum"); 23986 } 23987 23988 return stream.str(); 23989 } 23990 23991 /** Get number of test cases 23992 * 23993 * @return Number of test cases 23994 **/ 23995 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber() 23996 { 23997 return static_cast<GLuint>(m_test_cases.size()); 23998 } 23999 24000 /** Selects if "compute" stage is relevant for test 24001 * 24002 * @param ignored 24003 * 24004 * @return false 24005 **/ 24006 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */) 24007 { 24008 return false; 24009 } 24010 24011 /** Prepare all test cases 24012 * 24013 **/ 24014 void XFBExceedOffsetLimitTest::testInit() 24015 { 24016 for (GLuint c = 0; c < CASE_MAX; ++c) 24017 { 24018 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 24019 { 24020 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 24021 (Utils::Shader::FRAGMENT == stage)) 24022 { 24023 continue; 24024 } 24025 24026 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage }; 24027 24028 m_test_cases.push_back(test_case); 24029 } 24030 } 24031 } 24032 24033 /** Constructor 24034 * 24035 * @param context Test context 24036 **/ 24037 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context& context) 24038 : BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected") 24039 { 24040 /* Nothing to be done here */ 24041 } 24042 24043 /** Get descriptors of buffers necessary for test 24044 * 24045 * @param test_case_index Index of test case 24046 * @param out_descriptors Descriptors of buffers used by test 24047 **/ 24048 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors) 24049 { 24050 // the function "getType(test_case_index)" can't return correct data type, so change code as following: 24051 const Utils::Type& type = m_test_cases[test_case_index].m_type; 24052 24053 /* Test needs single uniform and two xfbs */ 24054 out_descriptors.resize(3); 24055 24056 /* Get references */ 24057 bufferDescriptor& uniform = out_descriptors[0]; 24058 bufferDescriptor& xfb_1 = out_descriptors[1]; 24059 bufferDescriptor& xfb_3 = out_descriptors[2]; 24060 24061 /* Index */ 24062 uniform.m_index = 0; 24063 xfb_1.m_index = 1; 24064 xfb_3.m_index = 3; 24065 24066 /* Target */ 24067 uniform.m_target = Utils::Buffer::Uniform; 24068 xfb_1.m_target = Utils::Buffer::Transform_feedback; 24069 xfb_3.m_target = Utils::Buffer::Transform_feedback; 24070 24071 /* Data */ 24072 const GLuint gen_start = Utils::s_rand; 24073 const std::vector<GLubyte>& chichi_data = type.GenerateData(); 24074 const std::vector<GLubyte>& bulma_data = type.GenerateData(); 24075 const std::vector<GLubyte>& trunks_data = type.GenerateData(); 24076 const std::vector<GLubyte>& bra_data = type.GenerateData(); 24077 const std::vector<GLubyte>& gohan_data = type.GenerateData(); 24078 const std::vector<GLubyte>& goten_data = type.GenerateData(); 24079 24080 Utils::s_rand = gen_start; 24081 const std::vector<GLubyte>& chichi_data_pck = type.GenerateDataPacked(); 24082 const std::vector<GLubyte>& bulma_data_pck = type.GenerateDataPacked(); 24083 const std::vector<GLubyte>& trunks_data_pck = type.GenerateDataPacked(); 24084 const std::vector<GLubyte>& bra_data_pck = type.GenerateDataPacked(); 24085 const std::vector<GLubyte>& gohan_data_pck = type.GenerateDataPacked(); 24086 const std::vector<GLubyte>& goten_data_pck = type.GenerateDataPacked(); 24087 24088 const GLuint type_size = static_cast<GLuint>(chichi_data.size()); 24089 const GLuint type_size_pck = static_cast<GLuint>(chichi_data_pck.size()); 24090 24091 /* Uniform data */ 24092 uniform.m_initial_data.resize(6 * type_size); 24093 memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size); 24094 memcpy(&uniform.m_initial_data[0] + type_size, &bulma_data[0], type_size); 24095 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &trunks_data[0], type_size); 24096 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &bra_data[0], type_size); 24097 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &gohan_data[0], type_size); 24098 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &goten_data[0], type_size); 24099 24100 /* XFB data */ 24101 xfb_1.m_initial_data.resize(3 * type_size_pck); 24102 xfb_1.m_expected_data.resize(3 * type_size_pck); 24103 xfb_3.m_initial_data.resize(3 * type_size_pck); 24104 xfb_3.m_expected_data.resize(3 * type_size_pck); 24105 24106 for (GLuint i = 0; i < 3 * type_size_pck; ++i) 24107 { 24108 xfb_1.m_initial_data[i] = (glw::GLubyte)i; 24109 xfb_1.m_expected_data[i] = (glw::GLubyte)i; 24110 xfb_3.m_initial_data[i] = (glw::GLubyte)i; 24111 xfb_3.m_expected_data[i] = (glw::GLubyte)i; 24112 } 24113 24114 memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck); 24115 memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck); 24116 memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck); 24117 memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck); 24118 memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck); 24119 memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck); 24120 } 24121 24122 /** Source for given test case and stage 24123 * 24124 * @param test_case_index Index of test case 24125 * @param stage Shader stage 24126 * 24127 * @return Shader source 24128 **/ 24129 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 24130 { 24131 static const GLchar* fs = 24132 "#version 430 core\n" 24133 "#extension GL_ARB_enhanced_layouts : require\n" 24134 "\n" 24135 "flat in TYPE chichi;\n" 24136 "flat in TYPE bulma;\n" 24137 "in Vegeta {\n" 24138 " flat TYPE trunk;\n" 24139 " flat TYPE bra;\n" 24140 "} vegeta;\n" 24141 "in Goku {\n" 24142 " flat TYPE gohan;\n" 24143 " flat TYPE goten;\n" 24144 "} goku;\n" 24145 "\n" 24146 "out vec4 fs_out;\n" 24147 "\n" 24148 "void main()\n" 24149 "{\n" 24150 " fs_out = vec4(1);\n" 24151 " if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n" 24152 " {\n" 24153 " fs_out = vec4(0);\n" 24154 " }\n" 24155 "}\n" 24156 "\n"; 24157 24158 static const GLchar* gs = "#version 430 core\n" 24159 "#extension GL_ARB_enhanced_layouts : require\n" 24160 "\n" 24161 "layout(points) in;\n" 24162 "layout(points, max_vertices = 1) out;\n" 24163 "\n" 24164 "INTERFACE" 24165 "\n" 24166 "void main()\n" 24167 "{\n" 24168 "ASSIGNMENTS" 24169 " EmitVertex();\n" 24170 "}\n" 24171 "\n"; 24172 24173 static const GLchar* tcs = "#version 430 core\n" 24174 "#extension GL_ARB_enhanced_layouts : require\n" 24175 "\n" 24176 "layout(vertices = 1) out;\n" 24177 "\n" 24178 "\n" 24179 "void main()\n" 24180 "{\n" 24181 " gl_TessLevelOuter[0] = 1.0;\n" 24182 " gl_TessLevelOuter[1] = 1.0;\n" 24183 " gl_TessLevelOuter[2] = 1.0;\n" 24184 " gl_TessLevelOuter[3] = 1.0;\n" 24185 " gl_TessLevelInner[0] = 1.0;\n" 24186 " gl_TessLevelInner[1] = 1.0;\n" 24187 "}\n" 24188 "\n"; 24189 24190 static const GLchar* tes = "#version 430 core\n" 24191 "#extension GL_ARB_enhanced_layouts : require\n" 24192 "\n" 24193 "layout(isolines, point_mode) in;\n" 24194 "\n" 24195 "INTERFACE" 24196 "\n" 24197 "void main()\n" 24198 "{\n" 24199 "ASSIGNMENTS" 24200 "}\n" 24201 "\n"; 24202 24203 static const GLchar* vs = "#version 430 core\n" 24204 "#extension GL_ARB_enhanced_layouts : require\n" 24205 "\n" 24206 "void main()\n" 24207 "{\n" 24208 "}\n" 24209 "\n"; 24210 24211 static const GLchar* vs_tested = "#version 430 core\n" 24212 "#extension GL_ARB_enhanced_layouts : require\n" 24213 "\n" 24214 "INTERFACE" 24215 "\n" 24216 "void main()\n" 24217 "{\n" 24218 "ASSIGNMENTS" 24219 "}\n" 24220 "\n"; 24221 24222 std::string source; 24223 const _testCase& test_case = m_test_cases[test_case_index]; 24224 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 24225 24226 if (test_case.m_stage == stage) 24227 { 24228 std::string assignments = " chichi = uni_chichi;\n" 24229 " bulma = uni_bulma;\n" 24230 " vegeta.trunk = uni_trunk;\n" 24231 " vegeta.bra = uni_bra;\n" 24232 " goku.gohan = uni_gohan;\n" 24233 " goku.goten = uni_goten;\n"; 24234 24235 std::string interface = "layout (xfb_buffer = 3) out;\n" 24236 "\n" 24237 "const uint type_size = SIZE;\n" 24238 "\n" 24239 "layout ( xfb_offset = 2 * type_size) flat out TYPE chichi;\n" 24240 "layout (xfb_buffer = 1, xfb_offset = 0) flat out TYPE bulma;\n" 24241 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n" 24242 " flat TYPE trunk;\n" 24243 " flat TYPE bra;\n" 24244 "} vegeta;\n" 24245 "layout ( xfb_offset = 0) out Goku {\n" 24246 " flat TYPE gohan;\n" 24247 " flat TYPE goten;\n" 24248 "} goku;\n" 24249 "\n" 24250 // Uniform block must be declared with std140, otherwise each block member is not packed 24251 "layout(binding = 0, std140) uniform block {\n" 24252 " TYPE uni_chichi;\n" 24253 " TYPE uni_bulma;\n" 24254 " TYPE uni_trunk;\n" 24255 " TYPE uni_bra;\n" 24256 " TYPE uni_gohan;\n" 24257 " TYPE uni_goten;\n" 24258 "};\n"; 24259 24260 /* Prepare interface string */ 24261 { 24262 GLchar buffer[16]; 24263 size_t position = 0; 24264 const GLuint type_size = test_case.m_type.GetSize(); 24265 24266 sprintf(buffer, "%d", type_size); 24267 24268 Utils::replaceToken("SIZE", position, buffer, interface); 24269 Utils::replaceAllTokens("TYPE", type_name, interface); 24270 } 24271 24272 switch (stage) 24273 { 24274 case Utils::Shader::GEOMETRY: 24275 source = gs; 24276 break; 24277 case Utils::Shader::TESS_EVAL: 24278 source = tes; 24279 break; 24280 case Utils::Shader::VERTEX: 24281 source = vs_tested; 24282 break; 24283 default: 24284 TCU_FAIL("Invalid enum"); 24285 } 24286 24287 /* Replace tokens */ 24288 { 24289 size_t position = 0; 24290 24291 Utils::replaceToken("INTERFACE", position, interface.c_str(), source); 24292 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source); 24293 } 24294 } 24295 else 24296 { 24297 switch (test_case.m_stage) 24298 { 24299 case Utils::Shader::GEOMETRY: 24300 switch (stage) 24301 { 24302 case Utils::Shader::FRAGMENT: 24303 source = fs; 24304 Utils::replaceAllTokens("TYPE", type_name, source); 24305 break; 24306 case Utils::Shader::VERTEX: 24307 source = vs; 24308 break; 24309 default: 24310 source = ""; 24311 } 24312 break; 24313 case Utils::Shader::TESS_EVAL: 24314 switch (stage) 24315 { 24316 case Utils::Shader::FRAGMENT: 24317 source = fs; 24318 Utils::replaceAllTokens("TYPE", type_name, source); 24319 break; 24320 case Utils::Shader::TESS_CTRL: 24321 source = tcs; 24322 break; 24323 case Utils::Shader::VERTEX: 24324 source = vs; 24325 break; 24326 default: 24327 source = ""; 24328 } 24329 break; 24330 case Utils::Shader::VERTEX: 24331 switch (stage) 24332 { 24333 case Utils::Shader::FRAGMENT: 24334 source = fs; 24335 Utils::replaceAllTokens("TYPE", type_name, source); 24336 break; 24337 default: 24338 source = ""; 24339 } 24340 break; 24341 default: 24342 TCU_FAIL("Invalid enum"); 24343 break; 24344 } 24345 } 24346 24347 return source; 24348 } 24349 24350 /** Get name of test case 24351 * 24352 * @param test_case_index Index of test case 24353 * 24354 * @return Name of case 24355 **/ 24356 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index) 24357 { 24358 std::string name; 24359 const _testCase& test_case = m_test_cases[test_case_index]; 24360 24361 name = "Tested stage: "; 24362 name.append(Utils::Shader::GetStageName(test_case.m_stage)); 24363 name.append(". Tested type: "); 24364 name.append(test_case.m_type.GetGLSLTypeName()); 24365 24366 return name; 24367 } 24368 24369 /** Get number of cases 24370 * 24371 * @return Number of test cases 24372 **/ 24373 GLuint XFBGlobalBufferTest::getTestCaseNumber() 24374 { 24375 return static_cast<GLuint>(m_test_cases.size()); 24376 } 24377 24378 /** Prepare set of test cases 24379 * 24380 **/ 24381 void XFBGlobalBufferTest::testInit() 24382 { 24383 GLuint n_types = getTypesNumber(); 24384 24385 for (GLuint i = 0; i < n_types; ++i) 24386 { 24387 const Utils::Type& type = getType(i); 24388 /* 24389 When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will 24390 cause a link time error. 24391 */ 24392 if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 || 24393 strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0) 24394 { 24395 continue; 24396 } 24397 const _testCase test_cases[] = { { Utils::Shader::VERTEX, type }, 24398 { Utils::Shader::GEOMETRY, type }, 24399 { Utils::Shader::TESS_EVAL, type } }; 24400 24401 m_test_cases.push_back(test_cases[0]); 24402 m_test_cases.push_back(test_cases[1]); 24403 m_test_cases.push_back(test_cases[2]); 24404 } 24405 } 24406 24407 /** Constructor 24408 * 24409 * @param context Test context 24410 **/ 24411 XFBStrideTest::XFBStrideTest(deqp::Context& context) 24412 : BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types") 24413 { 24414 /* Nothing to be done here */ 24415 } 24416 24417 /** Execute drawArrays for single vertex 24418 * 24419 * @param test_case_index 24420 * 24421 * @return true 24422 **/ 24423 bool XFBStrideTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 24424 { 24425 const Functions& gl = m_context.getRenderContext().getFunctions(); 24426 GLenum primitive_type = GL_PATCHES; 24427 const testCase& test_case = m_test_cases[test_case_index]; 24428 24429 if (Utils::Shader::VERTEX == test_case.m_stage) 24430 { 24431 primitive_type = GL_POINTS; 24432 } 24433 24434 gl.disable(GL_RASTERIZER_DISCARD); 24435 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 24436 24437 gl.beginTransformFeedback(GL_POINTS); 24438 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 24439 24440 gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */); 24441 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 24442 24443 gl.endTransformFeedback(); 24444 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 24445 24446 return true; 24447 } 24448 24449 /** Get descriptors of buffers necessary for test 24450 * 24451 * @param test_case_index Index of test case 24452 * @param out_descriptors Descriptors of buffers used by test 24453 **/ 24454 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors) 24455 { 24456 const testCase& test_case = m_test_cases[test_case_index]; 24457 const Utils::Type& type = test_case.m_type; 24458 24459 /* Test needs single uniform and xfb */ 24460 out_descriptors.resize(2); 24461 24462 /* Get references */ 24463 bufferDescriptor& uniform = out_descriptors[0]; 24464 bufferDescriptor& xfb = out_descriptors[1]; 24465 24466 /* Index */ 24467 uniform.m_index = 0; 24468 xfb.m_index = 0; 24469 24470 /* Target */ 24471 uniform.m_target = Utils::Buffer::Uniform; 24472 xfb.m_target = Utils::Buffer::Transform_feedback; 24473 24474 /* Data */ 24475 const GLuint rand_start = Utils::s_rand; 24476 const std::vector<GLubyte>& uniform_data = type.GenerateData(); 24477 24478 Utils::s_rand = rand_start; 24479 const std::vector<GLubyte>& xfb_data = type.GenerateDataPacked(); 24480 24481 const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size()); 24482 const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size()); 24483 /* 24484 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer, 24485 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;", 24486 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader 24487 only one valid data should be initialized in xfb.m_expected_data 24488 */ 24489 const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2; 24490 /* Uniform data */ 24491 uniform.m_initial_data.resize(uni_type_size); 24492 memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size); 24493 24494 /* XFB data */ 24495 xfb.m_initial_data.resize(xfb_data_size); 24496 xfb.m_expected_data.resize(xfb_data_size); 24497 24498 for (GLuint i = 0; i < xfb_data_size; ++i) 24499 { 24500 xfb.m_initial_data[i] = (glw::GLubyte)i; 24501 xfb.m_expected_data[i] = (glw::GLubyte)i; 24502 } 24503 24504 if (test_case.m_stage == Utils::Shader::VERTEX) 24505 { 24506 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size); 24507 } 24508 else 24509 { 24510 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size); 24511 memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size); 24512 } 24513 } 24514 24515 /** Get body of main function for given shader stage 24516 * 24517 * @param test_case_index Index of test case 24518 * @param stage Shader stage 24519 * @param out_assignments Set to empty 24520 * @param out_calculations Set to empty 24521 **/ 24522 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments, 24523 std::string& out_calculations) 24524 { 24525 const testCase& test_case = m_test_cases[test_case_index]; 24526 24527 out_calculations = ""; 24528 24529 static const GLchar* vs_tes_gs = " goku = uni_goku;\n"; 24530 static const GLchar* fs = " fs_out = vec4(1, 0.25, 0.5, 0.75);\n" 24531 " if (TYPE(0) == goku)\n" 24532 " {\n" 24533 " fs_out = vec4(1, 0.75, 0.5, 0.5);\n" 24534 " }\n"; 24535 24536 const GLchar* assignments = ""; 24537 24538 if (test_case.m_stage == stage) 24539 { 24540 switch (stage) 24541 { 24542 case Utils::Shader::GEOMETRY: 24543 assignments = vs_tes_gs; 24544 break; 24545 case Utils::Shader::TESS_EVAL: 24546 assignments = vs_tes_gs; 24547 break; 24548 case Utils::Shader::VERTEX: 24549 assignments = vs_tes_gs; 24550 break; 24551 default: 24552 TCU_FAIL("Invalid enum"); 24553 } 24554 } 24555 else 24556 { 24557 switch (stage) 24558 { 24559 case Utils::Shader::FRAGMENT: 24560 assignments = fs; 24561 break; 24562 case Utils::Shader::GEOMETRY: 24563 case Utils::Shader::TESS_CTRL: 24564 case Utils::Shader::TESS_EVAL: 24565 case Utils::Shader::VERTEX: 24566 break; 24567 default: 24568 TCU_FAIL("Invalid enum"); 24569 } 24570 } 24571 24572 out_assignments = assignments; 24573 24574 if (Utils::Shader::FRAGMENT == stage) 24575 { 24576 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments); 24577 } 24578 } 24579 24580 /** Get interface of shader 24581 * 24582 * @param test_case_index Index of test case 24583 * @param stage Shader stage 24584 * @param out_interface Set to "" 24585 **/ 24586 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface) 24587 { 24588 static const GLchar* vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n" 24589 "\n" 24590 "layout(std140, binding = 0) uniform Goku {\n" 24591 " TYPE uni_goku;\n" 24592 "};\n"; 24593 static const GLchar* fs = "FLAT in TYPE goku;\n" 24594 "\n" 24595 "out vec4 fs_out;\n"; 24596 24597 const testCase& test_case = m_test_cases[test_case_index]; 24598 const GLchar* interface = ""; 24599 const GLchar* flat = ""; 24600 24601 if (test_case.m_stage == stage) 24602 { 24603 switch (stage) 24604 { 24605 case Utils::Shader::GEOMETRY: 24606 interface = vs_tes_gs; 24607 break; 24608 case Utils::Shader::TESS_EVAL: 24609 interface = vs_tes_gs; 24610 break; 24611 case Utils::Shader::VERTEX: 24612 interface = vs_tes_gs; 24613 break; 24614 default: 24615 TCU_FAIL("Invalid enum"); 24616 } 24617 } 24618 else 24619 { 24620 switch (stage) 24621 { 24622 case Utils::Shader::FRAGMENT: 24623 interface = fs; 24624 break; 24625 case Utils::Shader::GEOMETRY: 24626 case Utils::Shader::TESS_CTRL: 24627 case Utils::Shader::TESS_EVAL: 24628 case Utils::Shader::VERTEX: 24629 break; 24630 default: 24631 TCU_FAIL("Invalid enum"); 24632 } 24633 } 24634 24635 out_interface = interface; 24636 24637 if (Utils::Type::Float != test_case.m_type.m_basic_type) 24638 { 24639 flat = "flat"; 24640 } 24641 24642 Utils::replaceAllTokens("FLAT", flat, out_interface); 24643 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface); 24644 } 24645 24646 /** Get source code of shader 24647 * 24648 * @param test_case_index Index of test case 24649 * @param stage Shader stage 24650 * 24651 * @return Source 24652 **/ 24653 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 24654 { 24655 std::string source; 24656 const testCase& test_case = m_test_cases[test_case_index]; 24657 24658 switch (test_case.m_stage) 24659 { 24660 case Utils::Shader::VERTEX: 24661 switch (stage) 24662 { 24663 case Utils::Shader::FRAGMENT: 24664 case Utils::Shader::VERTEX: 24665 source = BufferTestBase::getShaderSource(test_case_index, stage); 24666 break; 24667 default: 24668 break; 24669 } 24670 break; 24671 24672 case Utils::Shader::TESS_EVAL: 24673 switch (stage) 24674 { 24675 case Utils::Shader::FRAGMENT: 24676 case Utils::Shader::TESS_CTRL: 24677 case Utils::Shader::TESS_EVAL: 24678 case Utils::Shader::VERTEX: 24679 source = BufferTestBase::getShaderSource(test_case_index, stage); 24680 break; 24681 default: 24682 break; 24683 } 24684 break; 24685 24686 case Utils::Shader::GEOMETRY: 24687 source = BufferTestBase::getShaderSource(test_case_index, stage); 24688 break; 24689 24690 default: 24691 TCU_FAIL("Invalid enum"); 24692 break; 24693 } 24694 24695 /* */ 24696 return source; 24697 } 24698 24699 /** Get name of test case 24700 * 24701 * @param test_case_index Index of test case 24702 * 24703 * @return Name of tested stage 24704 **/ 24705 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index) 24706 { 24707 std::stringstream stream; 24708 const testCase& test_case = m_test_cases[test_case_index]; 24709 24710 stream << "Type: " << test_case.m_type.GetGLSLTypeName() 24711 << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage); 24712 24713 return stream.str(); 24714 } 24715 24716 /** Returns number of test cases 24717 * 24718 * @return TEST_MAX 24719 **/ 24720 glw::GLuint XFBStrideTest::getTestCaseNumber() 24721 { 24722 return static_cast<GLuint>(m_test_cases.size()); 24723 } 24724 24725 /** Prepare all test cases 24726 * 24727 **/ 24728 void XFBStrideTest::testInit() 24729 { 24730 const GLuint n_types = getTypesNumber(); 24731 24732 for (GLuint i = 0; i < n_types; ++i) 24733 { 24734 const Utils::Type& type = getType(i); 24735 24736 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 24737 { 24738 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) || 24739 (Utils::Shader::TESS_CTRL == stage)) 24740 { 24741 continue; 24742 } 24743 24744 testCase test_case = { (Utils::Shader::STAGES)stage, type }; 24745 24746 m_test_cases.push_back(test_case); 24747 } 24748 } 24749 } 24750 24751 /** Constructor 24752 * 24753 * @param context Test framework context 24754 **/ 24755 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context& context) 24756 : NegativeTestBase( 24757 context, "xfb_block_member_buffer", 24758 "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer") 24759 { 24760 } 24761 24762 /** Source for given test case and stage 24763 * 24764 * @param test_case_index Index of test case 24765 * @param stage Shader stage 24766 * 24767 * @return Shader source 24768 **/ 24769 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 24770 { 24771 static const GLchar* var_definition = "layout (xfb_offset = 0) out Goku {\n" 24772 " vec4 gohan;\n" 24773 " layout (xfb_buffer = 1) vec4 goten;\n" 24774 "} gokuARRAY;\n"; 24775 static const GLchar* var_use = " gokuINDEX.gohan = result / 2;\n" 24776 " gokuINDEX.goten = result / 4;\n"; 24777 static const GLchar* fs = "#version 430 core\n" 24778 "#extension GL_ARB_enhanced_layouts : require\n" 24779 "\n" 24780 "in vec4 gs_fs;\n" 24781 "out vec4 fs_out;\n" 24782 "\n" 24783 "void main()\n" 24784 "{\n" 24785 " fs_out = gs_fs;\n" 24786 "}\n" 24787 "\n"; 24788 static const GLchar* gs_tested = "#version 430 core\n" 24789 "#extension GL_ARB_enhanced_layouts : require\n" 24790 "\n" 24791 "layout(points) in;\n" 24792 "layout(triangle_strip, max_vertices = 4) out;\n" 24793 "\n" 24794 "VAR_DEFINITION" 24795 "\n" 24796 "in vec4 tes_gs[];\n" 24797 "out vec4 gs_fs;\n" 24798 "\n" 24799 "void main()\n" 24800 "{\n" 24801 " vec4 result = tes_gs[0];\n" 24802 "\n" 24803 "VARIABLE_USE" 24804 "\n" 24805 " gs_fs = result;\n" 24806 " gl_Position = vec4(-1, -1, 0, 1);\n" 24807 " EmitVertex();\n" 24808 " gs_fs = result;\n" 24809 " gl_Position = vec4(-1, 1, 0, 1);\n" 24810 " EmitVertex();\n" 24811 " gs_fs = result;\n" 24812 " gl_Position = vec4(1, -1, 0, 1);\n" 24813 " EmitVertex();\n" 24814 " gs_fs = result;\n" 24815 " gl_Position = vec4(1, 1, 0, 1);\n" 24816 " EmitVertex();\n" 24817 "}\n" 24818 "\n"; 24819 static const GLchar* tcs = "#version 430 core\n" 24820 "#extension GL_ARB_enhanced_layouts : require\n" 24821 "\n" 24822 "layout(vertices = 1) out;\n" 24823 "\n" 24824 "in vec4 vs_tcs[];\n" 24825 "out vec4 tcs_tes[];\n" 24826 "\n" 24827 "void main()\n" 24828 "{\n" 24829 "\n" 24830 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 24831 "\n" 24832 " gl_TessLevelOuter[0] = 1.0;\n" 24833 " gl_TessLevelOuter[1] = 1.0;\n" 24834 " gl_TessLevelOuter[2] = 1.0;\n" 24835 " gl_TessLevelOuter[3] = 1.0;\n" 24836 " gl_TessLevelInner[0] = 1.0;\n" 24837 " gl_TessLevelInner[1] = 1.0;\n" 24838 "}\n" 24839 "\n"; 24840 static const GLchar* tcs_tested = "#version 430 core\n" 24841 "#extension GL_ARB_enhanced_layouts : require\n" 24842 "\n" 24843 "layout(vertices = 1) out;\n" 24844 "\n" 24845 "VAR_DEFINITION" 24846 "\n" 24847 "in vec4 vs_tcs[];\n" 24848 "out vec4 tcs_tes[];\n" 24849 "\n" 24850 "void main()\n" 24851 "{\n" 24852 " vec4 result = vs_tcs[gl_InvocationID];\n" 24853 "\n" 24854 "VARIABLE_USE" 24855 "\n" 24856 " tcs_tes[gl_InvocationID] = result;\n" 24857 "\n" 24858 " gl_TessLevelOuter[0] = 1.0;\n" 24859 " gl_TessLevelOuter[1] = 1.0;\n" 24860 " gl_TessLevelOuter[2] = 1.0;\n" 24861 " gl_TessLevelOuter[3] = 1.0;\n" 24862 " gl_TessLevelInner[0] = 1.0;\n" 24863 " gl_TessLevelInner[1] = 1.0;\n" 24864 "}\n" 24865 "\n"; 24866 static const GLchar* tes_tested = "#version 430 core\n" 24867 "#extension GL_ARB_enhanced_layouts : require\n" 24868 "\n" 24869 "layout(isolines, point_mode) in;\n" 24870 "\n" 24871 "VAR_DEFINITION" 24872 "\n" 24873 "in vec4 tcs_tes[];\n" 24874 "out vec4 tes_gs;\n" 24875 "\n" 24876 "void main()\n" 24877 "{\n" 24878 " vec4 result = tcs_tes[0];\n" 24879 "\n" 24880 "VARIABLE_USE" 24881 "\n" 24882 " tes_gs += result;\n" 24883 "}\n" 24884 "\n"; 24885 static const GLchar* vs = "#version 430 core\n" 24886 "#extension GL_ARB_enhanced_layouts : require\n" 24887 "\n" 24888 "in vec4 in_vs;\n" 24889 "out vec4 vs_tcs;\n" 24890 "\n" 24891 "void main()\n" 24892 "{\n" 24893 " vs_tcs = in_vs;\n" 24894 "}\n" 24895 "\n"; 24896 static const GLchar* vs_tested = "#version 430 core\n" 24897 "#extension GL_ARB_enhanced_layouts : require\n" 24898 "\n" 24899 "VAR_DEFINITION" 24900 "\n" 24901 "in vec4 in_vs;\n" 24902 "out vec4 vs_tcs;\n" 24903 "\n" 24904 "void main()\n" 24905 "{\n" 24906 " vec4 result = in_vs;\n" 24907 "\n" 24908 "VARIABLE_USE" 24909 "\n" 24910 " vs_tcs = result;\n" 24911 "}\n" 24912 "\n"; 24913 24914 std::string source; 24915 testCase& test_case = m_test_cases[test_case_index]; 24916 24917 if (test_case.m_stage == stage) 24918 { 24919 const GLchar* array = ""; 24920 const GLchar* index = ""; 24921 size_t position = 0; 24922 24923 switch (stage) 24924 { 24925 case Utils::Shader::GEOMETRY: 24926 source = gs_tested; 24927 array = "[]"; 24928 index = "[0]"; 24929 break; 24930 case Utils::Shader::TESS_CTRL: 24931 source = tcs_tested; 24932 array = "[]"; 24933 index = "[gl_InvocationID]"; 24934 break; 24935 case Utils::Shader::TESS_EVAL: 24936 source = tes_tested; 24937 array = "[]"; 24938 index = "[0]"; 24939 break; 24940 case Utils::Shader::VERTEX: 24941 source = vs_tested; 24942 break; 24943 default: 24944 TCU_FAIL("Invalid enum"); 24945 } 24946 24947 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 24948 position = 0; 24949 Utils::replaceToken("ARRAY", position, array, source); 24950 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 24951 24952 Utils::replaceAllTokens("INDEX", index, source); 24953 } 24954 else 24955 { 24956 switch (test_case.m_stage) 24957 { 24958 case Utils::Shader::GEOMETRY: 24959 switch (stage) 24960 { 24961 case Utils::Shader::FRAGMENT: 24962 source = fs; 24963 break; 24964 case Utils::Shader::VERTEX: 24965 source = vs; 24966 break; 24967 default: 24968 source = ""; 24969 } 24970 break; 24971 case Utils::Shader::TESS_CTRL: 24972 switch (stage) 24973 { 24974 case Utils::Shader::FRAGMENT: 24975 source = fs; 24976 break; 24977 case Utils::Shader::VERTEX: 24978 source = vs; 24979 break; 24980 default: 24981 source = ""; 24982 } 24983 break; 24984 case Utils::Shader::TESS_EVAL: 24985 switch (stage) 24986 { 24987 case Utils::Shader::FRAGMENT: 24988 source = fs; 24989 break; 24990 case Utils::Shader::TESS_CTRL: 24991 source = tcs; 24992 break; 24993 case Utils::Shader::VERTEX: 24994 source = vs; 24995 break; 24996 default: 24997 source = ""; 24998 } 24999 break; 25000 case Utils::Shader::VERTEX: 25001 switch (stage) 25002 { 25003 case Utils::Shader::FRAGMENT: 25004 source = fs; 25005 break; 25006 default: 25007 source = ""; 25008 } 25009 break; 25010 default: 25011 TCU_FAIL("Invalid enum"); 25012 break; 25013 } 25014 } 25015 25016 return source; 25017 } 25018 25019 /** Get description of test case 25020 * 25021 * @param test_case_index Index of test case 25022 * 25023 * @return Test case description 25024 **/ 25025 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index) 25026 { 25027 std::stringstream stream; 25028 testCase& test_case = m_test_cases[test_case_index]; 25029 25030 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage); 25031 25032 return stream.str(); 25033 } 25034 25035 /** Get number of test cases 25036 * 25037 * @return Number of test cases 25038 **/ 25039 GLuint XFBBlockMemberBufferTest::getTestCaseNumber() 25040 { 25041 return static_cast<GLuint>(m_test_cases.size()); 25042 } 25043 25044 /** Selects if "compute" stage is relevant for test 25045 * 25046 * @param ignored 25047 * 25048 * @return false 25049 **/ 25050 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */) 25051 { 25052 return false; 25053 } 25054 25055 /** Prepare all test cases 25056 * 25057 **/ 25058 void XFBBlockMemberBufferTest::testInit() 25059 { 25060 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 25061 { 25062 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 25063 (Utils::Shader::FRAGMENT == stage)) 25064 { 25065 continue; 25066 } 25067 25068 testCase test_case = { (Utils::Shader::STAGES)stage }; 25069 25070 m_test_cases.push_back(test_case); 25071 } 25072 } 25073 25074 /** Constructor 25075 * 25076 * @param context Test framework context 25077 **/ 25078 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context& context) 25079 : NegativeTestBase(context, "xfb_output_overlapping", 25080 "Test verifies that compiler reports error when two xfb qualified outputs overlap") 25081 { 25082 } 25083 25084 /** Source for given test case and stage 25085 * 25086 * @param test_case_index Index of test case 25087 * @param stage Shader stage 25088 * 25089 * @return Shader source 25090 **/ 25091 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 25092 { 25093 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n" 25094 "layout (xfb_offset = OFFSET) out TYPE gotenARRAY;\n"; 25095 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n" 25096 " gotenINDEX = TYPE(1);\n" 25097 " if (vec4(0) == result)\n" 25098 " {\n" 25099 " gohanINDEX = TYPE(1);\n" 25100 " gotenINDEX = TYPE(0);\n" 25101 " }\n"; 25102 static const GLchar* fs = "#version 430 core\n" 25103 "#extension GL_ARB_enhanced_layouts : require\n" 25104 "\n" 25105 "in vec4 gs_fs;\n" 25106 "out vec4 fs_out;\n" 25107 "\n" 25108 "void main()\n" 25109 "{\n" 25110 " fs_out = gs_fs;\n" 25111 "}\n" 25112 "\n"; 25113 static const GLchar* gs_tested = "#version 430 core\n" 25114 "#extension GL_ARB_enhanced_layouts : require\n" 25115 "\n" 25116 "layout(points) in;\n" 25117 "layout(triangle_strip, max_vertices = 4) out;\n" 25118 "\n" 25119 "VAR_DEFINITION" 25120 "\n" 25121 "in vec4 tes_gs[];\n" 25122 "out vec4 gs_fs;\n" 25123 "\n" 25124 "void main()\n" 25125 "{\n" 25126 " vec4 result = tes_gs[0];\n" 25127 "\n" 25128 "VARIABLE_USE" 25129 "\n" 25130 " gs_fs = result;\n" 25131 " gl_Position = vec4(-1, -1, 0, 1);\n" 25132 " EmitVertex();\n" 25133 " gs_fs = result;\n" 25134 " gl_Position = vec4(-1, 1, 0, 1);\n" 25135 " EmitVertex();\n" 25136 " gs_fs = result;\n" 25137 " gl_Position = vec4(1, -1, 0, 1);\n" 25138 " EmitVertex();\n" 25139 " gs_fs = result;\n" 25140 " gl_Position = vec4(1, 1, 0, 1);\n" 25141 " EmitVertex();\n" 25142 "}\n" 25143 "\n"; 25144 static const GLchar* tcs = "#version 430 core\n" 25145 "#extension GL_ARB_enhanced_layouts : require\n" 25146 "\n" 25147 "layout(vertices = 1) out;\n" 25148 "\n" 25149 "in vec4 vs_tcs[];\n" 25150 "out vec4 tcs_tes[];\n" 25151 "\n" 25152 "void main()\n" 25153 "{\n" 25154 "\n" 25155 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 25156 "\n" 25157 " gl_TessLevelOuter[0] = 1.0;\n" 25158 " gl_TessLevelOuter[1] = 1.0;\n" 25159 " gl_TessLevelOuter[2] = 1.0;\n" 25160 " gl_TessLevelOuter[3] = 1.0;\n" 25161 " gl_TessLevelInner[0] = 1.0;\n" 25162 " gl_TessLevelInner[1] = 1.0;\n" 25163 "}\n" 25164 "\n"; 25165 static const GLchar* tcs_tested = "#version 430 core\n" 25166 "#extension GL_ARB_enhanced_layouts : require\n" 25167 "\n" 25168 "layout(vertices = 1) out;\n" 25169 "\n" 25170 "VAR_DEFINITION" 25171 "\n" 25172 "in vec4 vs_tcs[];\n" 25173 "out vec4 tcs_tes[];\n" 25174 "\n" 25175 "void main()\n" 25176 "{\n" 25177 " vec4 result = vs_tcs[gl_InvocationID];\n" 25178 "\n" 25179 "VARIABLE_USE" 25180 "\n" 25181 " tcs_tes[gl_InvocationID] = result;\n" 25182 "\n" 25183 " gl_TessLevelOuter[0] = 1.0;\n" 25184 " gl_TessLevelOuter[1] = 1.0;\n" 25185 " gl_TessLevelOuter[2] = 1.0;\n" 25186 " gl_TessLevelOuter[3] = 1.0;\n" 25187 " gl_TessLevelInner[0] = 1.0;\n" 25188 " gl_TessLevelInner[1] = 1.0;\n" 25189 "}\n" 25190 "\n"; 25191 static const GLchar* tes_tested = "#version 430 core\n" 25192 "#extension GL_ARB_enhanced_layouts : require\n" 25193 "\n" 25194 "layout(isolines, point_mode) in;\n" 25195 "\n" 25196 "VAR_DEFINITION" 25197 "\n" 25198 "in vec4 tcs_tes[];\n" 25199 "out vec4 tes_gs;\n" 25200 "\n" 25201 "void main()\n" 25202 "{\n" 25203 " vec4 result = tcs_tes[0];\n" 25204 "\n" 25205 "VARIABLE_USE" 25206 "\n" 25207 " tes_gs += result;\n" 25208 "}\n" 25209 "\n"; 25210 static const GLchar* vs = "#version 430 core\n" 25211 "#extension GL_ARB_enhanced_layouts : require\n" 25212 "\n" 25213 "in vec4 in_vs;\n" 25214 "out vec4 vs_tcs;\n" 25215 "\n" 25216 "void main()\n" 25217 "{\n" 25218 " vs_tcs = in_vs;\n" 25219 "}\n" 25220 "\n"; 25221 static const GLchar* vs_tested = "#version 430 core\n" 25222 "#extension GL_ARB_enhanced_layouts : require\n" 25223 "\n" 25224 "VAR_DEFINITION" 25225 "\n" 25226 "in vec4 in_vs;\n" 25227 "out vec4 vs_tcs;\n" 25228 "\n" 25229 "void main()\n" 25230 "{\n" 25231 " vec4 result = in_vs;\n" 25232 "\n" 25233 "VARIABLE_USE" 25234 "\n" 25235 " vs_tcs = result;\n" 25236 "}\n" 25237 "\n"; 25238 25239 std::string source; 25240 testCase& test_case = m_test_cases[test_case_index]; 25241 25242 if (test_case.m_stage == stage) 25243 { 25244 const GLchar* array = ""; 25245 GLchar buffer_gohan[16]; 25246 GLchar buffer_goten[16]; 25247 const GLchar* index = ""; 25248 size_t position = 0; 25249 size_t position_start = 0; 25250 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 25251 25252 sprintf(buffer_gohan, "%d", test_case.m_offset_gohan); 25253 sprintf(buffer_goten, "%d", test_case.m_offset_goten); 25254 25255 switch (stage) 25256 { 25257 case Utils::Shader::GEOMETRY: 25258 source = gs_tested; 25259 array = "[]"; 25260 index = "[0]"; 25261 break; 25262 case Utils::Shader::TESS_CTRL: 25263 source = tcs_tested; 25264 array = "[]"; 25265 index = "[gl_InvocationID]"; 25266 break; 25267 case Utils::Shader::TESS_EVAL: 25268 source = tes_tested; 25269 array = "[]"; 25270 index = "[0]"; 25271 break; 25272 case Utils::Shader::VERTEX: 25273 source = vs_tested; 25274 break; 25275 default: 25276 TCU_FAIL("Invalid enum"); 25277 } 25278 25279 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 25280 position = 0; 25281 Utils::replaceToken("OFFSET", position, buffer_gohan, source); 25282 Utils::replaceToken("TYPE", position, type_name, source); 25283 Utils::replaceToken("ARRAY", position, array, source); 25284 Utils::replaceToken("OFFSET", position, buffer_goten, source); 25285 Utils::replaceToken("TYPE", position, type_name, source); 25286 Utils::replaceToken("ARRAY", position, array, source); 25287 position_start = position; 25288 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 25289 position = position_start; 25290 Utils::replaceToken("INDEX", position, index, source); 25291 Utils::replaceToken("TYPE", position, type_name, source); 25292 Utils::replaceToken("INDEX", position, index, source); 25293 Utils::replaceToken("TYPE", position, type_name, source); 25294 Utils::replaceToken("INDEX", position, index, source); 25295 Utils::replaceToken("TYPE", position, type_name, source); 25296 Utils::replaceToken("INDEX", position, index, source); 25297 Utils::replaceToken("TYPE", position, type_name, source); 25298 } 25299 else 25300 { 25301 switch (test_case.m_stage) 25302 { 25303 case Utils::Shader::GEOMETRY: 25304 switch (stage) 25305 { 25306 case Utils::Shader::FRAGMENT: 25307 source = fs; 25308 break; 25309 case Utils::Shader::VERTEX: 25310 source = vs; 25311 break; 25312 default: 25313 source = ""; 25314 } 25315 break; 25316 case Utils::Shader::TESS_CTRL: 25317 switch (stage) 25318 { 25319 case Utils::Shader::FRAGMENT: 25320 source = fs; 25321 break; 25322 case Utils::Shader::VERTEX: 25323 source = vs; 25324 break; 25325 default: 25326 source = ""; 25327 } 25328 break; 25329 case Utils::Shader::TESS_EVAL: 25330 switch (stage) 25331 { 25332 case Utils::Shader::FRAGMENT: 25333 source = fs; 25334 break; 25335 case Utils::Shader::TESS_CTRL: 25336 source = tcs; 25337 break; 25338 case Utils::Shader::VERTEX: 25339 source = vs; 25340 break; 25341 default: 25342 source = ""; 25343 } 25344 break; 25345 case Utils::Shader::VERTEX: 25346 switch (stage) 25347 { 25348 case Utils::Shader::FRAGMENT: 25349 source = fs; 25350 break; 25351 default: 25352 source = ""; 25353 } 25354 break; 25355 default: 25356 TCU_FAIL("Invalid enum"); 25357 break; 25358 } 25359 } 25360 25361 return source; 25362 } 25363 25364 /** Get description of test case 25365 * 25366 * @param test_case_index Index of test case 25367 * 25368 * @return Test case description 25369 **/ 25370 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index) 25371 { 25372 std::stringstream stream; 25373 testCase& test_case = m_test_cases[test_case_index]; 25374 25375 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 25376 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offsets: " << test_case.m_offset_gohan << " & " 25377 << test_case.m_offset_goten; 25378 25379 return stream.str(); 25380 } 25381 25382 /** Get number of test cases 25383 * 25384 * @return Number of test cases 25385 **/ 25386 GLuint XFBOutputOverlappingTest::getTestCaseNumber() 25387 { 25388 return static_cast<GLuint>(m_test_cases.size()); 25389 } 25390 25391 /** Selects if "compute" stage is relevant for test 25392 * 25393 * @param ignored 25394 * 25395 * @return false 25396 **/ 25397 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */) 25398 { 25399 return false; 25400 } 25401 25402 /** Prepare all test cases 25403 * 25404 **/ 25405 void XFBOutputOverlappingTest::testInit() 25406 { 25407 const GLuint n_types = getTypesNumber(); 25408 25409 for (GLuint i = 0; i < n_types; ++i) 25410 { 25411 const Utils::Type& type = getType(i); 25412 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type); 25413 25414 /* Skip scalars, not applicable as: 25415 * 25416 * The offset must be a multiple of the size of the first component of the first 25417 * qualified variable or block member, or a compile-time error results. 25418 */ 25419 if ((1 == type.m_n_columns) && (1 == type.m_n_rows)) 25420 { 25421 continue; 25422 } 25423 25424 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 25425 { 25426 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 25427 (Utils::Shader::FRAGMENT == stage)) 25428 { 25429 continue; 25430 } 25431 25432 testCase test_case = { 0 /* gohan offset */, base_alingment /* goten_offset */, 25433 (Utils::Shader::STAGES)stage, type }; 25434 25435 m_test_cases.push_back(test_case); 25436 } 25437 } 25438 } 25439 25440 /** Constructor 25441 * 25442 * @param context Test framework context 25443 **/ 25444 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context& context) 25445 : NegativeTestBase(context, "xfb_invalid_offset_alignment", 25446 "Test verifies that compiler reports error when xfb_offset has invalid alignment") 25447 { 25448 } 25449 25450 /** Source for given test case and stage 25451 * 25452 * @param test_case_index Index of test case 25453 * @param stage Shader stage 25454 * 25455 * @return Shader source 25456 **/ 25457 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 25458 { 25459 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n"; 25460 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n" 25461 " if (vec4(0) == result)\n" 25462 " {\n" 25463 " gohanINDEX = TYPE(1);\n" 25464 " }\n"; 25465 static const GLchar* fs = "#version 430 core\n" 25466 "#extension GL_ARB_enhanced_layouts : require\n" 25467 "\n" 25468 "in vec4 gs_fs;\n" 25469 "out vec4 fs_out;\n" 25470 "\n" 25471 "void main()\n" 25472 "{\n" 25473 " fs_out = gs_fs;\n" 25474 "}\n" 25475 "\n"; 25476 static const GLchar* gs_tested = "#version 430 core\n" 25477 "#extension GL_ARB_enhanced_layouts : require\n" 25478 "\n" 25479 "layout(points) in;\n" 25480 "layout(triangle_strip, max_vertices = 4) out;\n" 25481 "\n" 25482 "VAR_DEFINITION" 25483 "\n" 25484 "in vec4 tes_gs[];\n" 25485 "out vec4 gs_fs;\n" 25486 "\n" 25487 "void main()\n" 25488 "{\n" 25489 " vec4 result = tes_gs[0];\n" 25490 "\n" 25491 "VARIABLE_USE" 25492 "\n" 25493 " gs_fs = result;\n" 25494 " gl_Position = vec4(-1, -1, 0, 1);\n" 25495 " EmitVertex();\n" 25496 " gs_fs = result;\n" 25497 " gl_Position = vec4(-1, 1, 0, 1);\n" 25498 " EmitVertex();\n" 25499 " gs_fs = result;\n" 25500 " gl_Position = vec4(1, -1, 0, 1);\n" 25501 " EmitVertex();\n" 25502 " gs_fs = result;\n" 25503 " gl_Position = vec4(1, 1, 0, 1);\n" 25504 " EmitVertex();\n" 25505 "}\n" 25506 "\n"; 25507 static const GLchar* tcs = "#version 430 core\n" 25508 "#extension GL_ARB_enhanced_layouts : require\n" 25509 "\n" 25510 "layout(vertices = 1) out;\n" 25511 "\n" 25512 "in vec4 vs_tcs[];\n" 25513 "out vec4 tcs_tes[];\n" 25514 "\n" 25515 "void main()\n" 25516 "{\n" 25517 "\n" 25518 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 25519 "\n" 25520 " gl_TessLevelOuter[0] = 1.0;\n" 25521 " gl_TessLevelOuter[1] = 1.0;\n" 25522 " gl_TessLevelOuter[2] = 1.0;\n" 25523 " gl_TessLevelOuter[3] = 1.0;\n" 25524 " gl_TessLevelInner[0] = 1.0;\n" 25525 " gl_TessLevelInner[1] = 1.0;\n" 25526 "}\n" 25527 "\n"; 25528 static const GLchar* tcs_tested = "#version 430 core\n" 25529 "#extension GL_ARB_enhanced_layouts : require\n" 25530 "\n" 25531 "layout(vertices = 1) out;\n" 25532 "\n" 25533 "VAR_DEFINITION" 25534 "\n" 25535 "in vec4 vs_tcs[];\n" 25536 "out vec4 tcs_tes[];\n" 25537 "\n" 25538 "void main()\n" 25539 "{\n" 25540 " vec4 result = vs_tcs[gl_InvocationID];\n" 25541 "\n" 25542 "VARIABLE_USE" 25543 "\n" 25544 " tcs_tes[gl_InvocationID] = result;\n" 25545 "\n" 25546 " gl_TessLevelOuter[0] = 1.0;\n" 25547 " gl_TessLevelOuter[1] = 1.0;\n" 25548 " gl_TessLevelOuter[2] = 1.0;\n" 25549 " gl_TessLevelOuter[3] = 1.0;\n" 25550 " gl_TessLevelInner[0] = 1.0;\n" 25551 " gl_TessLevelInner[1] = 1.0;\n" 25552 "}\n" 25553 "\n"; 25554 static const GLchar* tes_tested = "#version 430 core\n" 25555 "#extension GL_ARB_enhanced_layouts : require\n" 25556 "\n" 25557 "layout(isolines, point_mode) in;\n" 25558 "\n" 25559 "VAR_DEFINITION" 25560 "\n" 25561 "in vec4 tcs_tes[];\n" 25562 "out vec4 tes_gs;\n" 25563 "\n" 25564 "void main()\n" 25565 "{\n" 25566 " vec4 result = tcs_tes[0];\n" 25567 "\n" 25568 "VARIABLE_USE" 25569 "\n" 25570 " tes_gs += result;\n" 25571 "}\n" 25572 "\n"; 25573 static const GLchar* vs = "#version 430 core\n" 25574 "#extension GL_ARB_enhanced_layouts : require\n" 25575 "\n" 25576 "in vec4 in_vs;\n" 25577 "out vec4 vs_tcs;\n" 25578 "\n" 25579 "void main()\n" 25580 "{\n" 25581 " vs_tcs = in_vs;\n" 25582 "}\n" 25583 "\n"; 25584 static const GLchar* vs_tested = "#version 430 core\n" 25585 "#extension GL_ARB_enhanced_layouts : require\n" 25586 "\n" 25587 "VAR_DEFINITION" 25588 "\n" 25589 "in vec4 in_vs;\n" 25590 "out vec4 vs_tcs;\n" 25591 "\n" 25592 "void main()\n" 25593 "{\n" 25594 " vec4 result = in_vs;\n" 25595 "\n" 25596 "VARIABLE_USE" 25597 "\n" 25598 " vs_tcs = result;\n" 25599 "}\n" 25600 "\n"; 25601 25602 std::string source; 25603 testCase& test_case = m_test_cases[test_case_index]; 25604 25605 if (test_case.m_stage == stage) 25606 { 25607 const GLchar* array = ""; 25608 GLchar buffer[16]; 25609 const GLchar* index = ""; 25610 size_t position = 0; 25611 size_t position_start = 0; 25612 const GLchar* type_name = test_case.m_type.GetGLSLTypeName(); 25613 25614 sprintf(buffer, "%d", test_case.m_offset); 25615 25616 switch (stage) 25617 { 25618 case Utils::Shader::GEOMETRY: 25619 source = gs_tested; 25620 array = "[]"; 25621 index = "[0]"; 25622 break; 25623 case Utils::Shader::TESS_CTRL: 25624 source = tcs_tested; 25625 array = "[]"; 25626 index = "[gl_InvocationID]"; 25627 break; 25628 case Utils::Shader::TESS_EVAL: 25629 source = tes_tested; 25630 array = "[]"; 25631 index = "[0]"; 25632 break; 25633 case Utils::Shader::VERTEX: 25634 source = vs_tested; 25635 break; 25636 default: 25637 TCU_FAIL("Invalid enum"); 25638 } 25639 25640 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 25641 position = 0; 25642 Utils::replaceToken("OFFSET", position, buffer, source); 25643 Utils::replaceToken("TYPE", position, type_name, source); 25644 Utils::replaceToken("ARRAY", position, array, source); 25645 position_start = position; 25646 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 25647 position = position_start; 25648 Utils::replaceToken("INDEX", position, index, source); 25649 Utils::replaceToken("TYPE", position, type_name, source); 25650 Utils::replaceToken("INDEX", position, index, source); 25651 Utils::replaceToken("TYPE", position, type_name, source); 25652 } 25653 else 25654 { 25655 switch (test_case.m_stage) 25656 { 25657 case Utils::Shader::GEOMETRY: 25658 switch (stage) 25659 { 25660 case Utils::Shader::FRAGMENT: 25661 source = fs; 25662 break; 25663 case Utils::Shader::VERTEX: 25664 source = vs; 25665 break; 25666 default: 25667 source = ""; 25668 } 25669 break; 25670 case Utils::Shader::TESS_CTRL: 25671 switch (stage) 25672 { 25673 case Utils::Shader::FRAGMENT: 25674 source = fs; 25675 break; 25676 case Utils::Shader::VERTEX: 25677 source = vs; 25678 break; 25679 default: 25680 source = ""; 25681 } 25682 break; 25683 case Utils::Shader::TESS_EVAL: 25684 switch (stage) 25685 { 25686 case Utils::Shader::FRAGMENT: 25687 source = fs; 25688 break; 25689 case Utils::Shader::TESS_CTRL: 25690 source = tcs; 25691 break; 25692 case Utils::Shader::VERTEX: 25693 source = vs; 25694 break; 25695 default: 25696 source = ""; 25697 } 25698 break; 25699 case Utils::Shader::VERTEX: 25700 switch (stage) 25701 { 25702 case Utils::Shader::FRAGMENT: 25703 source = fs; 25704 break; 25705 default: 25706 source = ""; 25707 } 25708 break; 25709 default: 25710 TCU_FAIL("Invalid enum"); 25711 break; 25712 } 25713 } 25714 25715 return source; 25716 } 25717 25718 /** Get description of test case 25719 * 25720 * @param test_case_index Index of test case 25721 * 25722 * @return Test case description 25723 **/ 25724 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index) 25725 { 25726 std::stringstream stream; 25727 testCase& test_case = m_test_cases[test_case_index]; 25728 25729 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) 25730 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset; 25731 25732 return stream.str(); 25733 } 25734 25735 /** Get number of test cases 25736 * 25737 * @return Number of test cases 25738 **/ 25739 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber() 25740 { 25741 return static_cast<GLuint>(m_test_cases.size()); 25742 } 25743 25744 /** Selects if "compute" stage is relevant for test 25745 * 25746 * @param ignored 25747 * 25748 * @return false 25749 **/ 25750 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */) 25751 { 25752 return false; 25753 } 25754 25755 /** Prepare all test cases 25756 * 25757 **/ 25758 void XFBInvalidOffsetAlignmentTest::testInit() 25759 { 25760 const GLuint n_types = getTypesNumber(); 25761 25762 for (GLuint i = 0; i < n_types; ++i) 25763 { 25764 const Utils::Type& type = getType(i); 25765 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type); 25766 25767 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 25768 { 25769 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) || 25770 (Utils::Shader::FRAGMENT == stage)) 25771 { 25772 continue; 25773 } 25774 25775 for (GLuint offset = base_alingment + 1; offset < 2 * base_alingment; ++offset) 25776 { 25777 testCase test_case = { offset, (Utils::Shader::STAGES)stage, type }; 25778 25779 m_test_cases.push_back(test_case); 25780 } 25781 } 25782 } 25783 } 25784 25785 /** Constructor 25786 * 25787 * @param context Test context 25788 **/ 25789 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context& context) 25790 : BufferTestBase(context, "xfb_capture_inactive_output_variable", 25791 "Test verifies that inactive variables are captured") 25792 { 25793 /* Nothing to be done here */ 25794 } 25795 25796 /** Execute drawArrays for single vertex 25797 * 25798 * @param test_case_index 25799 * 25800 * @return true 25801 **/ 25802 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 25803 { 25804 const Functions& gl = m_context.getRenderContext().getFunctions(); 25805 GLenum primitive_type = GL_PATCHES; 25806 25807 if (TEST_VS == test_case_index) 25808 { 25809 primitive_type = GL_POINTS; 25810 } 25811 25812 gl.disable(GL_RASTERIZER_DISCARD); 25813 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 25814 25815 gl.beginTransformFeedback(GL_POINTS); 25816 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 25817 25818 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */); 25819 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 25820 25821 gl.endTransformFeedback(); 25822 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 25823 25824 return true; 25825 } 25826 25827 /** Get descriptors of buffers necessary for test 25828 * 25829 * @param ignored 25830 * @param out_descriptors Descriptors of buffers used by test 25831 **/ 25832 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 25833 bufferDescriptor::Vector& out_descriptors) 25834 { 25835 const Utils::Type& type = Utils::Type::vec4; 25836 25837 /* Test needs single uniform and xfb */ 25838 out_descriptors.resize(2); 25839 25840 /* Get references */ 25841 bufferDescriptor& uniform = out_descriptors[0]; 25842 bufferDescriptor& xfb = out_descriptors[1]; 25843 25844 /* Index */ 25845 uniform.m_index = 0; 25846 xfb.m_index = 0; 25847 25848 /* Target */ 25849 uniform.m_target = Utils::Buffer::Uniform; 25850 xfb.m_target = Utils::Buffer::Transform_feedback; 25851 25852 /* Data */ 25853 const std::vector<GLubyte>& gohan_data = type.GenerateData(); 25854 const std::vector<GLubyte>& goten_data = type.GenerateData(); 25855 25856 const GLuint type_size = static_cast<GLuint>(gohan_data.size()); 25857 25858 /* Uniform data */ 25859 uniform.m_initial_data.resize(2 * type_size); 25860 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size); 25861 memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size); 25862 25863 /* XFB data */ 25864 xfb.m_initial_data.resize(3 * type_size); 25865 xfb.m_expected_data.resize(3 * type_size); 25866 25867 for (GLuint i = 0; i < 3 * type_size; ++i) 25868 { 25869 xfb.m_initial_data[i] = (glw::GLubyte)i; 25870 xfb.m_expected_data[i] = (glw::GLubyte)i; 25871 } 25872 25873 memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size); 25874 memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size); 25875 } 25876 25877 /** Get body of main function for given shader stage 25878 * 25879 * @param test_case_index Index of test case 25880 * @param stage Shader stage 25881 * @param out_assignments Set to empty 25882 * @param out_calculations Set to empty 25883 **/ 25884 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, 25885 std::string& out_assignments, std::string& out_calculations) 25886 { 25887 out_calculations = ""; 25888 25889 static const GLchar* vs_tes_gs = " goten = uni_goten;\n" 25890 " gohan = uni_gohan;\n"; 25891 static const GLchar* fs = " fs_out = goku + gohan + goten;\n"; 25892 25893 const GLchar* assignments = ""; 25894 25895 switch (stage) 25896 { 25897 case Utils::Shader::FRAGMENT: 25898 assignments = fs; 25899 break; 25900 25901 case Utils::Shader::GEOMETRY: 25902 if (TEST_GS == test_case_index) 25903 { 25904 assignments = vs_tes_gs; 25905 } 25906 break; 25907 25908 case Utils::Shader::TESS_CTRL: 25909 break; 25910 25911 case Utils::Shader::TESS_EVAL: 25912 if (TEST_TES == test_case_index) 25913 { 25914 assignments = vs_tes_gs; 25915 } 25916 break; 25917 25918 case Utils::Shader::VERTEX: 25919 if (TEST_VS == test_case_index) 25920 { 25921 assignments = vs_tes_gs; 25922 } 25923 break; 25924 25925 default: 25926 TCU_FAIL("Invalid enum"); 25927 } 25928 25929 out_assignments = assignments; 25930 } 25931 25932 /** Get interface of shader 25933 * 25934 * @param test_case_index Index of test case 25935 * @param stage Shader stage 25936 * @param out_interface Set to "" 25937 **/ 25938 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, 25939 std::string& out_interface) 25940 { 25941 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n" 25942 "\n" 25943 "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n" 25944 "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n" 25945 "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n" 25946 "\n" 25947 "layout(binding = 0) uniform block {\n" 25948 " vec4 uni_gohan;\n" 25949 " vec4 uni_goten;\n" 25950 "};\n"; 25951 static const GLchar* fs = "in vec4 goku;\n" 25952 "in vec4 gohan;\n" 25953 "in vec4 goten;\n" 25954 "out vec4 fs_out;\n"; 25955 25956 const GLchar* interface = ""; 25957 25958 switch (stage) 25959 { 25960 case Utils::Shader::FRAGMENT: 25961 interface = fs; 25962 break; 25963 25964 case Utils::Shader::GEOMETRY: 25965 if (TEST_GS == test_case_index) 25966 { 25967 interface = vs_tes_gs; 25968 } 25969 break; 25970 25971 case Utils::Shader::TESS_CTRL: 25972 break; 25973 25974 case Utils::Shader::TESS_EVAL: 25975 if (TEST_TES == test_case_index) 25976 { 25977 interface = vs_tes_gs; 25978 } 25979 break; 25980 25981 case Utils::Shader::VERTEX: 25982 if (TEST_VS == test_case_index) 25983 { 25984 interface = vs_tes_gs; 25985 } 25986 break; 25987 25988 default: 25989 TCU_FAIL("Invalid enum"); 25990 } 25991 25992 out_interface = interface; 25993 } 25994 25995 /** Get source code of shader 25996 * 25997 * @param test_case_index Index of test case 25998 * @param stage Shader stage 25999 * 26000 * @return Source 26001 **/ 26002 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 26003 { 26004 std::string source; 26005 26006 switch (test_case_index) 26007 { 26008 case TEST_VS: 26009 switch (stage) 26010 { 26011 case Utils::Shader::FRAGMENT: 26012 case Utils::Shader::VERTEX: 26013 source = BufferTestBase::getShaderSource(test_case_index, stage); 26014 break; 26015 default: 26016 break; 26017 } 26018 break; 26019 26020 case TEST_TES: 26021 switch (stage) 26022 { 26023 case Utils::Shader::FRAGMENT: 26024 case Utils::Shader::TESS_CTRL: 26025 case Utils::Shader::TESS_EVAL: 26026 case Utils::Shader::VERTEX: 26027 source = BufferTestBase::getShaderSource(test_case_index, stage); 26028 break; 26029 default: 26030 break; 26031 } 26032 break; 26033 26034 case TEST_GS: 26035 source = BufferTestBase::getShaderSource(test_case_index, stage); 26036 break; 26037 26038 default: 26039 TCU_FAIL("Invalid enum"); 26040 break; 26041 } 26042 26043 /* */ 26044 return source; 26045 } 26046 26047 /** Get name of test case 26048 * 26049 * @param test_case_index Index of test case 26050 * 26051 * @return Name of tested stage 26052 **/ 26053 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index) 26054 { 26055 const GLchar* name = 0; 26056 26057 switch (test_case_index) 26058 { 26059 case TEST_VS: 26060 name = "vertex"; 26061 break; 26062 case TEST_TES: 26063 name = "tessellation evaluation"; 26064 break; 26065 case TEST_GS: 26066 name = "geometry"; 26067 break; 26068 default: 26069 TCU_FAIL("Invalid enum"); 26070 } 26071 26072 return name; 26073 } 26074 26075 /** Returns number of test cases 26076 * 26077 * @return TEST_MAX 26078 **/ 26079 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber() 26080 { 26081 return TEST_MAX; 26082 } 26083 26084 /** Inspects program to check if all resources are as expected 26085 * 26086 * @param ignored 26087 * @param program Program instance 26088 * @param out_stream Error message 26089 * 26090 * @return true if everything is ok, false otherwise 26091 **/ 26092 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program& program, 26093 std::stringstream& out_stream) 26094 { 26095 GLint stride = 0; 26096 const Utils::Type& type = Utils::Type::vec4; 26097 const GLuint type_size = type.GetSize(); 26098 26099 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 26100 1 /* buf_size */, &stride); 26101 26102 if ((GLint)(3 * type_size) != stride) 26103 { 26104 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size); 26105 26106 return false; 26107 } 26108 26109 return true; 26110 } 26111 26112 /** Verify contents of buffers 26113 * 26114 * @param buffers Collection of buffers to be verified 26115 * 26116 * @return true if everything is as expected, false otherwise 26117 **/ 26118 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection& buffers) 26119 { 26120 bool result = true; 26121 26122 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */; 26123 Utils::Buffer* buffer = pair.m_buffer; 26124 bufferDescriptor* descriptor = pair.m_descriptor; 26125 26126 /* Get pointer to contents of buffer */ 26127 buffer->Bind(); 26128 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly); 26129 26130 /* Get pointer to expected data */ 26131 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0]; 26132 26133 /* Compare */ 26134 static const GLuint vec4_size = 16; 26135 26136 int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size); 26137 int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size); 26138 26139 if ((0 != res_gohan) || (0 != res_goten)) 26140 { 26141 m_context.getTestContext().getLog() 26142 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target) 26143 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage; 26144 26145 result = false; 26146 } 26147 26148 /* Release buffer mapping */ 26149 buffer->UnMap(); 26150 26151 return result; 26152 } 26153 26154 /** Constructor 26155 * 26156 * @param context Test context 26157 **/ 26158 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context& context) 26159 : BufferTestBase(context, "xfb_capture_inactive_output_component", 26160 "Test verifies that inactive components are not modified") 26161 { 26162 /* Nothing to be done here */ 26163 } 26164 26165 /** Execute drawArrays for single vertex 26166 * 26167 * @param test_case_index 26168 * 26169 * @return true 26170 **/ 26171 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 26172 { 26173 const Functions& gl = m_context.getRenderContext().getFunctions(); 26174 GLenum primitive_type = GL_PATCHES; 26175 26176 if (TEST_VS == test_case_index) 26177 { 26178 primitive_type = GL_POINTS; 26179 } 26180 26181 gl.disable(GL_RASTERIZER_DISCARD); 26182 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 26183 26184 gl.beginTransformFeedback(GL_POINTS); 26185 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 26186 26187 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */); 26188 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 26189 26190 gl.endTransformFeedback(); 26191 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 26192 26193 return true; 26194 } 26195 26196 /** Get descriptors of buffers necessary for test 26197 * 26198 * @param ignored 26199 * @param out_descriptors Descriptors of buffers used by test 26200 **/ 26201 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 26202 bufferDescriptor::Vector& out_descriptors) 26203 { 26204 const Utils::Type& type = Utils::Type::vec4; 26205 26206 /* Test needs single uniform and xfb */ 26207 out_descriptors.resize(2); 26208 26209 /* Get references */ 26210 bufferDescriptor& uniform = out_descriptors[0]; 26211 bufferDescriptor& xfb = out_descriptors[1]; 26212 26213 /* Index */ 26214 uniform.m_index = 0; 26215 xfb.m_index = 0; 26216 26217 /* Target */ 26218 uniform.m_target = Utils::Buffer::Uniform; 26219 xfb.m_target = Utils::Buffer::Transform_feedback; 26220 26221 /* Data */ 26222 const std::vector<GLubyte>& goku_data = type.GenerateData(); 26223 const std::vector<GLubyte>& gohan_data = type.GenerateData(); 26224 const std::vector<GLubyte>& goten_data = type.GenerateData(); 26225 const std::vector<GLubyte>& chichi_data = type.GenerateData(); 26226 const std::vector<GLubyte>& vegeta_data = type.GenerateData(); 26227 const std::vector<GLubyte>& trunks_data = type.GenerateData(); 26228 const std::vector<GLubyte>& bra_data = type.GenerateData(); 26229 const std::vector<GLubyte>& bulma_data = type.GenerateData(); 26230 26231 const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type); 26232 const GLuint type_size = static_cast<GLuint>(gohan_data.size()); 26233 26234 /* Uniform data */ 26235 uniform.m_initial_data.resize(8 * type_size); 26236 memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size); 26237 memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size); 26238 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size); 26239 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size); 26240 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size); 26241 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size); 26242 memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size); 26243 memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size); 26244 26245 /* XFB data */ 26246 xfb.m_initial_data.resize(8 * type_size); 26247 xfb.m_expected_data.resize(8 * type_size); 26248 26249 for (GLuint i = 0; i < 8 * type_size; ++i) 26250 { 26251 xfb.m_initial_data[i] = (glw::GLubyte)i; 26252 xfb.m_expected_data[i] = (glw::GLubyte)i; 26253 } 26254 26255 /* goku - x, z - 32 */ 26256 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size); 26257 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size); 26258 26259 /* gohan - y, w - 0 */ 26260 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size); 26261 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size); 26262 26263 /* goten - x, y - 16 */ 26264 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size); 26265 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size); 26266 26267 /* chichi - z, w - 48 */ 26268 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size); 26269 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size); 26270 26271 /* vegeta - x - 112 */ 26272 memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size); 26273 26274 /* trunks - y - 96 */ 26275 memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size); 26276 26277 /* bra - z - 80 */ 26278 memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size); 26279 26280 /* bulma - w - 64 */ 26281 memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size); 26282 } 26283 26284 /** Get body of main function for given shader stage 26285 * 26286 * @param test_case_index Index of test case 26287 * @param stage Shader stage 26288 * @param out_assignments Set to empty 26289 * @param out_calculations Set to empty 26290 **/ 26291 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, 26292 std::string& out_assignments, std::string& out_calculations) 26293 { 26294 out_calculations = ""; 26295 26296 static const GLchar* vs_tes_gs = " goku.x = uni_goku.x ;\n" 26297 " goku.z = uni_goku.z ;\n" 26298 " gohan.y = uni_gohan.y ;\n" 26299 " gohan.w = uni_gohan.w ;\n" 26300 " goten.x = uni_goten.x ;\n" 26301 " goten.y = uni_goten.y ;\n" 26302 " chichi.z = uni_chichi.z ;\n" 26303 " chichi.w = uni_chichi.w ;\n" 26304 " vegeta.x = uni_vegeta.x ;\n" 26305 " trunks.y = uni_trunks.y ;\n" 26306 " bra.z = uni_bra.z ;\n" 26307 " bulma.w = uni_bulma.w ;\n"; 26308 static const GLchar* fs = " fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n"; 26309 26310 const GLchar* assignments = ""; 26311 26312 switch (stage) 26313 { 26314 case Utils::Shader::FRAGMENT: 26315 assignments = fs; 26316 break; 26317 26318 case Utils::Shader::GEOMETRY: 26319 if (TEST_GS == test_case_index) 26320 { 26321 assignments = vs_tes_gs; 26322 } 26323 break; 26324 26325 case Utils::Shader::TESS_CTRL: 26326 break; 26327 26328 case Utils::Shader::TESS_EVAL: 26329 if (TEST_TES == test_case_index) 26330 { 26331 assignments = vs_tes_gs; 26332 } 26333 break; 26334 26335 case Utils::Shader::VERTEX: 26336 if (TEST_VS == test_case_index) 26337 { 26338 assignments = vs_tes_gs; 26339 } 26340 break; 26341 26342 default: 26343 TCU_FAIL("Invalid enum"); 26344 } 26345 26346 out_assignments = assignments; 26347 } 26348 26349 /** Get interface of shader 26350 * 26351 * @param test_case_index Index of test case 26352 * @param stage Shader stage 26353 * @param out_interface Set to "" 26354 **/ 26355 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, 26356 std::string& out_interface) 26357 { 26358 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n" 26359 "\n" 26360 "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n" 26361 "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n" 26362 "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n" 26363 "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n" 26364 "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n" 26365 "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n" 26366 "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n" 26367 "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n" 26368 "\n" 26369 "layout(binding = 0) uniform block {\n" 26370 " vec4 uni_goku;\n" 26371 " vec4 uni_gohan;\n" 26372 " vec4 uni_goten;\n" 26373 " vec4 uni_chichi;\n" 26374 " vec4 uni_vegeta;\n" 26375 " vec4 uni_trunks;\n" 26376 " vec4 uni_bra;\n" 26377 " vec4 uni_bulma;\n" 26378 "};\n"; 26379 static const GLchar* fs = "in vec4 vegeta;\n" 26380 "in vec4 trunks;\n" 26381 "in vec4 bra;\n" 26382 "in vec4 bulma;\n" 26383 "in vec4 goku;\n" 26384 "in vec4 gohan;\n" 26385 "in vec4 goten;\n" 26386 "in vec4 chichi;\n" 26387 "\n" 26388 "out vec4 fs_out;\n"; 26389 26390 const GLchar* interface = ""; 26391 26392 switch (stage) 26393 { 26394 case Utils::Shader::FRAGMENT: 26395 interface = fs; 26396 break; 26397 26398 case Utils::Shader::GEOMETRY: 26399 if (TEST_GS == test_case_index) 26400 { 26401 interface = vs_tes_gs; 26402 } 26403 break; 26404 26405 case Utils::Shader::TESS_CTRL: 26406 break; 26407 26408 case Utils::Shader::TESS_EVAL: 26409 if (TEST_TES == test_case_index) 26410 { 26411 interface = vs_tes_gs; 26412 } 26413 break; 26414 26415 case Utils::Shader::VERTEX: 26416 if (TEST_VS == test_case_index) 26417 { 26418 interface = vs_tes_gs; 26419 } 26420 break; 26421 26422 default: 26423 TCU_FAIL("Invalid enum"); 26424 } 26425 26426 out_interface = interface; 26427 } 26428 26429 /** Get source code of shader 26430 * 26431 * @param test_case_index Index of test case 26432 * @param stage Shader stage 26433 * 26434 * @return Source 26435 **/ 26436 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 26437 { 26438 std::string source; 26439 26440 switch (test_case_index) 26441 { 26442 case TEST_VS: 26443 switch (stage) 26444 { 26445 case Utils::Shader::FRAGMENT: 26446 case Utils::Shader::VERTEX: 26447 source = BufferTestBase::getShaderSource(test_case_index, stage); 26448 break; 26449 default: 26450 break; 26451 } 26452 break; 26453 26454 case TEST_TES: 26455 switch (stage) 26456 { 26457 case Utils::Shader::FRAGMENT: 26458 case Utils::Shader::TESS_CTRL: 26459 case Utils::Shader::TESS_EVAL: 26460 case Utils::Shader::VERTEX: 26461 source = BufferTestBase::getShaderSource(test_case_index, stage); 26462 break; 26463 default: 26464 break; 26465 } 26466 break; 26467 26468 case TEST_GS: 26469 source = BufferTestBase::getShaderSource(test_case_index, stage); 26470 break; 26471 26472 default: 26473 TCU_FAIL("Invalid enum"); 26474 break; 26475 } 26476 26477 /* */ 26478 return source; 26479 } 26480 26481 /** Get name of test case 26482 * 26483 * @param test_case_index Index of test case 26484 * 26485 * @return Name of tested stage 26486 **/ 26487 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index) 26488 { 26489 const GLchar* name = 0; 26490 26491 switch (test_case_index) 26492 { 26493 case TEST_VS: 26494 name = "vertex"; 26495 break; 26496 case TEST_TES: 26497 name = "tessellation evaluation"; 26498 break; 26499 case TEST_GS: 26500 name = "geometry"; 26501 break; 26502 default: 26503 TCU_FAIL("Invalid enum"); 26504 } 26505 26506 return name; 26507 } 26508 26509 /** Returns number of test cases 26510 * 26511 * @return TEST_MAX 26512 **/ 26513 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber() 26514 { 26515 return TEST_MAX; 26516 } 26517 26518 /** Verify contents of buffers 26519 * 26520 * @param buffers Collection of buffers to be verified 26521 * 26522 * @return true if everything is as expected, false otherwise 26523 **/ 26524 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection& buffers) 26525 { 26526 bool result = true; 26527 26528 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */; 26529 Utils::Buffer* buffer = pair.m_buffer; 26530 bufferDescriptor* descriptor = pair.m_descriptor; 26531 26532 /* Get pointer to contents of buffer */ 26533 buffer->Bind(); 26534 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly); 26535 26536 /* Get pointer to expected data */ 26537 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0]; 26538 26539 /* Compare */ 26540 static const GLuint comp_size = 4; 26541 static const GLuint vec4_size = 16; 26542 26543 int res_goku_x = 26544 memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size); 26545 int res_goku_z = 26546 memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size); 26547 26548 int res_gohan_y = 26549 memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size); 26550 int res_gohan_w = 26551 memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size); 26552 26553 int res_goten_x = 26554 memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size); 26555 int res_goten_y = 26556 memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size); 26557 26558 int res_chichi_z = 26559 memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size); 26560 int res_chichi_w = 26561 memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size); 26562 26563 int res_vegeta_x = 26564 memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size); 26565 26566 int res_trunks_y = 26567 memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size); 26568 26569 int res_bra_z = 26570 memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size); 26571 26572 int res_bulma_w = 26573 memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size); 26574 26575 if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) || 26576 (0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) || 26577 (0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w)) 26578 { 26579 m_context.getTestContext().getLog() 26580 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target) 26581 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage; 26582 26583 result = false; 26584 } 26585 26586 /* Release buffer mapping */ 26587 buffer->UnMap(); 26588 26589 return result; 26590 } 26591 26592 /** Constructor 26593 * 26594 * @param context Test context 26595 **/ 26596 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context& context) 26597 : BufferTestBase(context, "xfb_capture_inactive_output_block_member", 26598 "Test verifies that inactive block members are captured") 26599 { 26600 /* Nothing to be done here */ 26601 } 26602 26603 /** Execute drawArrays for single vertex 26604 * 26605 * @param test_case_index 26606 * 26607 * @return true 26608 **/ 26609 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 26610 { 26611 const Functions& gl = m_context.getRenderContext().getFunctions(); 26612 GLenum primitive_type = GL_PATCHES; 26613 26614 if (TEST_VS == test_case_index) 26615 { 26616 primitive_type = GL_POINTS; 26617 } 26618 26619 gl.disable(GL_RASTERIZER_DISCARD); 26620 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 26621 26622 gl.beginTransformFeedback(GL_POINTS); 26623 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 26624 26625 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */); 26626 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 26627 26628 gl.endTransformFeedback(); 26629 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 26630 26631 return true; 26632 } 26633 26634 /** Get descriptors of buffers necessary for test 26635 * 26636 * @param ignored 26637 * @param out_descriptors Descriptors of buffers used by test 26638 **/ 26639 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 26640 bufferDescriptor::Vector& out_descriptors) 26641 { 26642 const Utils::Type& type = Utils::Type::vec4; 26643 26644 /* Test needs single uniform and xfb */ 26645 out_descriptors.resize(2); 26646 26647 /* Get references */ 26648 bufferDescriptor& uniform = out_descriptors[0]; 26649 bufferDescriptor& xfb = out_descriptors[1]; 26650 26651 /* Index */ 26652 uniform.m_index = 0; 26653 xfb.m_index = 0; 26654 26655 /* Target */ 26656 uniform.m_target = Utils::Buffer::Uniform; 26657 xfb.m_target = Utils::Buffer::Transform_feedback; 26658 26659 /* Data */ 26660 const std::vector<GLubyte>& gohan_data = type.GenerateData(); 26661 const std::vector<GLubyte>& chichi_data = type.GenerateData(); 26662 26663 const GLuint type_size = static_cast<GLuint>(gohan_data.size()); 26664 26665 /* Uniform data */ 26666 uniform.m_initial_data.resize(2 * type_size); 26667 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size); 26668 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size); 26669 26670 /* XFB data */ 26671 xfb.m_initial_data.resize(4 * type_size); 26672 xfb.m_expected_data.resize(4 * type_size); 26673 26674 for (GLuint i = 0; i < 4 * type_size; ++i) 26675 { 26676 xfb.m_initial_data[i] = (glw::GLubyte)i; 26677 xfb.m_expected_data[i] = (glw::GLubyte)i; 26678 } 26679 26680 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size); 26681 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size); 26682 } 26683 26684 /** Get body of main function for given shader stage 26685 * 26686 * @param test_case_index Index of test case 26687 * @param stage Shader stage 26688 * @param out_assignments Set to empty 26689 * @param out_calculations Set to empty 26690 **/ 26691 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, 26692 std::string& out_assignments, std::string& out_calculations) 26693 { 26694 out_calculations = ""; 26695 26696 static const GLchar* vs_tes_gs = " chichi = uni_chichi;\n" 26697 " gohan = uni_gohan;\n"; 26698 static const GLchar* fs = " fs_out = goten + gohan + chichi;\n"; 26699 26700 const GLchar* assignments = ""; 26701 26702 switch (stage) 26703 { 26704 case Utils::Shader::FRAGMENT: 26705 assignments = fs; 26706 break; 26707 26708 case Utils::Shader::GEOMETRY: 26709 if (TEST_GS == test_case_index) 26710 { 26711 assignments = vs_tes_gs; 26712 } 26713 break; 26714 26715 case Utils::Shader::TESS_CTRL: 26716 break; 26717 26718 case Utils::Shader::TESS_EVAL: 26719 if (TEST_TES == test_case_index) 26720 { 26721 assignments = vs_tes_gs; 26722 } 26723 break; 26724 26725 case Utils::Shader::VERTEX: 26726 if (TEST_VS == test_case_index) 26727 { 26728 assignments = vs_tes_gs; 26729 } 26730 break; 26731 26732 default: 26733 TCU_FAIL("Invalid enum"); 26734 } 26735 26736 out_assignments = assignments; 26737 } 26738 26739 /** Get interface of shader 26740 * 26741 * @param test_case_index Index of test case 26742 * @param stage Shader stage 26743 * @param out_interface Set to "" 26744 **/ 26745 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, 26746 std::string& out_interface) 26747 { 26748 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n" 26749 "\n" 26750 "layout (xfb_offset = 1 * sizeof_type) out Goku {\n" 26751 " vec4 gohan;\n" 26752 " vec4 goten;\n" 26753 " vec4 chichi;\n" 26754 "};\n" 26755 "\n" 26756 "layout(binding = 0) uniform block {\n" 26757 " vec4 uni_gohan;\n" 26758 " vec4 uni_chichi;\n" 26759 "};\n"; 26760 static const GLchar* fs = "in Goku {\n" 26761 " vec4 gohan;\n" 26762 " vec4 goten;\n" 26763 " vec4 chichi;\n" 26764 "};\n" 26765 "out vec4 fs_out;\n"; 26766 26767 const GLchar* interface = ""; 26768 26769 switch (stage) 26770 { 26771 case Utils::Shader::FRAGMENT: 26772 interface = fs; 26773 break; 26774 26775 case Utils::Shader::GEOMETRY: 26776 if (TEST_GS == test_case_index) 26777 { 26778 interface = vs_tes_gs; 26779 } 26780 break; 26781 26782 case Utils::Shader::TESS_CTRL: 26783 break; 26784 26785 case Utils::Shader::TESS_EVAL: 26786 if (TEST_TES == test_case_index) 26787 { 26788 interface = vs_tes_gs; 26789 } 26790 break; 26791 26792 case Utils::Shader::VERTEX: 26793 if (TEST_VS == test_case_index) 26794 { 26795 interface = vs_tes_gs; 26796 } 26797 break; 26798 26799 default: 26800 TCU_FAIL("Invalid enum"); 26801 } 26802 26803 out_interface = interface; 26804 } 26805 26806 /** Get source code of shader 26807 * 26808 * @param test_case_index Index of test case 26809 * @param stage Shader stage 26810 * 26811 * @return Source 26812 **/ 26813 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint test_case_index, 26814 Utils::Shader::STAGES stage) 26815 { 26816 std::string source; 26817 26818 switch (test_case_index) 26819 { 26820 case TEST_VS: 26821 switch (stage) 26822 { 26823 case Utils::Shader::FRAGMENT: 26824 case Utils::Shader::VERTEX: 26825 source = BufferTestBase::getShaderSource(test_case_index, stage); 26826 break; 26827 default: 26828 break; 26829 } 26830 break; 26831 26832 case TEST_TES: 26833 switch (stage) 26834 { 26835 case Utils::Shader::FRAGMENT: 26836 case Utils::Shader::TESS_CTRL: 26837 case Utils::Shader::TESS_EVAL: 26838 case Utils::Shader::VERTEX: 26839 source = BufferTestBase::getShaderSource(test_case_index, stage); 26840 break; 26841 default: 26842 break; 26843 } 26844 break; 26845 26846 case TEST_GS: 26847 source = BufferTestBase::getShaderSource(test_case_index, stage); 26848 break; 26849 26850 default: 26851 TCU_FAIL("Invalid enum"); 26852 break; 26853 } 26854 26855 /* */ 26856 return source; 26857 } 26858 26859 /** Get name of test case 26860 * 26861 * @param test_case_index Index of test case 26862 * 26863 * @return Name of tested stage 26864 **/ 26865 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index) 26866 { 26867 const GLchar* name = 0; 26868 26869 switch (test_case_index) 26870 { 26871 case TEST_VS: 26872 name = "vertex"; 26873 break; 26874 case TEST_TES: 26875 name = "tessellation evaluation"; 26876 break; 26877 case TEST_GS: 26878 name = "geometry"; 26879 break; 26880 default: 26881 TCU_FAIL("Invalid enum"); 26882 } 26883 26884 return name; 26885 } 26886 26887 /** Returns number of test cases 26888 * 26889 * @return TEST_MAX 26890 **/ 26891 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber() 26892 { 26893 return TEST_MAX; 26894 } 26895 26896 /** Verify contents of buffers 26897 * 26898 * @param buffers Collection of buffers to be verified 26899 * 26900 * @return true if everything is as expected, false otherwise 26901 **/ 26902 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection& buffers) 26903 { 26904 bool result = true; 26905 26906 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */; 26907 Utils::Buffer* buffer = pair.m_buffer; 26908 bufferDescriptor* descriptor = pair.m_descriptor; 26909 26910 /* Get pointer to contents of buffer */ 26911 buffer->Bind(); 26912 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly); 26913 26914 /* Get pointer to expected data */ 26915 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0]; 26916 26917 /* Compare */ 26918 static const GLuint vec4_size = 16; 26919 26920 int res_before = memcmp(buffer_data, expected_data, vec4_size); 26921 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size); 26922 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size); 26923 26924 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi)) 26925 { 26926 m_context.getTestContext().getLog() 26927 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target) 26928 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage; 26929 26930 result = false; 26931 } 26932 26933 /* Release buffer mapping */ 26934 buffer->UnMap(); 26935 26936 return result; 26937 } 26938 26939 /** Constructor 26940 * 26941 * @param context Test context 26942 **/ 26943 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context& context) 26944 : BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured") 26945 { 26946 /* Nothing to be done here */ 26947 } 26948 26949 /** Execute drawArrays for single vertex 26950 * 26951 * @param test_case_index 26952 * 26953 * @return true 26954 **/ 26955 bool XFBCaptureStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index) 26956 { 26957 const Functions& gl = m_context.getRenderContext().getFunctions(); 26958 GLenum primitive_type = GL_PATCHES; 26959 26960 if (TEST_VS == test_case_index) 26961 { 26962 primitive_type = GL_POINTS; 26963 } 26964 26965 gl.disable(GL_RASTERIZER_DISCARD); 26966 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable"); 26967 26968 gl.beginTransformFeedback(GL_POINTS); 26969 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 26970 26971 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */); 26972 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 26973 26974 gl.endTransformFeedback(); 26975 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 26976 26977 return true; 26978 } 26979 26980 /** Get descriptors of buffers necessary for test 26981 * 26982 * @param ignored 26983 * @param out_descriptors Descriptors of buffers used by test 26984 **/ 26985 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */, 26986 bufferDescriptor::Vector& out_descriptors) 26987 { 26988 const Utils::Type& type = Utils::Type::vec4; 26989 26990 /* Test needs single uniform and xfb */ 26991 out_descriptors.resize(2); 26992 26993 /* Get references */ 26994 bufferDescriptor& uniform = out_descriptors[0]; 26995 bufferDescriptor& xfb = out_descriptors[1]; 26996 26997 /* Index */ 26998 uniform.m_index = 0; 26999 xfb.m_index = 0; 27000 27001 /* Target */ 27002 uniform.m_target = Utils::Buffer::Uniform; 27003 xfb.m_target = Utils::Buffer::Transform_feedback; 27004 27005 /* Data */ 27006 const std::vector<GLubyte>& gohan_data = type.GenerateData(); 27007 const std::vector<GLubyte>& chichi_data = type.GenerateData(); 27008 27009 const GLuint type_size = static_cast<GLuint>(gohan_data.size()); 27010 27011 /* Uniform data */ 27012 uniform.m_initial_data.resize(2 * type_size); 27013 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size); 27014 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size); 27015 27016 /* XFB data */ 27017 xfb.m_initial_data.resize(4 * type_size); 27018 xfb.m_expected_data.resize(4 * type_size); 27019 27020 for (GLuint i = 0; i < 4 * type_size; ++i) 27021 { 27022 xfb.m_initial_data[i] = (glw::GLubyte)i; 27023 xfb.m_expected_data[i] = (glw::GLubyte)i; 27024 } 27025 27026 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size); 27027 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size); 27028 } 27029 27030 /** Get body of main function for given shader stage 27031 * 27032 * @param test_case_index Index of test case 27033 * @param stage Shader stage 27034 * @param out_assignments Set to empty 27035 * @param out_calculations Set to empty 27036 **/ 27037 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, 27038 std::string& out_assignments, std::string& out_calculations) 27039 { 27040 out_calculations = ""; 27041 27042 static const GLchar* vs_tes_gs = " goku.chichi = uni_chichi;\n" 27043 " goku.gohan = uni_gohan;\n"; 27044 static const GLchar* fs = " fs_out = goku.goten + goku.gohan + goku.chichi;\n"; 27045 27046 const GLchar* assignments = ""; 27047 27048 switch (stage) 27049 { 27050 case Utils::Shader::FRAGMENT: 27051 assignments = fs; 27052 break; 27053 27054 case Utils::Shader::GEOMETRY: 27055 if (TEST_GS == test_case_index) 27056 { 27057 assignments = vs_tes_gs; 27058 } 27059 break; 27060 27061 case Utils::Shader::TESS_CTRL: 27062 break; 27063 27064 case Utils::Shader::TESS_EVAL: 27065 if (TEST_TES == test_case_index) 27066 { 27067 assignments = vs_tes_gs; 27068 } 27069 break; 27070 27071 case Utils::Shader::VERTEX: 27072 if (TEST_VS == test_case_index) 27073 { 27074 assignments = vs_tes_gs; 27075 } 27076 break; 27077 27078 default: 27079 TCU_FAIL("Invalid enum"); 27080 } 27081 27082 out_assignments = assignments; 27083 } 27084 27085 /** Get interface of shader 27086 * 27087 * @param test_case_index Index of test case 27088 * @param stage Shader stage 27089 * @param out_interface Set to "" 27090 **/ 27091 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, 27092 std::string& out_interface) 27093 { 27094 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n" 27095 "\n" 27096 "struct Goku {\n" 27097 " vec4 gohan;\n" 27098 " vec4 goten;\n" 27099 " vec4 chichi;\n" 27100 "};\n" 27101 "\n" 27102 "layout (xfb_offset = sizeof_type) out Goku goku;\n" 27103 "\n" 27104 "layout(binding = 0, std140) uniform block {\n" 27105 " vec4 uni_gohan;\n" 27106 " vec4 uni_chichi;\n" 27107 "};\n"; 27108 static const GLchar* fs = "struct Goku {\n" 27109 " vec4 gohan;\n" 27110 " vec4 goten;\n" 27111 " vec4 chichi;\n" 27112 "};\n" 27113 "\n" 27114 "in Goku goku;\n" 27115 "\n" 27116 "out vec4 fs_out;\n"; 27117 27118 const GLchar* interface = ""; 27119 27120 switch (stage) 27121 { 27122 case Utils::Shader::FRAGMENT: 27123 interface = fs; 27124 break; 27125 27126 case Utils::Shader::GEOMETRY: 27127 if (TEST_GS == test_case_index) 27128 { 27129 interface = vs_tes_gs; 27130 } 27131 break; 27132 27133 case Utils::Shader::TESS_CTRL: 27134 break; 27135 27136 case Utils::Shader::TESS_EVAL: 27137 if (TEST_TES == test_case_index) 27138 { 27139 interface = vs_tes_gs; 27140 } 27141 break; 27142 27143 case Utils::Shader::VERTEX: 27144 if (TEST_VS == test_case_index) 27145 { 27146 interface = vs_tes_gs; 27147 } 27148 break; 27149 27150 default: 27151 TCU_FAIL("Invalid enum"); 27152 } 27153 27154 out_interface = interface; 27155 } 27156 27157 /** Get source code of shader 27158 * 27159 * @param test_case_index Index of test case 27160 * @param stage Shader stage 27161 * 27162 * @return Source 27163 **/ 27164 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 27165 { 27166 std::string source; 27167 27168 switch (test_case_index) 27169 { 27170 case TEST_VS: 27171 switch (stage) 27172 { 27173 case Utils::Shader::FRAGMENT: 27174 case Utils::Shader::VERTEX: 27175 source = BufferTestBase::getShaderSource(test_case_index, stage); 27176 break; 27177 default: 27178 break; 27179 } 27180 break; 27181 27182 case TEST_TES: 27183 switch (stage) 27184 { 27185 case Utils::Shader::FRAGMENT: 27186 case Utils::Shader::TESS_CTRL: 27187 case Utils::Shader::TESS_EVAL: 27188 case Utils::Shader::VERTEX: 27189 source = BufferTestBase::getShaderSource(test_case_index, stage); 27190 break; 27191 default: 27192 break; 27193 } 27194 break; 27195 27196 case TEST_GS: 27197 source = BufferTestBase::getShaderSource(test_case_index, stage); 27198 break; 27199 27200 default: 27201 TCU_FAIL("Invalid enum"); 27202 break; 27203 } 27204 27205 /* */ 27206 return source; 27207 } 27208 27209 /** Get name of test case 27210 * 27211 * @param test_case_index Index of test case 27212 * 27213 * @return Name of tested stage 27214 **/ 27215 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index) 27216 { 27217 const GLchar* name = 0; 27218 27219 switch (test_case_index) 27220 { 27221 case TEST_VS: 27222 name = "vertex"; 27223 break; 27224 case TEST_TES: 27225 name = "tessellation evaluation"; 27226 break; 27227 case TEST_GS: 27228 name = "geometry"; 27229 break; 27230 default: 27231 TCU_FAIL("Invalid enum"); 27232 } 27233 27234 return name; 27235 } 27236 27237 /** Returns number of test cases 27238 * 27239 * @return TEST_MAX 27240 **/ 27241 glw::GLuint XFBCaptureStructTest::getTestCaseNumber() 27242 { 27243 return TEST_MAX; 27244 } 27245 27246 /** Verify contents of buffers 27247 * 27248 * @param buffers Collection of buffers to be verified 27249 * 27250 * @return true if everything is as expected, false otherwise 27251 **/ 27252 bool XFBCaptureStructTest::verifyBuffers(bufferCollection& buffers) 27253 { 27254 bool result = true; 27255 27256 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */; 27257 Utils::Buffer* buffer = pair.m_buffer; 27258 bufferDescriptor* descriptor = pair.m_descriptor; 27259 27260 /* Get pointer to contents of buffer */ 27261 buffer->Bind(); 27262 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly); 27263 27264 /* Get pointer to expected data */ 27265 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0]; 27266 27267 /* Compare */ 27268 static const GLuint vec4_size = 16; 27269 27270 int res_before = memcmp(buffer_data, expected_data, vec4_size); 27271 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size); 27272 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size); 27273 27274 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi)) 27275 { 27276 m_context.getTestContext().getLog() 27277 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target) 27278 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage; 27279 27280 result = false; 27281 } 27282 27283 /* Release buffer mapping */ 27284 buffer->UnMap(); 27285 27286 return result; 27287 } 27288 27289 /** Constructor 27290 * 27291 * @param context Test framework context 27292 **/ 27293 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context& context) 27294 : NegativeTestBase(context, "xfb_capture_unsized_array", 27295 "Test verifies that compiler reports error when unsized array is qualified with xfb_offset") 27296 { 27297 } 27298 27299 /** Source for given test case and stage 27300 * 27301 * @param test_case_index Index of test case 27302 * @param stage Shader stage 27303 * 27304 * @return Shader source 27305 **/ 27306 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage) 27307 { 27308 static const GLchar* var_definition = "layout (xfb_offset = 0) out vec4 gokuARRAY[];\n"; 27309 static const GLchar* var_use = " gokuINDEX[0] = result / 2;\n"; 27310 static const GLchar* fs = "#version 430 core\n" 27311 "#extension GL_ARB_enhanced_layouts : require\n" 27312 "\n" 27313 "in vec4 gs_fs;\n" 27314 "out vec4 fs_out;\n" 27315 "\n" 27316 "void main()\n" 27317 "{\n" 27318 " fs_out = gs_fs;\n" 27319 "}\n" 27320 "\n"; 27321 static const GLchar* gs_tested = "#version 430 core\n" 27322 "#extension GL_ARB_enhanced_layouts : require\n" 27323 "\n" 27324 "layout(points) in;\n" 27325 "layout(triangle_strip, max_vertices = 4) out;\n" 27326 "\n" 27327 "VAR_DEFINITION" 27328 "\n" 27329 "in vec4 tes_gs[];\n" 27330 "out vec4 gs_fs;\n" 27331 "\n" 27332 "void main()\n" 27333 "{\n" 27334 " vec4 result = tes_gs[0];\n" 27335 "\n" 27336 "VARIABLE_USE" 27337 "\n" 27338 " gs_fs = result;\n" 27339 " gl_Position = vec4(-1, -1, 0, 1);\n" 27340 " EmitVertex();\n" 27341 " gs_fs = result;\n" 27342 " gl_Position = vec4(-1, 1, 0, 1);\n" 27343 " EmitVertex();\n" 27344 " gs_fs = result;\n" 27345 " gl_Position = vec4(1, -1, 0, 1);\n" 27346 " EmitVertex();\n" 27347 " gs_fs = result;\n" 27348 " gl_Position = vec4(1, 1, 0, 1);\n" 27349 " EmitVertex();\n" 27350 "}\n" 27351 "\n"; 27352 static const GLchar* tcs = "#version 430 core\n" 27353 "#extension GL_ARB_enhanced_layouts : require\n" 27354 "\n" 27355 "layout(vertices = 1) out;\n" 27356 "\n" 27357 "in vec4 vs_tcs[];\n" 27358 "out vec4 tcs_tes[];\n" 27359 "\n" 27360 "void main()\n" 27361 "{\n" 27362 "\n" 27363 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n" 27364 "\n" 27365 " gl_TessLevelOuter[0] = 1.0;\n" 27366 " gl_TessLevelOuter[1] = 1.0;\n" 27367 " gl_TessLevelOuter[2] = 1.0;\n" 27368 " gl_TessLevelOuter[3] = 1.0;\n" 27369 " gl_TessLevelInner[0] = 1.0;\n" 27370 " gl_TessLevelInner[1] = 1.0;\n" 27371 "}\n" 27372 "\n"; 27373 static const GLchar* tcs_tested = "#version 430 core\n" 27374 "#extension GL_ARB_enhanced_layouts : require\n" 27375 "\n" 27376 "layout(vertices = 1) out;\n" 27377 "\n" 27378 "VAR_DEFINITION" 27379 "\n" 27380 "in vec4 vs_tcs[];\n" 27381 "out vec4 tcs_tes[];\n" 27382 "\n" 27383 "void main()\n" 27384 "{\n" 27385 " vec4 result = vs_tcs[gl_InvocationID];\n" 27386 "\n" 27387 "VARIABLE_USE" 27388 "\n" 27389 " tcs_tes[gl_InvocationID] = result;\n" 27390 "\n" 27391 " gl_TessLevelOuter[0] = 1.0;\n" 27392 " gl_TessLevelOuter[1] = 1.0;\n" 27393 " gl_TessLevelOuter[2] = 1.0;\n" 27394 " gl_TessLevelOuter[3] = 1.0;\n" 27395 " gl_TessLevelInner[0] = 1.0;\n" 27396 " gl_TessLevelInner[1] = 1.0;\n" 27397 "}\n" 27398 "\n"; 27399 static const GLchar* tes_tested = "#version 430 core\n" 27400 "#extension GL_ARB_enhanced_layouts : require\n" 27401 "\n" 27402 "layout(isolines, point_mode) in;\n" 27403 "\n" 27404 "VAR_DEFINITION" 27405 "\n" 27406 "in vec4 tcs_tes[];\n" 27407 "out vec4 tes_gs;\n" 27408 "\n" 27409 "void main()\n" 27410 "{\n" 27411 " vec4 result = tcs_tes[0];\n" 27412 "\n" 27413 "VARIABLE_USE" 27414 "\n" 27415 " tes_gs += result;\n" 27416 "}\n" 27417 "\n"; 27418 static const GLchar* vs = "#version 430 core\n" 27419 "#extension GL_ARB_enhanced_layouts : require\n" 27420 "\n" 27421 "in vec4 in_vs;\n" 27422 "out vec4 vs_tcs;\n" 27423 "\n" 27424 "void main()\n" 27425 "{\n" 27426 " vs_tcs = in_vs;\n" 27427 "}\n" 27428 "\n"; 27429 static const GLchar* vs_tested = "#version 430 core\n" 27430 "#extension GL_ARB_enhanced_layouts : require\n" 27431 "\n" 27432 "VAR_DEFINITION" 27433 "\n" 27434 "in vec4 in_vs;\n" 27435 "out vec4 vs_tcs;\n" 27436 "\n" 27437 "void main()\n" 27438 "{\n" 27439 " vec4 result = in_vs;\n" 27440 "\n" 27441 "VARIABLE_USE" 27442 "\n" 27443 " vs_tcs = result;\n" 27444 "}\n" 27445 "\n"; 27446 27447 std::string source; 27448 testCase& test_case = m_test_cases[test_case_index]; 27449 27450 if (test_case.m_stage == stage) 27451 { 27452 const GLchar* array = ""; 27453 const GLchar* index = ""; 27454 size_t position = 0; 27455 27456 switch (stage) 27457 { 27458 case Utils::Shader::GEOMETRY: 27459 source = gs_tested; 27460 array = "[]"; 27461 index = "[0]"; 27462 break; 27463 case Utils::Shader::TESS_CTRL: 27464 source = tcs_tested; 27465 array = "[]"; 27466 index = "[gl_InvocationID]"; 27467 break; 27468 case Utils::Shader::TESS_EVAL: 27469 source = tes_tested; 27470 array = "[]"; 27471 index = "[0]"; 27472 break; 27473 case Utils::Shader::VERTEX: 27474 source = vs_tested; 27475 break; 27476 default: 27477 TCU_FAIL("Invalid enum"); 27478 } 27479 27480 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source); 27481 position = 0; 27482 Utils::replaceToken("ARRAY", position, array, source); 27483 Utils::replaceToken("VARIABLE_USE", position, var_use, source); 27484 27485 Utils::replaceAllTokens("INDEX", index, source); 27486 } 27487 else 27488 { 27489 switch (test_case.m_stage) 27490 { 27491 case Utils::Shader::GEOMETRY: 27492 switch (stage) 27493 { 27494 case Utils::Shader::FRAGMENT: 27495 source = fs; 27496 break; 27497 case Utils::Shader::VERTEX: 27498 source = vs; 27499 break; 27500 default: 27501 source = ""; 27502 } 27503 break; 27504 case Utils::Shader::TESS_CTRL: 27505 switch (stage) 27506 { 27507 case Utils::Shader::FRAGMENT: 27508 source = fs; 27509 break; 27510 case Utils::Shader::VERTEX: 27511 source = vs; 27512 break; 27513 default: 27514 source = ""; 27515 } 27516 break; 27517 case Utils::Shader::TESS_EVAL: 27518 switch (stage) 27519 { 27520 case Utils::Shader::FRAGMENT: 27521 source = fs; 27522 break; 27523 case Utils::Shader::TESS_CTRL: 27524 source = tcs; 27525 break; 27526 case Utils::Shader::VERTEX: 27527 source = vs; 27528 break; 27529 default: 27530 source = ""; 27531 } 27532 break; 27533 case Utils::Shader::VERTEX: 27534 switch (stage) 27535 { 27536 case Utils::Shader::FRAGMENT: 27537 source = fs; 27538 break; 27539 default: 27540 source = ""; 27541 } 27542 break; 27543 default: 27544 TCU_FAIL("Invalid enum"); 27545 break; 27546 } 27547 } 27548 27549 return source; 27550 } 27551 27552 /** Get description of test case 27553 * 27554 * @param test_case_index Index of test case 27555 * 27556 * @return Test case description 27557 **/ 27558 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index) 27559 { 27560 std::stringstream stream; 27561 testCase& test_case = m_test_cases[test_case_index]; 27562 27563 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage); 27564 27565 return stream.str(); 27566 } 27567 27568 /** Get number of test cases 27569 * 27570 * @return Number of test cases 27571 **/ 27572 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber() 27573 { 27574 return static_cast<GLuint>(m_test_cases.size()); 27575 } 27576 27577 /** Selects if "compute" stage is relevant for test 27578 * 27579 * @param ignored 27580 * 27581 * @return false 27582 **/ 27583 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */) 27584 { 27585 return false; 27586 } 27587 27588 /** Prepare all test cases 27589 * 27590 **/ 27591 void XFBCaptureUnsizedArrayTest::testInit() 27592 { 27593 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage) 27594 { 27595 /* Not aplicable for */ 27596 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) || 27597 (Utils::Shader::GEOMETRY == stage) || (Utils::Shader::TESS_EVAL == stage)) 27598 { 27599 continue; 27600 } 27601 27602 testCase test_case = { (Utils::Shader::STAGES)stage }; 27603 27604 m_test_cases.push_back(test_case); 27605 } 27606 } 27607 } /* EnhancedLayouts namespace */ 27608 27609 /** Constructor. 27610 * 27611 * @param context Rendering context. 27612 **/ 27613 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context& context) 27614 : TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality") 27615 { 27616 /* Left blank on purpose */ 27617 } 27618 27619 /** Initializes a texture_storage_multisample test group. 27620 * 27621 **/ 27622 void EnhancedLayoutsTests::init(void) 27623 { 27624 addChild(new EnhancedLayouts::APIConstantValuesTest(m_context)); 27625 addChild(new EnhancedLayouts::APIErrorsTest(m_context)); 27626 addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context)); 27627 addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context)); 27628 addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context)); 27629 addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context)); 27630 addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context)); 27631 addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context)); 27632 addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context)); 27633 addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context)); 27634 addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context)); 27635 addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context)); 27636 addChild(new EnhancedLayouts::XFBInputTest(m_context)); 27637 addChild(new EnhancedLayouts::XFBAllStagesTest(m_context)); 27638 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context)); 27639 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context)); 27640 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context)); 27641 addChild(new EnhancedLayouts::XFBStrideTest(m_context)); 27642 27643 addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context)); 27644 addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context)); 27645 addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context)); 27646 addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context)); 27647 addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context)); 27648 addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context)); 27649 addChild(new EnhancedLayouts::SSBAlignmentTest(m_context)); 27650 addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context)); 27651 addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context)); 27652 addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context)); 27653 addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context)); 27654 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context)); 27655 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context)); 27656 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context)); 27657 addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context)); 27658 addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context)); 27659 addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context)); 27660 addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context)); 27661 addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context)); 27662 addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context)); 27663 addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context)); 27664 addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context)); 27665 addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context)); 27666 addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context)); 27667 addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context)); 27668 addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context)); 27669 addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context)); 27670 addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context)); 27671 addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context)); 27672 addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context)); 27673 addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context)); 27674 addChild(new EnhancedLayouts::VaryingLocationsTest(m_context)); 27675 addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context)); 27676 addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context)); 27677 addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context)); 27678 addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context)); 27679 addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context)); 27680 addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context)); 27681 addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context)); 27682 addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context)); 27683 addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context)); 27684 addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context)); 27685 addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context)); 27686 addChild(new EnhancedLayouts::VaryingComponentsTest(m_context)); 27687 addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context)); 27688 } 27689 27690 } /* gl4cts namespace */ 27691