1 /*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2014-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 gl4GPUShaderFP64Tests.cpp 26 * \brief Implements conformance tests for "GPU Shader FP64" functionality. 27 */ /*-------------------------------------------------------------------*/ 28 29 #include "gl4cGPUShaderFP64Tests.hpp" 30 #include "gluContextInfo.hpp" 31 #include "glwFunctions.hpp" 32 #include "tcuMatrix.hpp" 33 #include "tcuTestLog.hpp" 34 35 #include <iomanip> 36 37 #include "deMath.h" 38 #include "deUniquePtr.hpp" 39 #include "tcuMatrixUtil.hpp" 40 #include "tcuVectorUtil.hpp" 41 42 #include <cstdlib> 43 #include <cstring> 44 #include <limits> 45 #include <memory> 46 47 namespace gl4cts 48 { 49 50 const glw::GLenum Utils::programInfo::ARB_COMPUTE_SHADER = 0x91B9; 51 52 /** Constructor 53 * 54 * @param context Test context 55 **/ 56 Utils::programInfo::programInfo(deqp::Context& context) 57 : m_context(context) 58 , m_compute_shader_id(0) 59 , m_fragment_shader_id(0) 60 , m_geometry_shader_id(0) 61 , m_program_object_id(0) 62 , m_tesselation_control_shader_id(0) 63 , m_tesselation_evaluation_shader_id(0) 64 , m_vertex_shader_id(0) 65 { 66 /* Nothing to be done here */ 67 } 68 69 /** Destructor 70 * 71 **/ 72 Utils::programInfo::~programInfo() 73 { 74 /* GL entry points */ 75 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 76 77 /* Make sure program object is no longer used by GL */ 78 gl.useProgram(0); 79 80 /* Clean program object */ 81 if (0 != m_program_object_id) 82 { 83 gl.deleteProgram(m_program_object_id); 84 m_program_object_id = 0; 85 } 86 87 /* Clean shaders */ 88 if (0 != m_compute_shader_id) 89 { 90 gl.deleteShader(m_compute_shader_id); 91 m_compute_shader_id = 0; 92 } 93 94 if (0 != m_fragment_shader_id) 95 { 96 gl.deleteShader(m_fragment_shader_id); 97 m_fragment_shader_id = 0; 98 } 99 100 if (0 != m_geometry_shader_id) 101 { 102 gl.deleteShader(m_geometry_shader_id); 103 m_geometry_shader_id = 0; 104 } 105 106 if (0 != m_tesselation_control_shader_id) 107 { 108 gl.deleteShader(m_tesselation_control_shader_id); 109 m_tesselation_control_shader_id = 0; 110 } 111 112 if (0 != m_tesselation_evaluation_shader_id) 113 { 114 gl.deleteShader(m_tesselation_evaluation_shader_id); 115 m_tesselation_evaluation_shader_id = 0; 116 } 117 118 if (0 != m_vertex_shader_id) 119 { 120 gl.deleteShader(m_vertex_shader_id); 121 m_vertex_shader_id = 0; 122 } 123 } 124 125 /** Build program 126 * 127 * @param compute_shader_code Compute shader source code 128 * @param fragment_shader_code Fragment shader source code 129 * @param geometry_shader_code Geometry shader source code 130 * @param tesselation_control_shader_code Tesselation control shader source code 131 * @param tesselation_evaluation_shader_code Tesselation evaluation shader source code 132 * @param vertex_shader_code Vertex shader source code 133 * @param varying_names Array of strings containing names of varyings to be captured with transfrom feedback 134 * @param n_varying_names Number of varyings to be captured with transfrom feedback 135 **/ 136 void Utils::programInfo::build(const glw::GLchar* compute_shader_code, const glw::GLchar* fragment_shader_code, 137 const glw::GLchar* geometry_shader_code, 138 const glw::GLchar* tesselation_control_shader_code, 139 const glw::GLchar* tesselation_evaluation_shader_code, 140 const glw::GLchar* vertex_shader_code, const glw::GLchar* const* varying_names, 141 glw::GLuint n_varying_names) 142 { 143 /* GL entry points */ 144 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 145 146 /* Create shader objects and compile */ 147 if (0 != compute_shader_code) 148 { 149 m_compute_shader_id = gl.createShader(ARB_COMPUTE_SHADER); 150 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 151 152 compile(m_compute_shader_id, compute_shader_code); 153 } 154 155 if (0 != fragment_shader_code) 156 { 157 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER); 158 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 159 160 compile(m_fragment_shader_id, fragment_shader_code); 161 } 162 163 if (0 != geometry_shader_code) 164 { 165 m_geometry_shader_id = gl.createShader(GL_GEOMETRY_SHADER); 166 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 167 168 compile(m_geometry_shader_id, geometry_shader_code); 169 } 170 171 if (0 != tesselation_control_shader_code) 172 { 173 m_tesselation_control_shader_id = gl.createShader(GL_TESS_CONTROL_SHADER); 174 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 175 176 compile(m_tesselation_control_shader_id, tesselation_control_shader_code); 177 } 178 179 if (0 != tesselation_evaluation_shader_code) 180 { 181 m_tesselation_evaluation_shader_id = gl.createShader(GL_TESS_EVALUATION_SHADER); 182 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 183 184 compile(m_tesselation_evaluation_shader_id, tesselation_evaluation_shader_code); 185 } 186 187 if (0 != vertex_shader_code) 188 { 189 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER); 190 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 191 192 compile(m_vertex_shader_id, vertex_shader_code); 193 } 194 195 /* Create program object */ 196 m_program_object_id = gl.createProgram(); 197 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram"); 198 199 /* Set up captyured varyings' names */ 200 if (0 != n_varying_names) 201 { 202 gl.transformFeedbackVaryings(m_program_object_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS); 203 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings"); 204 } 205 206 /* Link program */ 207 link(); 208 } 209 210 /** Compile shader 211 * 212 * @param shader_id Shader object id 213 * @param shader_code Shader source code 214 **/ 215 void Utils::programInfo::compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const 216 { 217 /* GL entry points */ 218 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 219 220 /* Compilation status */ 221 glw::GLint status = GL_FALSE; 222 223 /* Set source code */ 224 gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0); 225 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource"); 226 227 /* Compile */ 228 gl.compileShader(shader_id); 229 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader"); 230 231 /* Get compilation status */ 232 gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status); 233 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 234 235 /* Log compilation error */ 236 if (GL_TRUE != status) 237 { 238 glw::GLint length = 0; 239 std::vector<glw::GLchar> message; 240 241 /* Error log length */ 242 gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length); 243 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 244 245 /* Prepare storage */ 246 message.resize(length); 247 248 /* Get error log */ 249 gl.getShaderInfoLog(shader_id, length, 0, &message[0]); 250 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog"); 251 252 /* Log */ 253 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n" 254 << &message[0] << "\nShader source\n" 255 << shader_code << tcu::TestLog::EndMessage; 256 257 TCU_FAIL("Failed to compile shader"); 258 } 259 } 260 261 /** Attach shaders and link program 262 * 263 **/ 264 void Utils::programInfo::link() const 265 { 266 /* GL entry points */ 267 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 268 269 /* Link status */ 270 glw::GLint status = GL_FALSE; 271 272 /* Attach shaders */ 273 if (0 != m_compute_shader_id) 274 { 275 gl.attachShader(m_program_object_id, m_compute_shader_id); 276 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 277 } 278 279 if (0 != m_fragment_shader_id) 280 { 281 gl.attachShader(m_program_object_id, m_fragment_shader_id); 282 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 283 } 284 285 if (0 != m_geometry_shader_id) 286 { 287 gl.attachShader(m_program_object_id, m_geometry_shader_id); 288 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 289 } 290 291 if (0 != m_tesselation_control_shader_id) 292 { 293 gl.attachShader(m_program_object_id, m_tesselation_control_shader_id); 294 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 295 } 296 297 if (0 != m_tesselation_evaluation_shader_id) 298 { 299 gl.attachShader(m_program_object_id, m_tesselation_evaluation_shader_id); 300 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 301 } 302 303 if (0 != m_vertex_shader_id) 304 { 305 gl.attachShader(m_program_object_id, m_vertex_shader_id); 306 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 307 } 308 309 /* Link */ 310 gl.linkProgram(m_program_object_id); 311 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram"); 312 313 /* Get link status */ 314 gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status); 315 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 316 317 /* Log link error */ 318 if (GL_TRUE != status) 319 { 320 glw::GLint length = 0; 321 std::vector<glw::GLchar> message; 322 323 /* Get error log length */ 324 gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length); 325 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 326 327 message.resize(length); 328 329 /* Get error log */ 330 gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]); 331 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog"); 332 333 /* Log */ 334 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n" 335 << &message[0] << tcu::TestLog::EndMessage; 336 337 TCU_FAIL("Failed to link program"); 338 } 339 } 340 341 /** Retrieves base type of user-provided variable type. (eg. VARIABLE_TYPE_DOUBLE for double-precision 342 * matrix types. 343 * 344 * @param type Variable type to return base type for. 345 * 346 * @return Requested value or VARAIBLE_TYPE_UNKNOWN if @param type was not recognized. 347 **/ 348 Utils::_variable_type Utils::getBaseVariableType(_variable_type type) 349 { 350 _variable_type result = VARIABLE_TYPE_UNKNOWN; 351 352 switch (type) 353 { 354 case VARIABLE_TYPE_BOOL: 355 { 356 result = VARIABLE_TYPE_BOOL; 357 358 break; 359 } 360 361 case VARIABLE_TYPE_DOUBLE: 362 case VARIABLE_TYPE_DMAT2: 363 case VARIABLE_TYPE_DMAT2X3: 364 case VARIABLE_TYPE_DMAT2X4: 365 case VARIABLE_TYPE_DMAT3: 366 case VARIABLE_TYPE_DMAT3X2: 367 case VARIABLE_TYPE_DMAT3X4: 368 case VARIABLE_TYPE_DMAT4: 369 case VARIABLE_TYPE_DMAT4X2: 370 case VARIABLE_TYPE_DMAT4X3: 371 case VARIABLE_TYPE_DVEC2: 372 case VARIABLE_TYPE_DVEC3: 373 case VARIABLE_TYPE_DVEC4: 374 { 375 result = VARIABLE_TYPE_DOUBLE; 376 377 break; 378 } 379 380 case VARIABLE_TYPE_INT: 381 case VARIABLE_TYPE_IVEC2: 382 case VARIABLE_TYPE_IVEC3: 383 case VARIABLE_TYPE_IVEC4: 384 { 385 result = VARIABLE_TYPE_INT; 386 387 break; 388 } 389 390 case VARIABLE_TYPE_UINT: 391 case VARIABLE_TYPE_UVEC2: 392 case VARIABLE_TYPE_UVEC3: 393 case VARIABLE_TYPE_UVEC4: 394 { 395 result = VARIABLE_TYPE_UINT; 396 397 break; 398 } 399 400 case VARIABLE_TYPE_FLOAT: 401 case VARIABLE_TYPE_MAT2: 402 case VARIABLE_TYPE_MAT2X3: 403 case VARIABLE_TYPE_MAT2X4: 404 case VARIABLE_TYPE_MAT3: 405 case VARIABLE_TYPE_MAT3X2: 406 case VARIABLE_TYPE_MAT3X4: 407 case VARIABLE_TYPE_MAT4: 408 case VARIABLE_TYPE_MAT4X2: 409 case VARIABLE_TYPE_MAT4X3: 410 case VARIABLE_TYPE_VEC2: 411 case VARIABLE_TYPE_VEC3: 412 case VARIABLE_TYPE_VEC4: 413 { 414 result = VARIABLE_TYPE_FLOAT; 415 416 break; 417 } 418 419 default: 420 { 421 TCU_FAIL("Unrecognized variable type"); 422 } 423 } /* switch (type) */ 424 425 return result; 426 } 427 428 /** Returns size (in bytes) of a single component of a base variable type. 429 * 430 * @param type Base variable type to use for the query. 431 * 432 * @return Requested value or 0 if @param type was not recognized. 433 **/ 434 unsigned int Utils::getBaseVariableTypeComponentSize(_variable_type type) 435 { 436 unsigned int result = 0; 437 438 switch (type) 439 { 440 case VARIABLE_TYPE_BOOL: 441 result = sizeof(bool); 442 break; 443 case VARIABLE_TYPE_DOUBLE: 444 result = sizeof(double); 445 break; 446 case VARIABLE_TYPE_FLOAT: 447 result = sizeof(float); 448 break; 449 case VARIABLE_TYPE_INT: 450 result = sizeof(int); 451 break; 452 case VARIABLE_TYPE_UINT: 453 result = sizeof(unsigned int); 454 break; 455 456 default: 457 { 458 TCU_FAIL("Unrecognized variable type"); 459 } 460 } /* switch (type) */ 461 462 return result; 463 } 464 465 /** Returns component, corresponding to user-specified index 466 * (eg. index:0 corresponds to 'x', index:1 corresponds to 'y', 467 * and so on. 468 * 469 * @param index Component index. 470 * 471 * @return As per description. 472 **/ 473 unsigned char Utils::getComponentAtIndex(unsigned int index) 474 { 475 unsigned char result = '?'; 476 477 switch (index) 478 { 479 case 0: 480 result = 'x'; 481 break; 482 case 1: 483 result = 'y'; 484 break; 485 case 2: 486 result = 'z'; 487 break; 488 case 3: 489 result = 'w'; 490 break; 491 492 default: 493 { 494 TCU_FAIL("Unrecognized component index"); 495 } 496 } 497 498 return result; 499 } 500 501 /** Get _variable_type representing double-precision type with given dimmensions 502 * 503 * @param n_columns Number of columns 504 * @param n_row Number of rows 505 * 506 * @return Corresponding _variable_type 507 **/ 508 Utils::_variable_type Utils::getDoubleVariableType(glw::GLuint n_columns, glw::GLuint n_rows) 509 { 510 Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN; 511 512 static const _variable_type types[4][4] = { 513 { VARIABLE_TYPE_DOUBLE, VARIABLE_TYPE_DVEC2, VARIABLE_TYPE_DVEC3, VARIABLE_TYPE_DVEC4 }, 514 { VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT2, VARIABLE_TYPE_DMAT2X3, VARIABLE_TYPE_DMAT2X4 }, 515 { VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT3X2, VARIABLE_TYPE_DMAT3, VARIABLE_TYPE_DMAT3X4 }, 516 { VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT4X2, VARIABLE_TYPE_DMAT4X3, VARIABLE_TYPE_DMAT4 } 517 }; 518 519 type = types[n_columns - 1][n_rows - 1]; 520 521 return type; 522 } 523 524 /** Returns a single-precision equivalent of a double-precision floating-point variable 525 * type. 526 * 527 * @param type Double-precision variable type. Only VARIABLE_TYPE_D* variable types 528 * are accepted. 529 * 530 * @return Requested GLSL type. 531 **/ 532 std::string Utils::getFPVariableTypeStringForVariableType(_variable_type type) 533 { 534 std::string result = "[?]"; 535 536 switch (type) 537 { 538 case VARIABLE_TYPE_DOUBLE: 539 result = "float"; 540 break; 541 case VARIABLE_TYPE_DMAT2: 542 result = "mat2"; 543 break; 544 case VARIABLE_TYPE_DMAT2X3: 545 result = "mat2x3"; 546 break; 547 case VARIABLE_TYPE_DMAT2X4: 548 result = "mat2x4"; 549 break; 550 case VARIABLE_TYPE_DMAT3: 551 result = "mat3"; 552 break; 553 case VARIABLE_TYPE_DMAT3X2: 554 result = "mat3x2"; 555 break; 556 case VARIABLE_TYPE_DMAT3X4: 557 result = "mat3x4"; 558 break; 559 case VARIABLE_TYPE_DMAT4: 560 result = "mat4"; 561 break; 562 case VARIABLE_TYPE_DMAT4X2: 563 result = "mat4x2"; 564 break; 565 case VARIABLE_TYPE_DMAT4X3: 566 result = "mat4x3"; 567 break; 568 case VARIABLE_TYPE_DVEC2: 569 result = "vec2"; 570 break; 571 case VARIABLE_TYPE_DVEC3: 572 result = "vec3"; 573 break; 574 case VARIABLE_TYPE_DVEC4: 575 result = "vec4"; 576 break; 577 578 default: 579 { 580 TCU_FAIL("Unrecognized variable type"); 581 } 582 }; /* switch (type) */ 583 584 return result; 585 } 586 587 /** Returns GL data type enum corresponding to user-provided base variable type. 588 * 589 * @param type Base variable type to return corresponding GLenum value for. 590 * 591 * @return Corresponding GLenum value or GL_NONE if the input value was not 592 * recognized. 593 **/ 594 glw::GLenum Utils::getGLDataTypeOfBaseVariableType(_variable_type type) 595 { 596 glw::GLenum result = GL_NONE; 597 598 switch (type) 599 { 600 case VARIABLE_TYPE_BOOL: 601 result = GL_BOOL; 602 break; 603 case VARIABLE_TYPE_DOUBLE: 604 result = GL_DOUBLE; 605 break; 606 case VARIABLE_TYPE_FLOAT: 607 result = GL_FLOAT; 608 break; 609 case VARIABLE_TYPE_INT: 610 result = GL_INT; 611 break; 612 case VARIABLE_TYPE_UINT: 613 result = GL_UNSIGNED_INT; 614 break; 615 616 default: 617 { 618 TCU_FAIL("Unrecognized variable type"); 619 } 620 } 621 622 return result; 623 } 624 625 /** Return GLenum representing given <type> 626 * 627 * @param type Type of variable 628 * 629 * @return GL enumeration 630 **/ 631 glw::GLenum Utils::getGLDataTypeOfVariableType(_variable_type type) 632 { 633 glw::GLenum result = GL_NONE; 634 635 switch (type) 636 { 637 case VARIABLE_TYPE_BOOL: 638 result = GL_BOOL; 639 break; 640 case VARIABLE_TYPE_DOUBLE: 641 result = GL_DOUBLE; 642 break; 643 case VARIABLE_TYPE_DMAT2: 644 result = GL_DOUBLE_MAT2; 645 break; 646 case VARIABLE_TYPE_DMAT2X3: 647 result = GL_DOUBLE_MAT2x3; 648 break; 649 case VARIABLE_TYPE_DMAT2X4: 650 result = GL_DOUBLE_MAT2x4; 651 break; 652 case VARIABLE_TYPE_DMAT3: 653 result = GL_DOUBLE_MAT3; 654 break; 655 case VARIABLE_TYPE_DMAT3X2: 656 result = GL_DOUBLE_MAT3x2; 657 break; 658 case VARIABLE_TYPE_DMAT3X4: 659 result = GL_DOUBLE_MAT3x4; 660 break; 661 case VARIABLE_TYPE_DMAT4: 662 result = GL_DOUBLE_MAT4; 663 break; 664 case VARIABLE_TYPE_DMAT4X2: 665 result = GL_DOUBLE_MAT4x2; 666 break; 667 case VARIABLE_TYPE_DMAT4X3: 668 result = GL_DOUBLE_MAT4x3; 669 break; 670 case VARIABLE_TYPE_DVEC2: 671 result = GL_DOUBLE_VEC2; 672 break; 673 case VARIABLE_TYPE_DVEC3: 674 result = GL_DOUBLE_VEC3; 675 break; 676 case VARIABLE_TYPE_DVEC4: 677 result = GL_DOUBLE_VEC4; 678 break; 679 case VARIABLE_TYPE_FLOAT: 680 result = GL_FLOAT; 681 break; 682 case VARIABLE_TYPE_INT: 683 result = GL_INT; 684 break; 685 case VARIABLE_TYPE_IVEC2: 686 result = GL_INT_VEC2; 687 break; 688 case VARIABLE_TYPE_IVEC3: 689 result = GL_INT_VEC3; 690 break; 691 case VARIABLE_TYPE_IVEC4: 692 result = GL_INT_VEC4; 693 break; 694 case VARIABLE_TYPE_MAT2: 695 result = GL_FLOAT_MAT2; 696 break; 697 case VARIABLE_TYPE_MAT2X3: 698 result = GL_FLOAT_MAT2x3; 699 break; 700 case VARIABLE_TYPE_MAT2X4: 701 result = GL_FLOAT_MAT2x4; 702 break; 703 case VARIABLE_TYPE_MAT3: 704 result = GL_FLOAT_MAT3; 705 break; 706 case VARIABLE_TYPE_MAT3X2: 707 result = GL_FLOAT_MAT3x2; 708 break; 709 case VARIABLE_TYPE_MAT3X4: 710 result = GL_FLOAT_MAT3x4; 711 break; 712 case VARIABLE_TYPE_MAT4: 713 result = GL_FLOAT_MAT4; 714 break; 715 case VARIABLE_TYPE_MAT4X2: 716 result = GL_FLOAT_MAT4x2; 717 break; 718 case VARIABLE_TYPE_MAT4X3: 719 result = GL_FLOAT_MAT4x3; 720 break; 721 case VARIABLE_TYPE_UINT: 722 result = GL_UNSIGNED_INT; 723 break; 724 case VARIABLE_TYPE_UVEC2: 725 result = GL_UNSIGNED_INT_VEC2; 726 break; 727 case VARIABLE_TYPE_UVEC3: 728 result = GL_UNSIGNED_INT_VEC3; 729 break; 730 case VARIABLE_TYPE_UVEC4: 731 result = GL_UNSIGNED_INT_VEC4; 732 break; 733 case VARIABLE_TYPE_VEC2: 734 result = GL_FLOAT_VEC2; 735 break; 736 case VARIABLE_TYPE_VEC3: 737 result = GL_FLOAT_VEC3; 738 break; 739 case VARIABLE_TYPE_VEC4: 740 result = GL_FLOAT_VEC4; 741 break; 742 743 default: 744 { 745 TCU_FAIL("Unrecognized variable type"); 746 } 747 } 748 749 return result; 750 } 751 752 /** Get _variable_type representing integer type with given dimmensions 753 * 754 * @param n_columns Number of columns 755 * @param n_row Number of rows 756 * 757 * @return Corresponding _variable_type 758 **/ 759 Utils::_variable_type Utils::getIntVariableType(glw::GLuint n_columns, glw::GLuint n_rows) 760 { 761 Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN; 762 763 static const _variable_type types[4] = { VARIABLE_TYPE_INT, VARIABLE_TYPE_IVEC2, VARIABLE_TYPE_IVEC3, 764 VARIABLE_TYPE_IVEC4 }; 765 766 if (1 != n_columns) 767 { 768 TCU_FAIL("Not implemented"); 769 } 770 else 771 { 772 type = types[n_rows - 1]; 773 } 774 775 return type; 776 } 777 778 /** Returns te number of components that variables defined with user-specified type 779 * support. For matrix types, total amount of values accessible for the type will be 780 * returned. 781 * 782 * @param type Variable type to return the described vale for. 783 * 784 * @return As per description or 0 if @param type was not recognized. 785 */ 786 unsigned int Utils::getNumberOfComponentsForVariableType(_variable_type type) 787 { 788 unsigned int result = 0; 789 790 switch (type) 791 { 792 case VARIABLE_TYPE_BOOL: 793 case VARIABLE_TYPE_DOUBLE: 794 case VARIABLE_TYPE_FLOAT: 795 case VARIABLE_TYPE_INT: 796 case VARIABLE_TYPE_UINT: 797 { 798 result = 1; 799 800 break; 801 } 802 803 case VARIABLE_TYPE_DVEC2: 804 case VARIABLE_TYPE_IVEC2: 805 case VARIABLE_TYPE_UVEC2: 806 case VARIABLE_TYPE_VEC2: 807 { 808 result = 2; 809 810 break; 811 } 812 813 case VARIABLE_TYPE_DVEC3: 814 case VARIABLE_TYPE_IVEC3: 815 case VARIABLE_TYPE_UVEC3: 816 case VARIABLE_TYPE_VEC3: 817 { 818 result = 3; 819 820 break; 821 } 822 823 case VARIABLE_TYPE_DVEC4: 824 case VARIABLE_TYPE_IVEC4: 825 case VARIABLE_TYPE_UVEC4: 826 case VARIABLE_TYPE_VEC4: 827 { 828 result = 4; 829 830 break; 831 } 832 833 case VARIABLE_TYPE_DMAT2: 834 case VARIABLE_TYPE_MAT2: 835 { 836 result = 2 * 2; 837 838 break; 839 } 840 841 case VARIABLE_TYPE_DMAT2X3: 842 case VARIABLE_TYPE_DMAT3X2: 843 case VARIABLE_TYPE_MAT2X3: 844 case VARIABLE_TYPE_MAT3X2: 845 { 846 result = 2 * 3; 847 848 break; 849 } 850 851 case VARIABLE_TYPE_DMAT2X4: 852 case VARIABLE_TYPE_DMAT4X2: 853 case VARIABLE_TYPE_MAT2X4: 854 case VARIABLE_TYPE_MAT4X2: 855 { 856 result = 2 * 4; 857 858 break; 859 } 860 861 case VARIABLE_TYPE_DMAT3: 862 case VARIABLE_TYPE_MAT3: 863 { 864 result = 3 * 3; 865 866 break; 867 } 868 869 case VARIABLE_TYPE_DMAT3X4: 870 case VARIABLE_TYPE_DMAT4X3: 871 case VARIABLE_TYPE_MAT3X4: 872 case VARIABLE_TYPE_MAT4X3: 873 { 874 result = 3 * 4; 875 876 break; 877 } 878 879 case VARIABLE_TYPE_DMAT4: 880 case VARIABLE_TYPE_MAT4: 881 { 882 result = 4 * 4; 883 884 break; 885 } 886 887 default: 888 { 889 TCU_FAIL("Unrecognized type"); 890 } 891 } /* switch (type) */ 892 893 return result; 894 } 895 896 /** Returns number of columns user-specified matrix variable type describes. 897 * 898 * @param type Variable type to use for the query. Only VARIABLE_TYPE_DMAT* 899 * values are valid. 900 * 901 * @return As per description. 902 **/ 903 unsigned int Utils::getNumberOfColumnsForVariableType(_variable_type type) 904 { 905 unsigned int result = 0; 906 907 switch (type) 908 { 909 case VARIABLE_TYPE_BOOL: 910 case VARIABLE_TYPE_DOUBLE: 911 case VARIABLE_TYPE_FLOAT: 912 case VARIABLE_TYPE_INT: 913 case VARIABLE_TYPE_UINT: 914 case VARIABLE_TYPE_DVEC2: 915 case VARIABLE_TYPE_IVEC2: 916 case VARIABLE_TYPE_UVEC2: 917 case VARIABLE_TYPE_VEC2: 918 case VARIABLE_TYPE_DVEC3: 919 case VARIABLE_TYPE_IVEC3: 920 case VARIABLE_TYPE_UVEC3: 921 case VARIABLE_TYPE_VEC3: 922 case VARIABLE_TYPE_DVEC4: 923 case VARIABLE_TYPE_IVEC4: 924 case VARIABLE_TYPE_UVEC4: 925 case VARIABLE_TYPE_VEC4: 926 { 927 result = 1; 928 929 break; 930 } 931 932 case VARIABLE_TYPE_DMAT2: 933 case VARIABLE_TYPE_DMAT2X3: 934 case VARIABLE_TYPE_DMAT2X4: 935 case VARIABLE_TYPE_MAT2: 936 case VARIABLE_TYPE_MAT2X3: 937 case VARIABLE_TYPE_MAT2X4: 938 { 939 result = 2; 940 941 break; 942 } 943 944 case VARIABLE_TYPE_DMAT3: 945 case VARIABLE_TYPE_DMAT3X2: 946 case VARIABLE_TYPE_DMAT3X4: 947 case VARIABLE_TYPE_MAT3: 948 case VARIABLE_TYPE_MAT3X2: 949 case VARIABLE_TYPE_MAT3X4: 950 { 951 result = 3; 952 953 break; 954 } 955 956 case VARIABLE_TYPE_DMAT4: 957 case VARIABLE_TYPE_DMAT4X2: 958 case VARIABLE_TYPE_DMAT4X3: 959 case VARIABLE_TYPE_MAT4: 960 case VARIABLE_TYPE_MAT4X2: 961 case VARIABLE_TYPE_MAT4X3: 962 { 963 result = 4; 964 965 break; 966 } 967 968 default: 969 { 970 TCU_FAIL("Unrecognized type"); 971 } 972 } /* switch (type) */ 973 974 return result; 975 } 976 977 /** Returns maximum number of uniform locations taken by user-specified double-precision 978 * variable type. 979 * 980 * @param type Variable type to use for the query. Only VARIABLE_TYPE_D* values are valid. 981 * 982 * @return As per description. 983 **/ 984 unsigned int Utils::getNumberOfLocationsUsedByDoublePrecisionVariableType(_variable_type type) 985 { 986 unsigned int result = 0; 987 988 switch (type) 989 { 990 case VARIABLE_TYPE_DOUBLE: 991 result = 1; 992 break; 993 case VARIABLE_TYPE_DVEC2: 994 result = 1; 995 break; 996 case VARIABLE_TYPE_DVEC3: 997 result = 2; 998 break; 999 case VARIABLE_TYPE_DVEC4: 1000 result = 2; 1001 break; 1002 case VARIABLE_TYPE_DMAT2: 1003 result = 2; 1004 break; 1005 case VARIABLE_TYPE_DMAT2X3: 1006 result = 6; 1007 break; 1008 case VARIABLE_TYPE_DMAT2X4: 1009 result = 8; 1010 break; 1011 case VARIABLE_TYPE_DMAT3: 1012 result = 6; 1013 break; 1014 case VARIABLE_TYPE_DMAT3X2: 1015 result = 4; 1016 break; 1017 case VARIABLE_TYPE_DMAT3X4: 1018 result = 8; 1019 break; 1020 case VARIABLE_TYPE_DMAT4: 1021 result = 8; 1022 break; 1023 case VARIABLE_TYPE_DMAT4X2: 1024 result = 4; 1025 break; 1026 case VARIABLE_TYPE_DMAT4X3: 1027 result = 6; 1028 break; 1029 1030 default: 1031 { 1032 TCU_FAIL("Unrecognized type"); 1033 } 1034 } /* switch (type) */ 1035 1036 return result; 1037 } 1038 1039 /** Get number of rows for given variable type 1040 * 1041 * @param type Type of variable 1042 * 1043 * @return Number of rows 1044 **/ 1045 unsigned int Utils::getNumberOfRowsForVariableType(_variable_type type) 1046 { 1047 unsigned int result = 0; 1048 1049 switch (type) 1050 { 1051 case VARIABLE_TYPE_BOOL: 1052 case VARIABLE_TYPE_DOUBLE: 1053 case VARIABLE_TYPE_FLOAT: 1054 case VARIABLE_TYPE_INT: 1055 case VARIABLE_TYPE_UINT: 1056 { 1057 result = 1; 1058 1059 break; 1060 } 1061 1062 case VARIABLE_TYPE_DVEC2: 1063 case VARIABLE_TYPE_IVEC2: 1064 case VARIABLE_TYPE_UVEC2: 1065 case VARIABLE_TYPE_VEC2: 1066 case VARIABLE_TYPE_DMAT2: 1067 case VARIABLE_TYPE_DMAT3X2: 1068 case VARIABLE_TYPE_DMAT4X2: 1069 case VARIABLE_TYPE_MAT2: 1070 case VARIABLE_TYPE_MAT3X2: 1071 case VARIABLE_TYPE_MAT4X2: 1072 { 1073 result = 2; 1074 1075 break; 1076 } 1077 1078 case VARIABLE_TYPE_DVEC3: 1079 case VARIABLE_TYPE_IVEC3: 1080 case VARIABLE_TYPE_UVEC3: 1081 case VARIABLE_TYPE_VEC3: 1082 case VARIABLE_TYPE_DMAT2X3: 1083 case VARIABLE_TYPE_DMAT3: 1084 case VARIABLE_TYPE_DMAT4X3: 1085 case VARIABLE_TYPE_MAT2X3: 1086 case VARIABLE_TYPE_MAT3: 1087 case VARIABLE_TYPE_MAT4X3: 1088 { 1089 result = 3; 1090 1091 break; 1092 } 1093 1094 case VARIABLE_TYPE_DVEC4: 1095 case VARIABLE_TYPE_IVEC4: 1096 case VARIABLE_TYPE_UVEC4: 1097 case VARIABLE_TYPE_VEC4: 1098 case VARIABLE_TYPE_DMAT2X4: 1099 case VARIABLE_TYPE_DMAT3X4: 1100 case VARIABLE_TYPE_DMAT4: 1101 case VARIABLE_TYPE_MAT2X4: 1102 case VARIABLE_TYPE_MAT3X4: 1103 case VARIABLE_TYPE_MAT4: 1104 { 1105 result = 4; 1106 1107 break; 1108 } 1109 1110 default: 1111 { 1112 TCU_FAIL("Unrecognized type"); 1113 } 1114 } /* switch (type) */ 1115 1116 return result; 1117 } 1118 1119 /** Returns variable type of a matrix constructed by multiplying two matrices. 1120 * 1121 * @param type_matrix_a L-side matrix type. 1122 * @param type_matrix_b R-side matrix type. 1123 * 1124 * @return As per description. 1125 **/ 1126 Utils::_variable_type Utils::getPostMatrixMultiplicationVariableType(_variable_type type_matrix_a, 1127 _variable_type type_matrix_b) 1128 { 1129 const unsigned int n_a_columns = Utils::getNumberOfColumnsForVariableType(type_matrix_a); 1130 const unsigned int n_a_components = Utils::getNumberOfComponentsForVariableType(type_matrix_a); 1131 const unsigned int n_a_rows = n_a_components / n_a_columns; 1132 const unsigned int n_b_columns = Utils::getNumberOfColumnsForVariableType(type_matrix_b); 1133 const unsigned int n_result_columns = n_b_columns; 1134 const unsigned int n_result_rows = n_a_rows; 1135 Utils::_variable_type result; 1136 1137 switch (n_result_columns) 1138 { 1139 case 2: 1140 { 1141 switch (n_result_rows) 1142 { 1143 case 2: 1144 result = VARIABLE_TYPE_DMAT2; 1145 break; 1146 case 3: 1147 result = VARIABLE_TYPE_DMAT2X3; 1148 break; 1149 case 4: 1150 result = VARIABLE_TYPE_DMAT2X4; 1151 break; 1152 1153 default: 1154 { 1155 TCU_FAIL("Unrecognized amount of rows in result variable"); 1156 } 1157 } /* switch (n_result_rows) */ 1158 1159 break; 1160 } /* case 2: */ 1161 1162 case 3: 1163 { 1164 switch (n_result_rows) 1165 { 1166 case 2: 1167 result = VARIABLE_TYPE_DMAT3X2; 1168 break; 1169 case 3: 1170 result = VARIABLE_TYPE_DMAT3; 1171 break; 1172 case 4: 1173 result = VARIABLE_TYPE_DMAT3X4; 1174 break; 1175 1176 default: 1177 { 1178 TCU_FAIL("Unrecognized amount of rows in result variable"); 1179 } 1180 } /* switch (n_result_rows) */ 1181 1182 break; 1183 } /* case 3: */ 1184 1185 case 4: 1186 { 1187 switch (n_result_rows) 1188 { 1189 case 2: 1190 result = VARIABLE_TYPE_DMAT4X2; 1191 break; 1192 case 3: 1193 result = VARIABLE_TYPE_DMAT4X3; 1194 break; 1195 case 4: 1196 result = VARIABLE_TYPE_DMAT4; 1197 break; 1198 1199 default: 1200 { 1201 TCU_FAIL("Unrecognized amount of rows in result variable"); 1202 } 1203 } /* switch (n_result_rows) */ 1204 1205 break; 1206 } /* case 4: */ 1207 1208 default: 1209 { 1210 TCU_FAIL("Unrecognized amount of columns in result variable"); 1211 } 1212 } /* switch (n_result_columns) */ 1213 1214 /* Done */ 1215 return result; 1216 } 1217 1218 /** Returns a string holding the value represented by user-provided variable, for which 1219 * the data are represented in @param type variable type. 1220 * 1221 * @return As per description. 1222 **/ 1223 std::string Utils::getStringForVariableTypeValue(_variable_type type, const unsigned char* data_ptr) 1224 { 1225 std::stringstream result_sstream; 1226 1227 switch (type) 1228 { 1229 case VARIABLE_TYPE_BOOL: 1230 result_sstream << *((bool*)data_ptr); 1231 break; 1232 case VARIABLE_TYPE_DOUBLE: 1233 result_sstream << *((double*)data_ptr); 1234 break; 1235 case VARIABLE_TYPE_FLOAT: 1236 result_sstream << *((float*)data_ptr); 1237 break; 1238 case VARIABLE_TYPE_INT: 1239 result_sstream << *((int*)data_ptr); 1240 break; 1241 case VARIABLE_TYPE_UINT: 1242 result_sstream << *((unsigned int*)data_ptr); 1243 break; 1244 1245 default: 1246 { 1247 TCU_FAIL("Unrecognized variable type requested"); 1248 } 1249 } /* switch (type) */ 1250 1251 return result_sstream.str(); 1252 } 1253 1254 /** Returns variable type of a transposed matrix of user-specified variable type. 1255 * 1256 * @param type Variable type of the matrix to be transposed. 1257 * 1258 * @return Transposed matrix variable type. 1259 **/ 1260 Utils::_variable_type Utils::getTransposedMatrixVariableType(Utils::_variable_type type) 1261 { 1262 Utils::_variable_type result; 1263 1264 switch (type) 1265 { 1266 case VARIABLE_TYPE_DMAT2: 1267 result = VARIABLE_TYPE_DMAT2; 1268 break; 1269 case VARIABLE_TYPE_DMAT2X3: 1270 result = VARIABLE_TYPE_DMAT3X2; 1271 break; 1272 case VARIABLE_TYPE_DMAT2X4: 1273 result = VARIABLE_TYPE_DMAT4X2; 1274 break; 1275 case VARIABLE_TYPE_DMAT3: 1276 result = VARIABLE_TYPE_DMAT3; 1277 break; 1278 case VARIABLE_TYPE_DMAT3X2: 1279 result = VARIABLE_TYPE_DMAT2X3; 1280 break; 1281 case VARIABLE_TYPE_DMAT3X4: 1282 result = VARIABLE_TYPE_DMAT4X3; 1283 break; 1284 case VARIABLE_TYPE_DMAT4: 1285 result = VARIABLE_TYPE_DMAT4; 1286 break; 1287 case VARIABLE_TYPE_DMAT4X2: 1288 result = VARIABLE_TYPE_DMAT2X4; 1289 break; 1290 case VARIABLE_TYPE_DMAT4X3: 1291 result = VARIABLE_TYPE_DMAT3X4; 1292 break; 1293 1294 default: 1295 { 1296 TCU_FAIL("Unrecognized double-precision matrix variable type."); 1297 } 1298 } /* switch (type) */ 1299 1300 return result; 1301 } 1302 1303 /** Get _variable_type representing unsigned integer type with given dimmensions 1304 * 1305 * @param n_columns Number of columns 1306 * @param n_row Number of rows 1307 * 1308 * @return Corresponding _variable_type 1309 **/ 1310 Utils::_variable_type Utils::getUintVariableType(glw::GLuint n_columns, glw::GLuint n_rows) 1311 { 1312 Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN; 1313 1314 static const _variable_type types[4] = { VARIABLE_TYPE_UINT, VARIABLE_TYPE_UVEC2, VARIABLE_TYPE_UVEC3, 1315 VARIABLE_TYPE_UVEC4 }; 1316 1317 if (1 != n_columns) 1318 { 1319 TCU_FAIL("Not implemented"); 1320 } 1321 else 1322 { 1323 type = types[n_rows - 1]; 1324 } 1325 1326 return type; 1327 } 1328 1329 /** Returns a literal corresponding to a GLSL keyword describing user-specified 1330 * variable type. 1331 * 1332 * @param type Variable type to use for the query. 1333 * 1334 * @return Requested GLSL keyword or [?] if @param type was not recognized. 1335 **/ 1336 std::string Utils::getVariableTypeString(_variable_type type) 1337 { 1338 std::string result = "[?]"; 1339 1340 switch (type) 1341 { 1342 case VARIABLE_TYPE_BOOL: 1343 result = "bool"; 1344 break; 1345 case VARIABLE_TYPE_BVEC2: 1346 result = "bvec2"; 1347 break; 1348 case VARIABLE_TYPE_BVEC3: 1349 result = "bvec3"; 1350 break; 1351 case VARIABLE_TYPE_BVEC4: 1352 result = "bvec4"; 1353 break; 1354 case VARIABLE_TYPE_DOUBLE: 1355 result = "double"; 1356 break; 1357 case VARIABLE_TYPE_DMAT2: 1358 result = "dmat2"; 1359 break; 1360 case VARIABLE_TYPE_DMAT2X3: 1361 result = "dmat2x3"; 1362 break; 1363 case VARIABLE_TYPE_DMAT2X4: 1364 result = "dmat2x4"; 1365 break; 1366 case VARIABLE_TYPE_DMAT3: 1367 result = "dmat3"; 1368 break; 1369 case VARIABLE_TYPE_DMAT3X2: 1370 result = "dmat3x2"; 1371 break; 1372 case VARIABLE_TYPE_DMAT3X4: 1373 result = "dmat3x4"; 1374 break; 1375 case VARIABLE_TYPE_DMAT4: 1376 result = "dmat4"; 1377 break; 1378 case VARIABLE_TYPE_DMAT4X2: 1379 result = "dmat4x2"; 1380 break; 1381 case VARIABLE_TYPE_DMAT4X3: 1382 result = "dmat4x3"; 1383 break; 1384 case VARIABLE_TYPE_DVEC2: 1385 result = "dvec2"; 1386 break; 1387 case VARIABLE_TYPE_DVEC3: 1388 result = "dvec3"; 1389 break; 1390 case VARIABLE_TYPE_DVEC4: 1391 result = "dvec4"; 1392 break; 1393 case VARIABLE_TYPE_FLOAT: 1394 result = "float"; 1395 break; 1396 case VARIABLE_TYPE_INT: 1397 result = "int"; 1398 break; 1399 case VARIABLE_TYPE_IVEC2: 1400 result = "ivec2"; 1401 break; 1402 case VARIABLE_TYPE_IVEC3: 1403 result = "ivec3"; 1404 break; 1405 case VARIABLE_TYPE_IVEC4: 1406 result = "ivec4"; 1407 break; 1408 case VARIABLE_TYPE_MAT2: 1409 result = "mat2"; 1410 break; 1411 case VARIABLE_TYPE_MAT2X3: 1412 result = "mat2x3"; 1413 break; 1414 case VARIABLE_TYPE_MAT2X4: 1415 result = "mat2x4"; 1416 break; 1417 case VARIABLE_TYPE_MAT3: 1418 result = "mat3"; 1419 break; 1420 case VARIABLE_TYPE_MAT3X2: 1421 result = "mat3x2"; 1422 break; 1423 case VARIABLE_TYPE_MAT3X4: 1424 result = "mat3x4"; 1425 break; 1426 case VARIABLE_TYPE_MAT4: 1427 result = "mat4"; 1428 break; 1429 case VARIABLE_TYPE_MAT4X2: 1430 result = "mat4x2"; 1431 break; 1432 case VARIABLE_TYPE_MAT4X3: 1433 result = "mat4x3"; 1434 break; 1435 case VARIABLE_TYPE_UINT: 1436 result = "uint"; 1437 break; 1438 case VARIABLE_TYPE_UVEC2: 1439 result = "uvec2"; 1440 break; 1441 case VARIABLE_TYPE_UVEC3: 1442 result = "uvec3"; 1443 break; 1444 case VARIABLE_TYPE_UVEC4: 1445 result = "uvec4"; 1446 break; 1447 case VARIABLE_TYPE_VEC2: 1448 result = "vec2"; 1449 break; 1450 case VARIABLE_TYPE_VEC3: 1451 result = "vec3"; 1452 break; 1453 case VARIABLE_TYPE_VEC4: 1454 result = "vec4"; 1455 break; 1456 1457 default: 1458 { 1459 TCU_FAIL("Unrecognized variable type"); 1460 } 1461 }; /* switch (type) */ 1462 1463 return result; 1464 } 1465 1466 /** Check if GL context meets version requirements 1467 * 1468 * @param gl Functions 1469 * @param required_major Minimum required MAJOR_VERSION 1470 * @param required_minor Minimum required MINOR_VERSION 1471 * 1472 * @return true if GL context version is at least as requested, false otherwise 1473 **/ 1474 bool Utils::isGLVersionAtLeast(const glw::Functions& gl, glw::GLint required_major, glw::GLint required_minor) 1475 { 1476 glw::GLint major = 0; 1477 glw::GLint minor = 0; 1478 1479 gl.getIntegerv(GL_MAJOR_VERSION, &major); 1480 gl.getIntegerv(GL_MINOR_VERSION, &minor); 1481 1482 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 1483 1484 if (major > required_major) 1485 { 1486 /* Major is higher than required one */ 1487 return true; 1488 } 1489 else if (major == required_major) 1490 { 1491 if (minor >= required_minor) 1492 { 1493 /* Major is equal to required one */ 1494 /* Minor is higher than or equal to required one */ 1495 return true; 1496 } 1497 else 1498 { 1499 /* Major is equal to required one */ 1500 /* Minor is lower than required one */ 1501 return false; 1502 } 1503 } 1504 else 1505 { 1506 /* Major is lower than required one */ 1507 return false; 1508 } 1509 } 1510 1511 /** Tells whether user-specified variable type corresponds to a matrix type. 1512 * 1513 * @param type Variable type to use for the query. 1514 * 1515 * @return true if the variable type describes a matrix, false otherwise. 1516 **/ 1517 bool Utils::isMatrixVariableType(_variable_type type) 1518 { 1519 return (type == VARIABLE_TYPE_MAT2 || type == VARIABLE_TYPE_MAT3 || type == VARIABLE_TYPE_MAT4 || 1520 type == VARIABLE_TYPE_MAT2X3 || type == VARIABLE_TYPE_MAT2X4 || type == VARIABLE_TYPE_MAT3X2 || 1521 type == VARIABLE_TYPE_MAT3X4 || type == VARIABLE_TYPE_MAT4X2 || type == VARIABLE_TYPE_MAT4X3 || 1522 type == VARIABLE_TYPE_DMAT2 || type == VARIABLE_TYPE_DMAT3 || type == VARIABLE_TYPE_DMAT4 || 1523 type == VARIABLE_TYPE_DMAT2X3 || type == VARIABLE_TYPE_DMAT2X4 || type == VARIABLE_TYPE_DMAT3X2 || 1524 type == VARIABLE_TYPE_DMAT3X4 || type == VARIABLE_TYPE_DMAT4X2 || type == VARIABLE_TYPE_DMAT4X3); 1525 } 1526 1527 /** Tells whether user-specified variable type is scalar. 1528 * 1529 * @return true if @param type is a scalar variable type, false otherwise. 1530 **/ 1531 bool Utils::isScalarVariableType(_variable_type type) 1532 { 1533 bool result = false; 1534 1535 switch (type) 1536 { 1537 case VARIABLE_TYPE_BOOL: 1538 result = true; 1539 break; 1540 case VARIABLE_TYPE_DOUBLE: 1541 result = true; 1542 break; 1543 case VARIABLE_TYPE_FLOAT: 1544 result = true; 1545 break; 1546 case VARIABLE_TYPE_INT: 1547 result = true; 1548 break; 1549 case VARIABLE_TYPE_UINT: 1550 result = true; 1551 break; 1552 default: 1553 break; 1554 }; /* switch (type) */ 1555 1556 return result; 1557 } 1558 1559 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion> 1560 * 1561 * @param token Token string 1562 * @param search_position Position at which find will start, it is updated to position at which replaced text ends 1563 * @param text String that will be used as replacement for <token> 1564 * @param string String to work on 1565 **/ 1566 void Utils::replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text, 1567 std::string& string) 1568 { 1569 const size_t text_length = strlen(text); 1570 const size_t token_length = strlen(token); 1571 const size_t token_position = string.find(token, search_position); 1572 1573 string.replace(token_position, token_length, text, text_length); 1574 1575 search_position = token_position + text_length; 1576 } 1577 1578 /** Constructor. 1579 * 1580 * @param context Rendering context. 1581 * 1582 **/ 1583 GPUShaderFP64Test1::GPUShaderFP64Test1(deqp::Context& context) 1584 : TestCase(context, "errors", "Verifies that various erroneous conditions related to double-precision " 1585 "float uniform support & glUniform*() / glUniformMatrix*() API " 1586 " are reported correctly.") 1587 , m_has_test_passed(true) 1588 , m_po_bool_arr_uniform_location(0) 1589 , m_po_bool_uniform_location(0) 1590 , m_po_bvec2_arr_uniform_location(0) 1591 , m_po_bvec2_uniform_location(0) 1592 , m_po_bvec3_arr_uniform_location(0) 1593 , m_po_bvec3_uniform_location(0) 1594 , m_po_bvec4_arr_uniform_location(0) 1595 , m_po_bvec4_uniform_location(0) 1596 , m_po_dmat2_arr_uniform_location(0) 1597 , m_po_dmat2_uniform_location(0) 1598 , m_po_dmat2x3_arr_uniform_location(0) 1599 , m_po_dmat2x3_uniform_location(0) 1600 , m_po_dmat2x4_arr_uniform_location(0) 1601 , m_po_dmat2x4_uniform_location(0) 1602 , m_po_dmat3_arr_uniform_location(0) 1603 , m_po_dmat3_uniform_location(0) 1604 , m_po_dmat3x2_arr_uniform_location(0) 1605 , m_po_dmat3x2_uniform_location(0) 1606 , m_po_dmat3x4_arr_uniform_location(0) 1607 , m_po_dmat3x4_uniform_location(0) 1608 , m_po_dmat4_arr_uniform_location(0) 1609 , m_po_dmat4_uniform_location(0) 1610 , m_po_dmat4x2_arr_uniform_location(0) 1611 , m_po_dmat4x2_uniform_location(0) 1612 , m_po_dmat4x3_arr_uniform_location(0) 1613 , m_po_dmat4x3_uniform_location(0) 1614 , m_po_double_arr_uniform_location(0) 1615 , m_po_double_uniform_location(0) 1616 , m_po_dvec2_arr_uniform_location(0) 1617 , m_po_dvec2_uniform_location(0) 1618 , m_po_dvec3_arr_uniform_location(0) 1619 , m_po_dvec3_uniform_location(0) 1620 , m_po_dvec4_arr_uniform_location(0) 1621 , m_po_dvec4_uniform_location(0) 1622 , m_po_float_arr_uniform_location(0) 1623 , m_po_float_uniform_location(0) 1624 , m_po_int_arr_uniform_location(0) 1625 , m_po_int_uniform_location(0) 1626 , m_po_ivec2_arr_uniform_location(0) 1627 , m_po_ivec2_uniform_location(0) 1628 , m_po_ivec3_arr_uniform_location(0) 1629 , m_po_ivec3_uniform_location(0) 1630 , m_po_ivec4_arr_uniform_location(0) 1631 , m_po_ivec4_uniform_location(0) 1632 , m_po_sampler_uniform_location(0) 1633 , m_po_uint_arr_uniform_location(0) 1634 , m_po_uint_uniform_location(0) 1635 , m_po_uvec2_arr_uniform_location(0) 1636 , m_po_uvec2_uniform_location(0) 1637 , m_po_uvec3_arr_uniform_location(0) 1638 , m_po_uvec3_uniform_location(0) 1639 , m_po_uvec4_arr_uniform_location(0) 1640 , m_po_uvec4_uniform_location(0) 1641 , m_po_vec2_arr_uniform_location(0) 1642 , m_po_vec2_uniform_location(0) 1643 , m_po_vec3_arr_uniform_location(0) 1644 , m_po_vec3_uniform_location(0) 1645 , m_po_vec4_arr_uniform_location(0) 1646 , m_po_vec4_uniform_location(0) 1647 , m_po_id(0) 1648 , m_vs_id(0) 1649 { 1650 /* Left blank intentionally */ 1651 } 1652 1653 /** Deinitializes all GL objects that may have been created during 1654 * test execution. 1655 **/ 1656 void GPUShaderFP64Test1::deinit() 1657 { 1658 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1659 1660 if (m_po_id != 0) 1661 { 1662 gl.deleteProgram(m_po_id); 1663 1664 m_po_id = 0; 1665 } 1666 1667 if (m_vs_id != 0) 1668 { 1669 gl.deleteShader(m_vs_id); 1670 1671 m_vs_id = 0; 1672 } 1673 } 1674 1675 /** Returns a string describing GL API function represented by user-provided enum. 1676 * 1677 * @param func Uniform function to return the string for. 1678 * 1679 * @return As per description. [?] will be returned if the function was not recognized. 1680 **/ 1681 const char* GPUShaderFP64Test1::getUniformFunctionString(_uniform_function func) 1682 { 1683 const char* result = "[?]"; 1684 1685 switch (func) 1686 { 1687 case UNIFORM_FUNCTION_1D: 1688 result = "glUniform1d"; 1689 break; 1690 case UNIFORM_FUNCTION_1DV: 1691 result = "glUniform1dv"; 1692 break; 1693 case UNIFORM_FUNCTION_2D: 1694 result = "glUniform2d"; 1695 break; 1696 case UNIFORM_FUNCTION_2DV: 1697 result = "glUniform2dv"; 1698 break; 1699 case UNIFORM_FUNCTION_3D: 1700 result = "glUniform3d"; 1701 break; 1702 case UNIFORM_FUNCTION_3DV: 1703 result = "glUniform3dv"; 1704 break; 1705 case UNIFORM_FUNCTION_4D: 1706 result = "glUniform4d"; 1707 break; 1708 case UNIFORM_FUNCTION_4DV: 1709 result = "glUniform4dv"; 1710 break; 1711 case UNIFORM_FUNCTION_MATRIX2DV: 1712 result = "glUniformMatrix2dv"; 1713 break; 1714 case UNIFORM_FUNCTION_MATRIX2X3DV: 1715 result = "glUniformMatrix2x3dv"; 1716 break; 1717 case UNIFORM_FUNCTION_MATRIX2X4DV: 1718 result = "glUniformMatrix2x4dv"; 1719 break; 1720 case UNIFORM_FUNCTION_MATRIX3DV: 1721 result = "glUniformMatrix3dv"; 1722 break; 1723 case UNIFORM_FUNCTION_MATRIX3X2DV: 1724 result = "glUniformMatrix3x2dv"; 1725 break; 1726 case UNIFORM_FUNCTION_MATRIX3X4DV: 1727 result = "glUniformMatrix3x4dv"; 1728 break; 1729 case UNIFORM_FUNCTION_MATRIX4DV: 1730 result = "glUniformMatrix4dv"; 1731 break; 1732 case UNIFORM_FUNCTION_MATRIX4X2DV: 1733 result = "glUniformMatrix4x2dv"; 1734 break; 1735 case UNIFORM_FUNCTION_MATRIX4X3DV: 1736 result = "glUniformMatrix4x3dv"; 1737 break; 1738 default: 1739 break; 1740 } 1741 1742 return result; 1743 } 1744 1745 /** Returns name of an uniform bound to user-provided location. 1746 * 1747 * @param location Location of the uniform to return the name for. 1748 * 1749 * @return As per description. [?] will be returned if the location was not 1750 * recognized. 1751 **/ 1752 const char* GPUShaderFP64Test1::getUniformNameForLocation(glw::GLint location) 1753 { 1754 const char* result = "[?]"; 1755 1756 if (location == m_po_bool_arr_uniform_location) 1757 result = "uniform_bool_arr"; 1758 else if (location == m_po_bool_uniform_location) 1759 result = "uniform_bool"; 1760 else if (location == m_po_bvec2_arr_uniform_location) 1761 result = "uniform_bvec2_arr"; 1762 else if (location == m_po_bvec2_uniform_location) 1763 result = "uniform_bvec2"; 1764 else if (location == m_po_bvec3_arr_uniform_location) 1765 result = "uniform_bvec3_arr"; 1766 else if (location == m_po_bvec3_uniform_location) 1767 result = "uniform_bvec3"; 1768 else if (location == m_po_bvec4_arr_uniform_location) 1769 result = "uniform_bvec4_arr"; 1770 else if (location == m_po_bvec4_uniform_location) 1771 result = "uniform_bvec4"; 1772 else if (location == m_po_dmat2_arr_uniform_location) 1773 result = "uniform_dmat2_arr"; 1774 else if (location == m_po_dmat2_uniform_location) 1775 result = "uniform_dmat2"; 1776 else if (location == m_po_dmat2x3_arr_uniform_location) 1777 result = "uniform_dmat2x3_arr"; 1778 else if (location == m_po_dmat2x3_uniform_location) 1779 result = "uniform_dmat2x3"; 1780 else if (location == m_po_dmat2x4_arr_uniform_location) 1781 result = "uniform_dmat2x4_arr"; 1782 else if (location == m_po_dmat2x4_uniform_location) 1783 result = "uniform_dmat2x4"; 1784 else if (location == m_po_dmat3_arr_uniform_location) 1785 result = "uniform_dmat3_arr"; 1786 else if (location == m_po_dmat3_uniform_location) 1787 result = "uniform_dmat3"; 1788 else if (location == m_po_dmat3x2_arr_uniform_location) 1789 result = "uniform_dmat3x2_arr"; 1790 else if (location == m_po_dmat3x2_uniform_location) 1791 result = "uniform_dmat3x2"; 1792 else if (location == m_po_dmat3x4_arr_uniform_location) 1793 result = "uniform_dmat3x4_arr"; 1794 else if (location == m_po_dmat3x4_uniform_location) 1795 result = "uniform_dmat3x4"; 1796 else if (location == m_po_dmat4_arr_uniform_location) 1797 result = "uniform_dmat4_arr"; 1798 else if (location == m_po_dmat4_uniform_location) 1799 result = "uniform_dmat4"; 1800 else if (location == m_po_dmat4x2_arr_uniform_location) 1801 result = "uniform_dmat4x2_arr"; 1802 else if (location == m_po_dmat4x2_uniform_location) 1803 result = "uniform_dmat4x2"; 1804 else if (location == m_po_dmat4x3_arr_uniform_location) 1805 result = "uniform_dmat4x3_arr"; 1806 else if (location == m_po_dmat4x3_uniform_location) 1807 result = "uniform_dmat4x3"; 1808 else if (location == m_po_double_arr_uniform_location) 1809 result = "uniform_double_arr"; 1810 else if (location == m_po_double_uniform_location) 1811 result = "uniform_double"; 1812 else if (location == m_po_dvec2_arr_uniform_location) 1813 result = "uniform_dvec2_arr"; 1814 else if (location == m_po_dvec2_uniform_location) 1815 result = "uniform_dvec2"; 1816 else if (location == m_po_dvec3_arr_uniform_location) 1817 result = "uniform_dvec3_arr"; 1818 else if (location == m_po_dvec3_uniform_location) 1819 result = "uniform_dvec3"; 1820 else if (location == m_po_dvec4_arr_uniform_location) 1821 result = "uniform_dvec4_arr"; 1822 else if (location == m_po_dvec4_uniform_location) 1823 result = "uniform_dvec4"; 1824 else if (location == m_po_float_arr_uniform_location) 1825 result = "uniform_float_arr"; 1826 else if (location == m_po_float_uniform_location) 1827 result = "uniform_float"; 1828 else if (location == m_po_int_arr_uniform_location) 1829 result = "uniform_int_arr"; 1830 else if (location == m_po_int_uniform_location) 1831 result = "uniform_int"; 1832 else if (location == m_po_ivec2_arr_uniform_location) 1833 result = "uniform_ivec2_arr"; 1834 else if (location == m_po_ivec2_uniform_location) 1835 result = "uniform_ivec2"; 1836 else if (location == m_po_ivec3_arr_uniform_location) 1837 result = "uniform_ivec3_arr"; 1838 else if (location == m_po_ivec3_uniform_location) 1839 result = "uniform_ivec3"; 1840 else if (location == m_po_ivec4_arr_uniform_location) 1841 result = "uniform_ivec4_arr"; 1842 else if (location == m_po_ivec4_uniform_location) 1843 result = "uniform_ivec4"; 1844 else if (location == m_po_uint_arr_uniform_location) 1845 result = "uniform_uint_arr"; 1846 else if (location == m_po_uint_uniform_location) 1847 result = "uniform_uint"; 1848 else if (location == m_po_uvec2_arr_uniform_location) 1849 result = "uniform_uvec2_arr"; 1850 else if (location == m_po_uvec2_uniform_location) 1851 result = "uniform_uvec2"; 1852 else if (location == m_po_uvec3_arr_uniform_location) 1853 result = "uniform_uvec3_arr"; 1854 else if (location == m_po_uvec3_uniform_location) 1855 result = "uniform_uvec3"; 1856 else if (location == m_po_uvec4_arr_uniform_location) 1857 result = "uniform_uvec4_arr"; 1858 else if (location == m_po_uvec4_uniform_location) 1859 result = "uniform_uvec4"; 1860 else if (location == m_po_vec2_arr_uniform_location) 1861 result = "uniform_vec2_arr"; 1862 else if (location == m_po_vec2_uniform_location) 1863 result = "uniform_vec2"; 1864 else if (location == m_po_vec3_arr_uniform_location) 1865 result = "uniform_vec3_arr"; 1866 else if (location == m_po_vec3_uniform_location) 1867 result = "uniform_vec3"; 1868 else if (location == m_po_vec4_arr_uniform_location) 1869 result = "uniform_vec4_arr"; 1870 else if (location == m_po_vec4_uniform_location) 1871 result = "uniform_vec4"; 1872 1873 return result; 1874 } 1875 1876 /** Initializes all GL objects required to run the test. Also extracts locations of all 1877 * uniforms used by the test. 1878 * 1879 * This function can throw a TestError exception if the implementation misbehaves. 1880 */ 1881 void GPUShaderFP64Test1::initTest() 1882 { 1883 glw::GLint compile_status = GL_FALSE; 1884 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1885 glw::GLint link_status = GL_FALSE; 1886 1887 /* Set up a program object using all new double-precision types */ 1888 const char* vs_body = 1889 "#version 400\n" 1890 "\n" 1891 "uniform bool uniform_bool;\n" 1892 "uniform bvec2 uniform_bvec2;\n" 1893 "uniform bvec3 uniform_bvec3;\n" 1894 "uniform bvec4 uniform_bvec4;\n" 1895 "uniform dmat2 uniform_dmat2;\n" 1896 "uniform dmat2x3 uniform_dmat2x3;\n" 1897 "uniform dmat2x4 uniform_dmat2x4;\n" 1898 "uniform dmat3 uniform_dmat3;\n" 1899 "uniform dmat3x2 uniform_dmat3x2;\n" 1900 "uniform dmat3x4 uniform_dmat3x4;\n" 1901 "uniform dmat4 uniform_dmat4;\n" 1902 "uniform dmat4x2 uniform_dmat4x2;\n" 1903 "uniform dmat4x3 uniform_dmat4x3;\n" 1904 "uniform double uniform_double;\n" 1905 "uniform dvec2 uniform_dvec2;\n" 1906 "uniform dvec3 uniform_dvec3;\n" 1907 "uniform dvec4 uniform_dvec4;\n" 1908 "uniform float uniform_float;\n" 1909 "uniform int uniform_int;\n" 1910 "uniform ivec2 uniform_ivec2;\n" 1911 "uniform ivec3 uniform_ivec3;\n" 1912 "uniform ivec4 uniform_ivec4;\n" 1913 "uniform sampler2D uniform_sampler;\n" 1914 "uniform uint uniform_uint;\n" 1915 "uniform uvec2 uniform_uvec2;\n" 1916 "uniform uvec3 uniform_uvec3;\n" 1917 "uniform uvec4 uniform_uvec4;\n" 1918 "uniform vec2 uniform_vec2;\n" 1919 "uniform vec3 uniform_vec3;\n" 1920 "uniform vec4 uniform_vec4;\n" 1921 "uniform bool uniform_bool_arr [2];\n" 1922 "uniform bvec2 uniform_bvec2_arr [2];\n" 1923 "uniform bvec3 uniform_bvec3_arr [2];\n" 1924 "uniform bvec4 uniform_bvec4_arr [2];\n" 1925 "uniform dmat2 uniform_dmat2_arr [2];\n" 1926 "uniform dmat2x3 uniform_dmat2x3_arr[2];\n" 1927 "uniform dmat2x4 uniform_dmat2x4_arr[2];\n" 1928 "uniform dmat3 uniform_dmat3_arr [2];\n" 1929 "uniform dmat3x2 uniform_dmat3x2_arr[2];\n" 1930 "uniform dmat3x4 uniform_dmat3x4_arr[2];\n" 1931 "uniform dmat4 uniform_dmat4_arr [2];\n" 1932 "uniform dmat4x2 uniform_dmat4x2_arr[2];\n" 1933 "uniform dmat4x3 uniform_dmat4x3_arr[2];\n" 1934 "uniform double uniform_double_arr [2];\n" 1935 "uniform dvec2 uniform_dvec2_arr [2];\n" 1936 "uniform dvec3 uniform_dvec3_arr [2];\n" 1937 "uniform dvec4 uniform_dvec4_arr [2];\n" 1938 "uniform float uniform_float_arr [2];\n" 1939 "uniform int uniform_int_arr [2];\n" 1940 "uniform ivec2 uniform_ivec2_arr [2];\n" 1941 "uniform ivec3 uniform_ivec3_arr [2];\n" 1942 "uniform ivec4 uniform_ivec4_arr [2];\n" 1943 "uniform uint uniform_uint_arr [2];\n" 1944 "uniform uvec2 uniform_uvec2_arr [2];\n" 1945 "uniform uvec3 uniform_uvec3_arr [2];\n" 1946 "uniform uvec4 uniform_uvec4_arr [2];\n" 1947 "uniform vec2 uniform_vec2_arr [2];\n" 1948 "uniform vec3 uniform_vec3_arr [2];\n" 1949 "uniform vec4 uniform_vec4_arr [2];\n" 1950 "\n" 1951 "void main()\n" 1952 "{\n" 1953 " gl_Position = vec4(0) + texture(uniform_sampler, vec2(0) );\n" 1954 "\n" 1955 " if (uniform_bool && uniform_bvec2.y && uniform_bvec3.z && uniform_bvec4.w &&\n" 1956 " uniform_bool_arr[1] && uniform_bvec2_arr[1].y && uniform_bvec3_arr[1].z && uniform_bvec4_arr[1].w)\n" 1957 " {\n" 1958 " double sum = uniform_dmat2 [0].x + uniform_dmat2x3 [0].x + uniform_dmat2x4 [0].x +\n" 1959 " uniform_dmat3 [0].x + uniform_dmat3x2 [0].x + uniform_dmat3x4 [0].x +\n" 1960 " uniform_dmat4 [0].x + uniform_dmat4x2 [0].x + uniform_dmat4x3 [0].x +\n" 1961 " uniform_dmat2_arr[0][0].x + uniform_dmat2x3_arr[0][0].x + uniform_dmat2x4_arr[0][0].x +\n" 1962 " uniform_dmat3_arr[0][0].x + uniform_dmat3x2_arr[0][0].x + uniform_dmat3x4_arr[0][0].x +\n" 1963 " uniform_dmat4_arr[0][0].x + uniform_dmat4x2_arr[0][0].x + uniform_dmat4x3_arr[0][0].x +\n" 1964 " uniform_double + uniform_double_arr [0] +\n" 1965 " uniform_dvec2.x + uniform_dvec3.x + uniform_dvec4.x +\n" 1966 " uniform_dvec2_arr[0].x + uniform_dvec3_arr[0].x + uniform_dvec4_arr[0].x;\n" 1967 " int sum2 = uniform_int + uniform_ivec2.x + uniform_ivec3.x +\n" 1968 " uniform_ivec4.x + uniform_ivec2_arr[0].x + uniform_ivec3_arr[0].x +\n" 1969 " uniform_ivec4_arr[0].x + uniform_int_arr[0];\n" 1970 " uint sum3 = uniform_uint + uniform_uvec2.x + uniform_uvec3.x +\n" 1971 " uniform_uvec4.x + uniform_uint_arr[0] + uniform_uvec2_arr[0].x +\n" 1972 " uniform_uvec3_arr[0].x + uniform_uvec4_arr[0].x;\n" 1973 " float sum4 = uniform_float + uniform_float_arr[0] + \n" 1974 " uniform_vec2.x + uniform_vec2_arr[0].x + \n" 1975 " uniform_vec3.x + uniform_vec3_arr[0].x + \n" 1976 " uniform_vec4.x + uniform_vec4_arr[0].x;\n" 1977 "\n" 1978 " if (sum * sum4 > intBitsToFloat(sum2) * uintBitsToFloat(sum3) )\n" 1979 " {\n" 1980 " gl_Position = vec4(1);\n" 1981 " }\n" 1982 " }\n" 1983 "}\n"; 1984 1985 m_po_id = gl.createProgram(); 1986 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 1987 1988 m_vs_id = gl.createShader(GL_VERTEX_SHADER); 1989 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed."); 1990 1991 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */); 1992 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 1993 1994 gl.compileShader(m_vs_id); 1995 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); 1996 1997 gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status); 1998 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 1999 2000 if (compile_status != GL_TRUE) 2001 { 2002 TCU_FAIL("Shader compilation failed."); 2003 } 2004 2005 gl.attachShader(m_po_id, m_vs_id); 2006 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed."); 2007 2008 gl.linkProgram(m_po_id); 2009 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed."); 2010 2011 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status); 2012 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 2013 2014 if (link_status != GL_TRUE) 2015 { 2016 TCU_FAIL("Program linking failed."); 2017 } 2018 2019 m_po_bool_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bool_arr[0]"); 2020 m_po_bool_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bool"); 2021 m_po_bvec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec2_arr[0]"); 2022 m_po_bvec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec2"); 2023 m_po_bvec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec3_arr[0]"); 2024 m_po_bvec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec3"); 2025 m_po_bvec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec4_arr[0]"); 2026 m_po_bvec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec4"); 2027 m_po_dmat2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2_arr[0]"); 2028 m_po_dmat2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2"); 2029 m_po_dmat2x3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x3_arr[0]"); 2030 m_po_dmat2x3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x3"); 2031 m_po_dmat2x4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x4_arr[0]"); 2032 m_po_dmat2x4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x4"); 2033 m_po_dmat3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3_arr[0]"); 2034 m_po_dmat3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3"); 2035 m_po_dmat3x2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x2_arr[0]"); 2036 m_po_dmat3x2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x2"); 2037 m_po_dmat3x4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x4_arr[0]"); 2038 m_po_dmat3x4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x4"); 2039 m_po_dmat4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4_arr[0]"); 2040 m_po_dmat4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4"); 2041 m_po_dmat4x2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x2_arr[0]"); 2042 m_po_dmat4x2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x2"); 2043 m_po_dmat4x3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x3_arr[0]"); 2044 m_po_dmat4x3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x3"); 2045 m_po_double_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_double_arr[0]"); 2046 m_po_double_uniform_location = gl.getUniformLocation(m_po_id, "uniform_double"); 2047 m_po_dvec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec2_arr[0]"); 2048 m_po_dvec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec2"); 2049 m_po_dvec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec3_arr[0]"); 2050 m_po_dvec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec3"); 2051 m_po_dvec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec4_arr[0]"); 2052 m_po_dvec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec4"); 2053 m_po_float_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_float_arr[0]"); 2054 m_po_float_uniform_location = gl.getUniformLocation(m_po_id, "uniform_float"); 2055 m_po_int_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_int_arr[0]"); 2056 m_po_int_uniform_location = gl.getUniformLocation(m_po_id, "uniform_int"); 2057 m_po_ivec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec2_arr[0]"); 2058 m_po_ivec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec2"); 2059 m_po_ivec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec3_arr[0]"); 2060 m_po_ivec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec3"); 2061 m_po_ivec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec4_arr[0]"); 2062 m_po_ivec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec4"); 2063 m_po_sampler_uniform_location = gl.getUniformLocation(m_po_id, "uniform_sampler"); 2064 m_po_uint_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uint_arr[0]"); 2065 m_po_uint_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uint"); 2066 m_po_uvec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec2_arr[0]"); 2067 m_po_uvec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec2"); 2068 m_po_uvec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec3_arr[0]"); 2069 m_po_uvec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec3"); 2070 m_po_uvec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec4_arr[0]"); 2071 m_po_uvec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec4"); 2072 m_po_vec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec2_arr[0]"); 2073 m_po_vec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec2"); 2074 m_po_vec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec3_arr[0]"); 2075 m_po_vec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec3"); 2076 m_po_vec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec4_arr[0]"); 2077 m_po_vec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec4"); 2078 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call(s) failed."); 2079 2080 if (m_po_bool_arr_uniform_location == -1 || m_po_bool_uniform_location == -1 || 2081 m_po_bvec2_arr_uniform_location == -1 || m_po_bvec2_uniform_location == -1 || 2082 m_po_bvec3_arr_uniform_location == -1 || m_po_bvec3_uniform_location == -1 || 2083 m_po_bvec4_arr_uniform_location == -1 || m_po_bvec4_uniform_location == -1 || 2084 m_po_dmat2_arr_uniform_location == -1 || m_po_dmat2_uniform_location == -1 || 2085 m_po_dmat2x3_arr_uniform_location == -1 || m_po_dmat2x3_uniform_location == -1 || 2086 m_po_dmat2x4_arr_uniform_location == -1 || m_po_dmat2x4_uniform_location == -1 || 2087 m_po_dmat3_arr_uniform_location == -1 || m_po_dmat3_uniform_location == -1 || 2088 m_po_dmat3x2_arr_uniform_location == -1 || m_po_dmat3x2_uniform_location == -1 || 2089 m_po_dmat3x4_arr_uniform_location == -1 || m_po_dmat3x4_uniform_location == -1 || 2090 m_po_dmat4_arr_uniform_location == -1 || m_po_dmat4_uniform_location == -1 || 2091 m_po_dmat4x2_arr_uniform_location == -1 || m_po_dmat4x2_uniform_location == -1 || 2092 m_po_dmat4x3_arr_uniform_location == -1 || m_po_dmat4x3_uniform_location == -1 || 2093 m_po_double_arr_uniform_location == -1 || m_po_double_uniform_location == -1 || 2094 m_po_dvec2_arr_uniform_location == -1 || m_po_dvec2_uniform_location == -1 || 2095 m_po_dvec3_arr_uniform_location == -1 || m_po_dvec3_uniform_location == -1 || 2096 m_po_dvec4_arr_uniform_location == -1 || m_po_dvec4_uniform_location == -1 || 2097 m_po_float_arr_uniform_location == -1 || m_po_float_uniform_location == -1 || 2098 m_po_int_arr_uniform_location == -1 || m_po_int_uniform_location == -1 || 2099 m_po_ivec2_arr_uniform_location == -1 || m_po_ivec2_uniform_location == -1 || 2100 m_po_ivec3_arr_uniform_location == -1 || m_po_ivec3_uniform_location == -1 || 2101 m_po_ivec4_arr_uniform_location == -1 || m_po_ivec4_uniform_location == -1 || 2102 m_po_sampler_uniform_location == -1 || m_po_uint_arr_uniform_location == -1 || 2103 m_po_uint_uniform_location == -1 || m_po_uvec2_arr_uniform_location == -1 || 2104 m_po_uvec2_uniform_location == -1 || m_po_uvec3_arr_uniform_location == -1 || 2105 m_po_uvec3_uniform_location == -1 || m_po_uvec4_arr_uniform_location == -1 || 2106 m_po_uvec4_uniform_location == -1 || m_po_vec2_arr_uniform_location == -1 || m_po_vec2_uniform_location == -1 || 2107 m_po_vec3_arr_uniform_location == -1 || m_po_vec3_uniform_location == -1 || 2108 m_po_vec4_arr_uniform_location == -1 || m_po_vec4_uniform_location == -1) 2109 { 2110 TCU_FAIL("At last one of the required uniforms is considered inactive."); 2111 } 2112 } 2113 2114 /** Tells wheter uniform at user-specified location represents a double-precision 2115 * matrix uniform. 2116 * 2117 * @param uniform_location Location of the uniform to use for the query. 2118 * 2119 * @return Requested information. 2120 **/ 2121 bool GPUShaderFP64Test1::isMatrixUniform(glw::GLint uniform_location) 2122 { 2123 return (uniform_location == m_po_dmat2_uniform_location || uniform_location == m_po_dmat2x3_uniform_location || 2124 uniform_location == m_po_dmat2x4_uniform_location || uniform_location == m_po_dmat3_uniform_location || 2125 uniform_location == m_po_dmat3x2_uniform_location || uniform_location == m_po_dmat3x4_uniform_location || 2126 uniform_location == m_po_dmat4_uniform_location || uniform_location == m_po_dmat4x2_uniform_location || 2127 uniform_location == m_po_dmat4x3_uniform_location); 2128 } 2129 2130 /** Tells whether user-specified uniform function corresponds to one of the 2131 * functions in glUniformMatrix*() class. 2132 * 2133 * @param func Uniform function enum to use for the query. 2134 * 2135 * @return true if the specified enum represents one of the glUniformMatrix*() functions, 2136 * false otherwise. 2137 **/ 2138 bool GPUShaderFP64Test1::isMatrixUniformFunction(_uniform_function func) 2139 { 2140 return (func == UNIFORM_FUNCTION_MATRIX2DV || func == UNIFORM_FUNCTION_MATRIX2X3DV || 2141 func == UNIFORM_FUNCTION_MATRIX2X4DV || func == UNIFORM_FUNCTION_MATRIX3DV || 2142 func == UNIFORM_FUNCTION_MATRIX3X2DV || func == UNIFORM_FUNCTION_MATRIX3X4DV || 2143 func == UNIFORM_FUNCTION_MATRIX4DV || func == UNIFORM_FUNCTION_MATRIX4X2DV || 2144 func == UNIFORM_FUNCTION_MATRIX4X3DV); 2145 } 2146 2147 /** Executes test iteration. 2148 * 2149 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 2150 */ 2151 tcu::TestNode::IterateResult GPUShaderFP64Test1::iterate() 2152 { 2153 /* Do not execute the test if GL_ARB_texture_view is not supported */ 2154 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64")) 2155 { 2156 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported."); 2157 } 2158 2159 /* Initialize all ES objects required to run all the checks */ 2160 initTest(); 2161 2162 /* Make sure GL_INVALID_OPERATION is generated by glUniform*() and 2163 * glUniformMatrix*() functions if there is no current program object. 2164 */ 2165 m_has_test_passed &= verifyErrorGenerationWhenUniformFunctionsCalledWithoutActivePO(); 2166 2167 /* Make sure GL_INVALID_OPERATION is generated by glUniform*() if 2168 * the size of the uniform variable declared in the shader does not 2169 * match the size indicated by the command. 2170 */ 2171 m_has_test_passed &= verifyErrorGenerationWhenCallingSizeMismatchedUniformFunctions(); 2172 2173 /* Make sure GL_INVALID_OPERATION is generated if glUniform*() and 2174 * glUniformMatrix*() are used to load a uniform variable of type 2175 * bool, bvec2, bvec3, bvec4, float, int, ivec2, ivec3, ivec4, 2176 * unsigned int, uvec2, uvec3, uvec4, vec2, vec3, vec4 or an array 2177 * of these. 2178 */ 2179 m_has_test_passed &= verifyErrorGenerationWhenCallingTypeMismatchedUniformFunctions(); 2180 2181 /* Make sure GL_INVALID_OPERATION is generated if glUniform*() and 2182 * glUniformMatrix*() are used to load incompatible double-typed 2183 * uniforms, as presented below: 2184 * 2185 * I. double-typed uniform configured by glUniform2d(); 2186 * II. double-typed uniform configured by glUniform3d(); 2187 * III. double-typed uniform configured by glUniform4d(); 2188 * IV. double-typed uniform configured by glUniformMatrix*(); 2189 * V. dvec2-typed uniform configured by glUniform1d(); 2190 * VI. dvec2-typed uniform configured by glUniform3d(); 2191 * VII. dvec2-typed uniform configured by glUniform4d(); 2192 * VIII. dvec2-typed uniform configured by glUniformMatrix*(); 2193 * 2194 * (etc.) 2195 * 2196 */ 2197 m_has_test_passed &= verifyErrorGenerationWhenCallingMismatchedDoubleUniformFunctions(); 2198 2199 /* Make sure GL_INVALID_OPERATION is generated if <location> of 2200 * glUniform*() and glUniformMatrix*() is an invalid uniform 2201 * location for the current program object and location is not 2202 * equal to -1. 2203 */ 2204 m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidLocation(); 2205 2206 /* Make sure GL_INVALID_VALUE is generated if <count> of 2207 * glUniform*() (*dv() functions only) and glUniformMatrix*() is 2208 * negative. 2209 */ 2210 m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithNegativeCount(); 2211 2212 /* Make sure GL_INVALID_OPERATION is generated if <count> of 2213 * glUniform*() (*dv() functions only) and glUniformMatrix*() is 2214 * greater than 1 and the indicated uniform variable is not an 2215 * array variable. 2216 */ 2217 m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidCount(); 2218 2219 /* Make sure GL_INVALID_OPERATION is generated if a sampler is 2220 * loaded by glUniform*() and glUniformMatrix*(). 2221 */ 2222 m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsForSamplers(); 2223 2224 /* Make sure GL_INVALID_OPERATION is generated if glUniform*() and 2225 * glUniformMatrix*() is used to load values for uniforms of 2226 * boolean types. 2227 */ 2228 m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsForBooleans(); 2229 2230 if (m_has_test_passed) 2231 { 2232 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2233 } 2234 else 2235 { 2236 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2237 } 2238 2239 return STOP; 2240 } 2241 2242 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or 2243 * glUniformMatrix*dv() functions is used to load a boolean uniform. 2244 * 2245 * @return true if the implementation was found to behave as expected, false otherwise. 2246 **/ 2247 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsForBooleans() 2248 { 2249 const double double_data[] = { 2250 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 2251 }; 2252 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2253 bool result = true; 2254 glw::GLint uniform_locations[] = { m_po_bool_arr_uniform_location, m_po_bool_uniform_location, 2255 m_po_bvec2_arr_uniform_location, m_po_bvec2_uniform_location, 2256 m_po_bvec3_arr_uniform_location, m_po_bvec3_uniform_location, 2257 m_po_bvec4_arr_uniform_location, m_po_bvec4_uniform_location }; 2258 const unsigned int n_uniform_locations = sizeof(uniform_locations) / sizeof(uniform_locations[0]); 2259 2260 for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT; 2261 ++n_uniform_function) 2262 { 2263 const _uniform_function uniform_function = (_uniform_function)n_uniform_function; 2264 2265 for (unsigned int n_uniform_location = 0; n_uniform_location < n_uniform_locations; ++n_uniform_location) 2266 { 2267 const glw::GLint uniform_location = uniform_locations[n_uniform_location]; 2268 2269 switch (uniform_function) 2270 { 2271 case UNIFORM_FUNCTION_1D: 2272 gl.uniform1d(uniform_location, 0.0); 2273 break; 2274 case UNIFORM_FUNCTION_2D: 2275 gl.uniform2d(uniform_location, 0.0, 1.0); 2276 break; 2277 case UNIFORM_FUNCTION_3D: 2278 gl.uniform3d(uniform_location, 0.0, 1.0, 2.0); 2279 break; 2280 case UNIFORM_FUNCTION_4D: 2281 gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0); 2282 break; 2283 2284 case UNIFORM_FUNCTION_1DV: 2285 gl.uniform1dv(uniform_location, 1 /* count */, double_data); 2286 break; 2287 case UNIFORM_FUNCTION_2DV: 2288 gl.uniform2dv(uniform_location, 1 /* count */, double_data); 2289 break; 2290 case UNIFORM_FUNCTION_3DV: 2291 gl.uniform3dv(uniform_location, 1 /* count */, double_data); 2292 break; 2293 case UNIFORM_FUNCTION_4DV: 2294 gl.uniform4dv(uniform_location, 1 /* count */, double_data); 2295 break; 2296 2297 case UNIFORM_FUNCTION_MATRIX2DV: 2298 gl.uniformMatrix2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2299 break; 2300 case UNIFORM_FUNCTION_MATRIX2X3DV: 2301 gl.uniformMatrix2x3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2302 break; 2303 case UNIFORM_FUNCTION_MATRIX2X4DV: 2304 gl.uniformMatrix2x4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2305 break; 2306 case UNIFORM_FUNCTION_MATRIX3DV: 2307 gl.uniformMatrix3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2308 break; 2309 case UNIFORM_FUNCTION_MATRIX3X2DV: 2310 gl.uniformMatrix3x2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2311 break; 2312 case UNIFORM_FUNCTION_MATRIX3X4DV: 2313 gl.uniformMatrix3x4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2314 break; 2315 case UNIFORM_FUNCTION_MATRIX4DV: 2316 gl.uniformMatrix4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2317 break; 2318 case UNIFORM_FUNCTION_MATRIX4X2DV: 2319 gl.uniformMatrix4x2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2320 break; 2321 case UNIFORM_FUNCTION_MATRIX4X3DV: 2322 gl.uniformMatrix4x3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2323 break; 2324 2325 default: 2326 { 2327 TCU_FAIL("Unrecognized uniform function"); 2328 } 2329 } 2330 2331 /* Make sure GL_INVALID_OPERATION was generated by the call */ 2332 const glw::GLenum error_code = gl.getError(); 2333 2334 if (error_code != GL_INVALID_OPERATION) 2335 { 2336 m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function) 2337 << "() did not generate an error" 2338 " when applied against a boolean uniform." 2339 << tcu::TestLog::EndMessage; 2340 2341 result = false; 2342 } 2343 } /* for (all bool uniforms) */ 2344 } /* for (all uniform functions) */ 2345 2346 return result; 2347 } 2348 2349 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or 2350 * glUniformMatrix*dv() functions is used to load a sampler2D uniform. 2351 * 2352 * @return true if the implementation was found to behave as expected, false otherwise. 2353 **/ 2354 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsForSamplers() 2355 { 2356 const double double_data[] = { 2357 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 2358 }; 2359 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2360 bool result = true; 2361 2362 for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT; 2363 ++n_uniform_function) 2364 { 2365 _uniform_function uniform_function = (_uniform_function)n_uniform_function; 2366 2367 switch (uniform_function) 2368 { 2369 case UNIFORM_FUNCTION_1D: 2370 gl.uniform1d(m_po_sampler_uniform_location, 0.0); 2371 break; 2372 case UNIFORM_FUNCTION_2D: 2373 gl.uniform2d(m_po_sampler_uniform_location, 0.0, 1.0); 2374 break; 2375 case UNIFORM_FUNCTION_3D: 2376 gl.uniform3d(m_po_sampler_uniform_location, 0.0, 1.0, 2.0); 2377 break; 2378 case UNIFORM_FUNCTION_4D: 2379 gl.uniform4d(m_po_sampler_uniform_location, 0.0, 1.0, 2.0, 3.0); 2380 break; 2381 2382 case UNIFORM_FUNCTION_1DV: 2383 gl.uniform1dv(m_po_sampler_uniform_location, 1 /* count */, double_data); 2384 break; 2385 case UNIFORM_FUNCTION_2DV: 2386 gl.uniform2dv(m_po_sampler_uniform_location, 1 /* count */, double_data); 2387 break; 2388 case UNIFORM_FUNCTION_3DV: 2389 gl.uniform3dv(m_po_sampler_uniform_location, 1 /* count */, double_data); 2390 break; 2391 case UNIFORM_FUNCTION_4DV: 2392 gl.uniform4dv(m_po_sampler_uniform_location, 1 /* count */, double_data); 2393 break; 2394 2395 case UNIFORM_FUNCTION_MATRIX2DV: 2396 gl.uniformMatrix2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2397 break; 2398 case UNIFORM_FUNCTION_MATRIX2X3DV: 2399 gl.uniformMatrix2x3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2400 break; 2401 case UNIFORM_FUNCTION_MATRIX2X4DV: 2402 gl.uniformMatrix2x4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2403 break; 2404 case UNIFORM_FUNCTION_MATRIX3DV: 2405 gl.uniformMatrix3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2406 break; 2407 case UNIFORM_FUNCTION_MATRIX3X2DV: 2408 gl.uniformMatrix3x2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2409 break; 2410 case UNIFORM_FUNCTION_MATRIX3X4DV: 2411 gl.uniformMatrix3x4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2412 break; 2413 case UNIFORM_FUNCTION_MATRIX4DV: 2414 gl.uniformMatrix4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2415 break; 2416 case UNIFORM_FUNCTION_MATRIX4X2DV: 2417 gl.uniformMatrix4x2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2418 break; 2419 case UNIFORM_FUNCTION_MATRIX4X3DV: 2420 gl.uniformMatrix4x3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2421 break; 2422 2423 default: 2424 { 2425 TCU_FAIL("Unrecognized uniform function"); 2426 } 2427 } 2428 2429 /* Make sure GL_INVALID_OPERATION was generated by the call */ 2430 const glw::GLenum error_code = gl.getError(); 2431 2432 if (error_code != GL_INVALID_OPERATION) 2433 { 2434 m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function) 2435 << "() did not generate an error" 2436 " when applied against a sampler uniform." 2437 << tcu::TestLog::EndMessage; 2438 2439 result = false; 2440 } 2441 } /* for (all uniform functions) */ 2442 2443 return result; 2444 } 2445 2446 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*dv() or 2447 * glUniformMatrix*dv() functions is used to load a compatible uniform using an 2448 * invalid <count> argument. 2449 * 2450 * @return true if the implementation was found to behave as expected, false otherwise. 2451 **/ 2452 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidCount() 2453 { 2454 const glw::GLdouble double_values[16] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 2455 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 }; 2456 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2457 bool result = true; 2458 const _uniform_function uniform_functions[] = { UNIFORM_FUNCTION_1DV, UNIFORM_FUNCTION_2DV, 2459 UNIFORM_FUNCTION_3DV, UNIFORM_FUNCTION_4DV, 2460 UNIFORM_FUNCTION_MATRIX2DV, UNIFORM_FUNCTION_MATRIX2X3DV, 2461 UNIFORM_FUNCTION_MATRIX2X4DV, UNIFORM_FUNCTION_MATRIX3DV, 2462 UNIFORM_FUNCTION_MATRIX3X2DV, UNIFORM_FUNCTION_MATRIX3X4DV, 2463 UNIFORM_FUNCTION_MATRIX4DV, UNIFORM_FUNCTION_MATRIX4X2DV, 2464 UNIFORM_FUNCTION_MATRIX4X3DV }; 2465 const glw::GLint uniforms[] = { 2466 m_po_bool_uniform_location, m_po_bvec2_uniform_location, m_po_bvec3_uniform_location, 2467 m_po_bvec4_uniform_location, m_po_dmat2_uniform_location, m_po_dmat2x3_uniform_location, 2468 m_po_dmat2x4_uniform_location, m_po_dmat3_uniform_location, m_po_dmat3x2_uniform_location, 2469 m_po_dmat3x4_uniform_location, m_po_dmat4_uniform_location, m_po_dmat4x2_uniform_location, 2470 m_po_dmat4x3_uniform_location, m_po_double_uniform_location, m_po_dvec2_uniform_location, 2471 m_po_dvec3_uniform_location, m_po_dvec4_uniform_location, m_po_float_uniform_location, 2472 m_po_int_uniform_location, m_po_ivec2_uniform_location, m_po_ivec3_uniform_location, 2473 m_po_ivec4_uniform_location, m_po_uint_uniform_location, m_po_uvec2_uniform_location, 2474 m_po_uvec3_uniform_location, m_po_uvec4_uniform_location, m_po_vec2_uniform_location, 2475 m_po_vec3_uniform_location, m_po_vec4_uniform_location 2476 }; 2477 2478 const unsigned int n_uniform_functions = sizeof(uniform_functions) / sizeof(uniform_functions[0]); 2479 const unsigned int n_uniforms = sizeof(uniforms) / sizeof(uniforms[0]); 2480 2481 for (unsigned int n_uniform_function = 0; n_uniform_function < n_uniform_functions; ++n_uniform_function) 2482 { 2483 _uniform_function uniform_function = uniform_functions[n_uniform_function]; 2484 2485 for (unsigned int n_uniform = 0; n_uniform < n_uniforms; ++n_uniform) 2486 { 2487 glw::GLint uniform_location = uniforms[n_uniform]; 2488 2489 /* Make sure we only use glUniformMatrix*() functions with matrix uniforms, 2490 * and glUniform*() functions with vector uniforms. 2491 */ 2492 bool is_matrix_uniform = isMatrixUniform(uniform_location); 2493 2494 if (((false == is_matrix_uniform) && (true == isMatrixUniformFunction(uniform_function))) || 2495 ((true == is_matrix_uniform) && (false == isMatrixUniformFunction(uniform_function)))) 2496 { 2497 continue; 2498 } 2499 2500 /* Issue the call with an invalid <count> argument */ 2501 switch (uniform_function) 2502 { 2503 case UNIFORM_FUNCTION_1DV: 2504 gl.uniform1dv(uniform_location, 2, double_values); 2505 break; 2506 case UNIFORM_FUNCTION_2DV: 2507 gl.uniform2dv(uniform_location, 2, double_values); 2508 break; 2509 case UNIFORM_FUNCTION_3DV: 2510 gl.uniform3dv(uniform_location, 2, double_values); 2511 break; 2512 case UNIFORM_FUNCTION_4DV: 2513 gl.uniform4dv(uniform_location, 2, double_values); 2514 break; 2515 case UNIFORM_FUNCTION_MATRIX2DV: 2516 gl.uniformMatrix2dv(uniform_location, 2, GL_FALSE, double_values); 2517 break; 2518 case UNIFORM_FUNCTION_MATRIX2X3DV: 2519 gl.uniformMatrix2x3dv(uniform_location, 2, GL_FALSE, double_values); 2520 break; 2521 case UNIFORM_FUNCTION_MATRIX2X4DV: 2522 gl.uniformMatrix2x4dv(uniform_location, 2, GL_FALSE, double_values); 2523 break; 2524 case UNIFORM_FUNCTION_MATRIX3DV: 2525 gl.uniformMatrix3dv(uniform_location, 2, GL_FALSE, double_values); 2526 break; 2527 case UNIFORM_FUNCTION_MATRIX3X2DV: 2528 gl.uniformMatrix3x2dv(uniform_location, 2, GL_FALSE, double_values); 2529 break; 2530 case UNIFORM_FUNCTION_MATRIX3X4DV: 2531 gl.uniformMatrix3x4dv(uniform_location, 2, GL_FALSE, double_values); 2532 break; 2533 case UNIFORM_FUNCTION_MATRIX4DV: 2534 gl.uniformMatrix4dv(uniform_location, 2, GL_FALSE, double_values); 2535 break; 2536 case UNIFORM_FUNCTION_MATRIX4X2DV: 2537 gl.uniformMatrix4x2dv(uniform_location, 2, GL_FALSE, double_values); 2538 break; 2539 case UNIFORM_FUNCTION_MATRIX4X3DV: 2540 gl.uniformMatrix4x3dv(uniform_location, 2, GL_FALSE, double_values); 2541 break; 2542 2543 default: 2544 { 2545 TCU_FAIL("Unrecognized uniform function"); 2546 } 2547 } /* switch (uniform_function) */ 2548 2549 /* Make sure GL_INVALID_VALUE was generated */ 2550 glw::GLenum error_code = gl.getError(); 2551 2552 if (error_code != GL_INVALID_OPERATION) 2553 { 2554 m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function) 2555 << "() " 2556 "was called with an invalid count argument but did not generate a " 2557 "GL_INVALID_OPERATION error" 2558 << tcu::TestLog::EndMessage; 2559 2560 result = false; 2561 } 2562 } /* for (all non-arrayed uniforms) */ 2563 } /* for (all uniform functions) */ 2564 2565 return result; 2566 } 2567 2568 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or 2569 * glUniformMatrix*dv() functions is used to load an uniform at an invalid location. 2570 * 2571 * @return true if the implementation was found to behave as expected, false otherwise. 2572 **/ 2573 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidLocation() 2574 { 2575 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2576 bool result = true; 2577 2578 /* Find the largest valid uniform location */ 2579 const glw::GLint uniform_locations[] = { 2580 m_po_bool_arr_uniform_location, m_po_bool_uniform_location, m_po_bvec2_arr_uniform_location, 2581 m_po_bvec2_uniform_location, m_po_bvec3_arr_uniform_location, m_po_bvec3_uniform_location, 2582 m_po_bvec4_arr_uniform_location, m_po_bvec4_uniform_location, m_po_dmat2_arr_uniform_location, 2583 m_po_dmat2_uniform_location, m_po_dmat2x3_arr_uniform_location, m_po_dmat2x3_uniform_location, 2584 m_po_dmat2x4_arr_uniform_location, m_po_dmat2x4_uniform_location, m_po_dmat3_arr_uniform_location, 2585 m_po_dmat3_uniform_location, m_po_dmat3x2_arr_uniform_location, m_po_dmat3x2_uniform_location, 2586 m_po_dmat3x4_arr_uniform_location, m_po_dmat3x4_uniform_location, m_po_dmat4_arr_uniform_location, 2587 m_po_dmat4_uniform_location, m_po_dmat4x2_arr_uniform_location, m_po_dmat4x2_uniform_location, 2588 m_po_dmat4x3_arr_uniform_location, m_po_dmat4x3_uniform_location, m_po_double_arr_uniform_location, 2589 m_po_double_uniform_location, m_po_dvec2_arr_uniform_location, m_po_dvec2_uniform_location, 2590 m_po_dvec3_arr_uniform_location, m_po_dvec3_uniform_location, m_po_dvec4_arr_uniform_location, 2591 m_po_dvec4_uniform_location, m_po_float_arr_uniform_location, m_po_float_uniform_location, 2592 m_po_int_arr_uniform_location, m_po_int_uniform_location, m_po_ivec2_arr_uniform_location, 2593 m_po_ivec2_uniform_location, m_po_ivec3_arr_uniform_location, m_po_ivec3_uniform_location, 2594 m_po_ivec4_arr_uniform_location, m_po_ivec4_uniform_location, m_po_uint_arr_uniform_location, 2595 m_po_uint_uniform_location, m_po_uvec2_arr_uniform_location, m_po_uvec2_uniform_location, 2596 m_po_uvec3_arr_uniform_location, m_po_uvec3_uniform_location, m_po_uvec4_arr_uniform_location, 2597 m_po_uvec4_uniform_location, m_po_vec2_arr_uniform_location, m_po_vec2_uniform_location, 2598 m_po_vec3_arr_uniform_location, m_po_vec3_uniform_location, m_po_vec4_arr_uniform_location, 2599 m_po_vec4_uniform_location 2600 }; 2601 const unsigned int n_uniform_locations = sizeof(uniform_locations) / sizeof(uniform_locations[0]); 2602 glw::GLint valid_uniform_location = -1; 2603 2604 for (unsigned int n_uniform_location = 0; n_uniform_location < n_uniform_locations; ++n_uniform_location) 2605 { 2606 glw::GLint uniform_location = uniform_locations[n_uniform_location]; 2607 2608 if (uniform_location > valid_uniform_location) 2609 { 2610 valid_uniform_location = uniform_location; 2611 } 2612 } /* for (all uniform locations) */ 2613 2614 /* Iterate through all uniform functions and make sure GL_INVALID_OPERATION error is always generated 2615 * for invalid uniform location that is != -1 2616 */ 2617 const double double_data[] = { 2618 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 2619 }; 2620 const glw::GLint invalid_uniform_location = valid_uniform_location + 1; 2621 2622 for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT; 2623 ++n_uniform_function) 2624 { 2625 _uniform_function uniform_function = (_uniform_function)n_uniform_function; 2626 2627 switch (uniform_function) 2628 { 2629 case UNIFORM_FUNCTION_1D: 2630 gl.uniform1d(invalid_uniform_location, 0.0); 2631 break; 2632 case UNIFORM_FUNCTION_2D: 2633 gl.uniform2d(invalid_uniform_location, 0.0, 1.0); 2634 break; 2635 case UNIFORM_FUNCTION_3D: 2636 gl.uniform3d(invalid_uniform_location, 0.0, 1.0, 2.0); 2637 break; 2638 case UNIFORM_FUNCTION_4D: 2639 gl.uniform4d(invalid_uniform_location, 0.0, 1.0, 2.0, 3.0); 2640 break; 2641 2642 case UNIFORM_FUNCTION_1DV: 2643 gl.uniform1dv(invalid_uniform_location, 1 /* count */, double_data); 2644 break; 2645 case UNIFORM_FUNCTION_2DV: 2646 gl.uniform2dv(invalid_uniform_location, 1 /* count */, double_data); 2647 break; 2648 case UNIFORM_FUNCTION_3DV: 2649 gl.uniform3dv(invalid_uniform_location, 1 /* count */, double_data); 2650 break; 2651 case UNIFORM_FUNCTION_4DV: 2652 gl.uniform4dv(invalid_uniform_location, 1 /* count */, double_data); 2653 break; 2654 2655 case UNIFORM_FUNCTION_MATRIX2DV: 2656 gl.uniformMatrix2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2657 break; 2658 case UNIFORM_FUNCTION_MATRIX2X3DV: 2659 gl.uniformMatrix2x3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2660 break; 2661 case UNIFORM_FUNCTION_MATRIX2X4DV: 2662 gl.uniformMatrix2x4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2663 break; 2664 case UNIFORM_FUNCTION_MATRIX3DV: 2665 gl.uniformMatrix3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2666 break; 2667 case UNIFORM_FUNCTION_MATRIX3X2DV: 2668 gl.uniformMatrix3x2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2669 break; 2670 case UNIFORM_FUNCTION_MATRIX3X4DV: 2671 gl.uniformMatrix3x4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2672 break; 2673 case UNIFORM_FUNCTION_MATRIX4DV: 2674 gl.uniformMatrix4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2675 break; 2676 case UNIFORM_FUNCTION_MATRIX4X2DV: 2677 gl.uniformMatrix4x2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2678 break; 2679 case UNIFORM_FUNCTION_MATRIX4X3DV: 2680 gl.uniformMatrix4x3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data); 2681 break; 2682 2683 default: 2684 { 2685 TCU_FAIL("Unrecognized uniform function"); 2686 } 2687 } 2688 2689 const glw::GLenum error_code = gl.getError(); 2690 2691 if (error_code != GL_INVALID_OPERATION) 2692 { 2693 m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function) 2694 << "() did not generate an error" 2695 " when passed an invalid uniform location different from -1." 2696 << tcu::TestLog::EndMessage; 2697 2698 result = false; 2699 } 2700 } /* for (all uniform functions) */ 2701 2702 return result; 2703 } 2704 2705 /** Verifies GL_INVALID_VALUE is generated if any of the glUniform*dv() or 2706 * glUniformMatrix*dv() functions is used to load a compatible uniform using an 2707 * invalid <count> argument of -1. 2708 * 2709 * @return true if the implementation was found to behave as expected, false otherwise. 2710 **/ 2711 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithNegativeCount() 2712 { 2713 const glw::GLdouble double_values[16] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 2714 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 }; 2715 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2716 bool result = true; 2717 const _uniform_function uniform_functions[] = { UNIFORM_FUNCTION_1DV, UNIFORM_FUNCTION_2DV, 2718 UNIFORM_FUNCTION_3DV, UNIFORM_FUNCTION_4DV, 2719 UNIFORM_FUNCTION_MATRIX2DV, UNIFORM_FUNCTION_MATRIX2X3DV, 2720 UNIFORM_FUNCTION_MATRIX2X4DV, UNIFORM_FUNCTION_MATRIX3DV, 2721 UNIFORM_FUNCTION_MATRIX3X2DV, UNIFORM_FUNCTION_MATRIX3X4DV, 2722 UNIFORM_FUNCTION_MATRIX4DV, UNIFORM_FUNCTION_MATRIX4X2DV, 2723 UNIFORM_FUNCTION_MATRIX4X3DV }; 2724 const unsigned int n_uniform_functions = sizeof(uniform_functions) / sizeof(uniform_functions[0]); 2725 2726 for (unsigned int n_uniform_function = 0; n_uniform_function < n_uniform_functions; ++n_uniform_function) 2727 { 2728 _uniform_function uniform_function = uniform_functions[n_uniform_function]; 2729 2730 switch (uniform_function) 2731 { 2732 case UNIFORM_FUNCTION_1DV: 2733 gl.uniform1dv(m_po_double_arr_uniform_location, -1, double_values); 2734 break; 2735 case UNIFORM_FUNCTION_2DV: 2736 gl.uniform2dv(m_po_dvec2_arr_uniform_location, -1, double_values); 2737 break; 2738 case UNIFORM_FUNCTION_3DV: 2739 gl.uniform3dv(m_po_dvec3_arr_uniform_location, -1, double_values); 2740 break; 2741 case UNIFORM_FUNCTION_4DV: 2742 gl.uniform4dv(m_po_dvec4_arr_uniform_location, -1, double_values); 2743 break; 2744 case UNIFORM_FUNCTION_MATRIX2DV: 2745 gl.uniformMatrix2dv(m_po_dmat2_arr_uniform_location, -1, GL_FALSE, double_values); 2746 break; 2747 case UNIFORM_FUNCTION_MATRIX2X3DV: 2748 gl.uniformMatrix2x3dv(m_po_dmat2x3_arr_uniform_location, -1, GL_FALSE, double_values); 2749 break; 2750 case UNIFORM_FUNCTION_MATRIX2X4DV: 2751 gl.uniformMatrix2x4dv(m_po_dmat2x4_arr_uniform_location, -1, GL_FALSE, double_values); 2752 break; 2753 case UNIFORM_FUNCTION_MATRIX3DV: 2754 gl.uniformMatrix3dv(m_po_dmat3_arr_uniform_location, -1, GL_FALSE, double_values); 2755 break; 2756 case UNIFORM_FUNCTION_MATRIX3X2DV: 2757 gl.uniformMatrix3x2dv(m_po_dmat3x2_arr_uniform_location, -1, GL_FALSE, double_values); 2758 break; 2759 case UNIFORM_FUNCTION_MATRIX3X4DV: 2760 gl.uniformMatrix3x4dv(m_po_dmat3x4_arr_uniform_location, -1, GL_FALSE, double_values); 2761 break; 2762 case UNIFORM_FUNCTION_MATRIX4DV: 2763 gl.uniformMatrix4dv(m_po_dmat4_arr_uniform_location, -1, GL_FALSE, double_values); 2764 break; 2765 case UNIFORM_FUNCTION_MATRIX4X2DV: 2766 gl.uniformMatrix4x2dv(m_po_dmat4x2_arr_uniform_location, -1, GL_FALSE, double_values); 2767 break; 2768 case UNIFORM_FUNCTION_MATRIX4X3DV: 2769 gl.uniformMatrix4x3dv(m_po_dmat4x3_arr_uniform_location, -1, GL_FALSE, double_values); 2770 break; 2771 2772 default: 2773 { 2774 TCU_FAIL("Unrecognized uniform function"); 2775 } 2776 } /* switch (uniform_function) */ 2777 2778 /* Make sure GL_INVALID_VALUE was generated */ 2779 glw::GLenum error_code = gl.getError(); 2780 2781 if (error_code != GL_INVALID_VALUE) 2782 { 2783 m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function) 2784 << "() " 2785 "was called with a negative count argument but did not generate a " 2786 "GL_INVALID_VALUE error" 2787 << tcu::TestLog::EndMessage; 2788 2789 result = false; 2790 } 2791 } /* for (all uniform functions) */ 2792 2793 return result; 2794 } 2795 2796 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or 2797 * glUniformMatrix*dv() functions is used to load an uniform that's incompatible with the 2798 * function (as per spec). 2799 * 2800 * @return true if the implementation was found to behave as expected, false otherwise. 2801 **/ 2802 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingMismatchedDoubleUniformFunctions() 2803 { 2804 const double double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; 2805 glw::GLenum error_code = GL_NO_ERROR; 2806 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2807 bool result = true; 2808 2809 const glw::GLint double_uniform_locations[] = { m_po_dmat2_uniform_location, m_po_dmat2x3_uniform_location, 2810 m_po_dmat2x4_uniform_location, m_po_dmat3_uniform_location, 2811 m_po_dmat3x2_uniform_location, m_po_dmat3x4_uniform_location, 2812 m_po_dmat4_uniform_location, m_po_dmat4x2_uniform_location, 2813 m_po_dmat4x3_uniform_location, m_po_double_uniform_location, 2814 m_po_dvec2_uniform_location, m_po_dvec3_uniform_location, 2815 m_po_dvec4_uniform_location }; 2816 const unsigned int n_double_uniform_locations = 2817 sizeof(double_uniform_locations) / sizeof(double_uniform_locations[0]); 2818 2819 gl.useProgram(m_po_id); 2820 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 2821 2822 for (unsigned int n_uniform_location = 0; n_uniform_location < n_double_uniform_locations; ++n_uniform_location) 2823 { 2824 glw::GLint uniform_location = double_uniform_locations[n_uniform_location]; 2825 2826 for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST); 2827 function < static_cast<int>(UNIFORM_FUNCTION_COUNT); function++) 2828 { 2829 _uniform_function e_function = static_cast<_uniform_function>(function); 2830 /* Exclude valid combinations */ 2831 if (((uniform_location == m_po_dmat2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2DV)) || 2832 ((uniform_location == m_po_dmat2x3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2X3DV)) || 2833 ((uniform_location == m_po_dmat2x4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2X4DV)) || 2834 ((uniform_location == m_po_dmat3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3DV)) || 2835 ((uniform_location == m_po_dmat3x2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3X2DV)) || 2836 ((uniform_location == m_po_dmat3x4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3X4DV)) || 2837 ((uniform_location == m_po_dmat4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4DV)) || 2838 ((uniform_location == m_po_dmat4x2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4X2DV)) || 2839 ((uniform_location == m_po_dmat4x3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4X3DV)) || 2840 ((uniform_location == m_po_double_uniform_location) && 2841 ((e_function == UNIFORM_FUNCTION_1D) || (e_function == UNIFORM_FUNCTION_1DV))) || 2842 ((uniform_location == m_po_dvec2_uniform_location) && 2843 ((e_function == UNIFORM_FUNCTION_2D) || (e_function == UNIFORM_FUNCTION_2DV))) || 2844 ((uniform_location == m_po_dvec3_uniform_location) && 2845 ((e_function == UNIFORM_FUNCTION_3D) || (e_function == UNIFORM_FUNCTION_3DV))) || 2846 ((uniform_location == m_po_dvec4_uniform_location) && 2847 ((e_function == UNIFORM_FUNCTION_4D) || (e_function == UNIFORM_FUNCTION_4DV)))) 2848 { 2849 continue; 2850 } 2851 2852 switch (e_function) 2853 { 2854 case UNIFORM_FUNCTION_1D: 2855 { 2856 gl.uniform1d(uniform_location, double_data[0]); 2857 2858 break; 2859 } 2860 2861 case UNIFORM_FUNCTION_2D: 2862 { 2863 gl.uniform2d(uniform_location, double_data[0], double_data[1]); 2864 2865 break; 2866 } 2867 2868 case UNIFORM_FUNCTION_3D: 2869 { 2870 gl.uniform3d(uniform_location, double_data[0], double_data[1], double_data[2]); 2871 2872 break; 2873 } 2874 2875 case UNIFORM_FUNCTION_4D: 2876 { 2877 gl.uniform4d(uniform_location, double_data[0], double_data[1], double_data[2], double_data[3]); 2878 2879 break; 2880 } 2881 2882 case UNIFORM_FUNCTION_1DV: 2883 gl.uniform1dv(uniform_location, 1 /* count */, double_data); 2884 break; 2885 case UNIFORM_FUNCTION_2DV: 2886 gl.uniform2dv(uniform_location, 1 /* count */, double_data); 2887 break; 2888 case UNIFORM_FUNCTION_3DV: 2889 gl.uniform3dv(uniform_location, 1 /* count */, double_data); 2890 break; 2891 case UNIFORM_FUNCTION_4DV: 2892 gl.uniform4dv(uniform_location, 1 /* count */, double_data); 2893 break; 2894 case UNIFORM_FUNCTION_MATRIX2DV: 2895 gl.uniformMatrix2dv(uniform_location, 1 /* count */, GL_FALSE, double_data); 2896 break; 2897 case UNIFORM_FUNCTION_MATRIX2X3DV: 2898 gl.uniformMatrix2x3dv(uniform_location, 1 /* count */, GL_FALSE, double_data); 2899 break; 2900 case UNIFORM_FUNCTION_MATRIX2X4DV: 2901 gl.uniformMatrix2x4dv(uniform_location, 1 /* count */, GL_FALSE, double_data); 2902 break; 2903 case UNIFORM_FUNCTION_MATRIX3DV: 2904 gl.uniformMatrix3dv(uniform_location, 1 /* count */, GL_FALSE, double_data); 2905 break; 2906 case UNIFORM_FUNCTION_MATRIX3X2DV: 2907 gl.uniformMatrix3x2dv(uniform_location, 1 /* count */, GL_FALSE, double_data); 2908 break; 2909 case UNIFORM_FUNCTION_MATRIX3X4DV: 2910 gl.uniformMatrix3x4dv(uniform_location, 1 /* count */, GL_FALSE, double_data); 2911 break; 2912 case UNIFORM_FUNCTION_MATRIX4DV: 2913 gl.uniformMatrix4dv(uniform_location, 1 /* count */, GL_FALSE, double_data); 2914 break; 2915 case UNIFORM_FUNCTION_MATRIX4X2DV: 2916 gl.uniformMatrix4x2dv(uniform_location, 1 /* count */, GL_FALSE, double_data); 2917 break; 2918 case UNIFORM_FUNCTION_MATRIX4X3DV: 2919 gl.uniformMatrix4x3dv(uniform_location, 1 /* count */, GL_FALSE, double_data); 2920 break; 2921 2922 default: 2923 { 2924 TCU_FAIL("Unrecognized function"); 2925 } 2926 } /* switch (function) */ 2927 2928 /* Make sure GL_INVALID_OPERATION error was generated */ 2929 error_code = gl.getError(); 2930 2931 if (error_code != GL_INVALID_OPERATION) 2932 { 2933 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid error [" << error_code 2934 << "] was generated when a mismatched " 2935 "double-precision uniform function " 2936 << getUniformFunctionString(e_function) << "() was used to configure uniform " 2937 << getUniformNameForLocation(uniform_location) << "." << tcu::TestLog::EndMessage; 2938 2939 result = false; 2940 } 2941 } /* for (all uniform functions) */ 2942 } /* for (all uniform locations) */ 2943 2944 return result; 2945 } 2946 2947 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or 2948 * glUniform*dv() functions is used to load an uniform, size of which is incompatible 2949 * with the function. 2950 * 2951 * @return true if the implementation was found to behave as expected, false otherwise. 2952 **/ 2953 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingSizeMismatchedUniformFunctions() 2954 { 2955 const double double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; 2956 glw::GLenum error_code = GL_NO_ERROR; 2957 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2958 bool result = true; 2959 2960 const int data[] = { 2961 /* API function */ /* Uniform location */ /* Count (dv functions only) */ 2962 (int)UNIFORM_FUNCTION_2D, m_po_double_uniform_location, 0, (int)UNIFORM_FUNCTION_2DV, 2963 m_po_double_uniform_location, 2, (int)UNIFORM_FUNCTION_3D, m_po_double_uniform_location, 0, 2964 (int)UNIFORM_FUNCTION_3DV, m_po_double_uniform_location, 2, (int)UNIFORM_FUNCTION_4D, 2965 m_po_double_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_double_uniform_location, 2, 2966 (int)UNIFORM_FUNCTION_1D, m_po_dvec2_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV, 2967 m_po_dvec2_uniform_location, 2, (int)UNIFORM_FUNCTION_3D, m_po_dvec2_uniform_location, 0, 2968 (int)UNIFORM_FUNCTION_3DV, m_po_dvec2_uniform_location, 2, (int)UNIFORM_FUNCTION_4D, 2969 m_po_dvec2_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_dvec2_uniform_location, 2, 2970 (int)UNIFORM_FUNCTION_1D, m_po_dvec3_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV, 2971 m_po_dvec3_uniform_location, 2, (int)UNIFORM_FUNCTION_2D, m_po_dvec3_uniform_location, 0, 2972 (int)UNIFORM_FUNCTION_2DV, m_po_dvec3_uniform_location, 2, (int)UNIFORM_FUNCTION_4D, 2973 m_po_dvec3_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_dvec3_uniform_location, 2, 2974 (int)UNIFORM_FUNCTION_1D, m_po_dvec4_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV, 2975 m_po_dvec4_uniform_location, 2, (int)UNIFORM_FUNCTION_2D, m_po_dvec4_uniform_location, 0, 2976 (int)UNIFORM_FUNCTION_2DV, m_po_dvec4_uniform_location, 2, (int)UNIFORM_FUNCTION_3D, 2977 m_po_dvec4_uniform_location, 0, (int)UNIFORM_FUNCTION_3DV, m_po_dvec4_uniform_location, 2, 2978 }; 2979 const unsigned int n_checks = sizeof(data) / sizeof(data[0]) / 3 /* entries per row */; 2980 2981 gl.useProgram(m_po_id); 2982 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 2983 2984 for (unsigned int n_check = 0; n_check < n_checks; ++n_check) 2985 { 2986 _uniform_function function = (_uniform_function)data[n_check * 3 + 0]; 2987 int uniform_location = data[n_check * 3 + 1]; 2988 int uniform_count = data[n_check * 3 + 2]; 2989 2990 switch (function) 2991 { 2992 case UNIFORM_FUNCTION_1D: 2993 gl.uniform1d(uniform_location, 0.0); 2994 break; 2995 case UNIFORM_FUNCTION_1DV: 2996 gl.uniform1dv(uniform_location, uniform_count, double_data); 2997 break; 2998 case UNIFORM_FUNCTION_2D: 2999 gl.uniform2d(uniform_location, 0.0, 1.0); 3000 break; 3001 case UNIFORM_FUNCTION_2DV: 3002 gl.uniform2dv(uniform_location, uniform_count, double_data); 3003 break; 3004 case UNIFORM_FUNCTION_3D: 3005 gl.uniform3d(uniform_location, 0.0, 1.0, 2.0); 3006 break; 3007 case UNIFORM_FUNCTION_3DV: 3008 gl.uniform3dv(uniform_location, uniform_count, double_data); 3009 break; 3010 case UNIFORM_FUNCTION_4D: 3011 gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0); 3012 break; 3013 case UNIFORM_FUNCTION_4DV: 3014 gl.uniform4dv(uniform_location, uniform_count, double_data); 3015 break; 3016 3017 default: 3018 { 3019 DE_ASSERT(false); 3020 } 3021 } /* switch (function) */ 3022 3023 error_code = gl.getError(); 3024 if (error_code != GL_INVALID_OPERATION) 3025 { 3026 m_testCtx.getLog() << tcu::TestLog::Message << getUniformFunctionString(function) 3027 << "() function did not generate GL_INVALID_OPERATION error when called for" 3028 " a uniform of incompatible size. (check index: " 3029 << n_check << ")" << tcu::TestLog::EndMessage; 3030 3031 result = false; 3032 } 3033 } /* for (all checks) */ 3034 3035 return result; 3036 } 3037 3038 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or 3039 * glUniform*dv() functions is used to load an uniform, type of which is incompatible 3040 * with the function. 3041 * 3042 * @return true if the implementation was found to behave as expected, false otherwise. 3043 **/ 3044 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingTypeMismatchedUniformFunctions() 3045 { 3046 const double double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; 3047 glw::GLenum error_code = GL_NO_ERROR; 3048 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3049 bool result = true; 3050 3051 const glw::GLint nondouble_uniform_locations[] = { m_po_bool_uniform_location, m_po_bvec2_uniform_location, 3052 m_po_bvec3_uniform_location, m_po_bvec4_uniform_location, 3053 m_po_float_uniform_location, m_po_int_uniform_location, 3054 m_po_ivec2_uniform_location, m_po_ivec3_uniform_location, 3055 m_po_ivec4_uniform_location, m_po_uint_uniform_location, 3056 m_po_uvec2_uniform_location, m_po_uvec3_uniform_location, 3057 m_po_uvec4_uniform_location, m_po_vec2_uniform_location, 3058 m_po_vec3_uniform_location, m_po_vec4_uniform_location }; 3059 const unsigned int n_nondouble_uniform_locations = 3060 sizeof(nondouble_uniform_locations) / sizeof(nondouble_uniform_locations[0]); 3061 3062 gl.useProgram(m_po_id); 3063 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 3064 3065 for (unsigned int n_uniform_location = 0; n_uniform_location < n_nondouble_uniform_locations; ++n_uniform_location) 3066 { 3067 glw::GLint uniform_location = nondouble_uniform_locations[n_uniform_location]; 3068 3069 for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST); 3070 function < static_cast<int>(UNIFORM_FUNCTION_COUNT); ++function) 3071 { 3072 switch (static_cast<_uniform_function>(function)) 3073 { 3074 case UNIFORM_FUNCTION_1D: 3075 gl.uniform1d(uniform_location, 0.0); 3076 break; 3077 case UNIFORM_FUNCTION_1DV: 3078 gl.uniform1dv(uniform_location, 1, double_data); 3079 break; 3080 case UNIFORM_FUNCTION_2D: 3081 gl.uniform2d(uniform_location, 0.0, 1.0); 3082 break; 3083 case UNIFORM_FUNCTION_2DV: 3084 gl.uniform2dv(uniform_location, 1, double_data); 3085 break; 3086 case UNIFORM_FUNCTION_3D: 3087 gl.uniform3d(uniform_location, 0.0, 1.0, 2.0); 3088 break; 3089 case UNIFORM_FUNCTION_3DV: 3090 gl.uniform3dv(uniform_location, 1, double_data); 3091 break; 3092 case UNIFORM_FUNCTION_4D: 3093 gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0); 3094 break; 3095 case UNIFORM_FUNCTION_4DV: 3096 gl.uniform4dv(uniform_location, 1, double_data); 3097 break; 3098 3099 case UNIFORM_FUNCTION_MATRIX2DV: 3100 gl.uniformMatrix2dv(uniform_location, 1, GL_FALSE, double_data); 3101 break; 3102 case UNIFORM_FUNCTION_MATRIX2X3DV: 3103 gl.uniformMatrix2x3dv(uniform_location, 1, GL_FALSE, double_data); 3104 break; 3105 case UNIFORM_FUNCTION_MATRIX2X4DV: 3106 gl.uniformMatrix2x4dv(uniform_location, 1, GL_FALSE, double_data); 3107 break; 3108 case UNIFORM_FUNCTION_MATRIX3DV: 3109 gl.uniformMatrix3dv(uniform_location, 1, GL_FALSE, double_data); 3110 break; 3111 case UNIFORM_FUNCTION_MATRIX3X2DV: 3112 gl.uniformMatrix3x2dv(uniform_location, 1, GL_FALSE, double_data); 3113 break; 3114 case UNIFORM_FUNCTION_MATRIX3X4DV: 3115 gl.uniformMatrix3x4dv(uniform_location, 1, GL_FALSE, double_data); 3116 break; 3117 case UNIFORM_FUNCTION_MATRIX4DV: 3118 gl.uniformMatrix4dv(uniform_location, 1, GL_FALSE, double_data); 3119 break; 3120 case UNIFORM_FUNCTION_MATRIX4X2DV: 3121 gl.uniformMatrix4x2dv(uniform_location, 1, GL_FALSE, double_data); 3122 break; 3123 case UNIFORM_FUNCTION_MATRIX4X3DV: 3124 gl.uniformMatrix4x3dv(uniform_location, 1, GL_FALSE, double_data); 3125 break; 3126 3127 default: 3128 { 3129 DE_ASSERT(false); 3130 } 3131 } /* switch (function) */ 3132 3133 error_code = gl.getError(); 3134 if (error_code != GL_INVALID_OPERATION) 3135 { 3136 m_testCtx.getLog() << tcu::TestLog::Message 3137 << getUniformFunctionString(static_cast<_uniform_function>(function)) 3138 << "() function did not generate GL_INVALID_OPERATION error when called for" 3139 " a uniform of incompatible type." 3140 << tcu::TestLog::EndMessage; 3141 3142 result = false; 3143 } 3144 } 3145 } /* for (all checks) */ 3146 3147 return result; 3148 } 3149 3150 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or 3151 * glUniform*dv() functions are called without a bound program object. 3152 * 3153 * @return true if the implementation was found to behave as expected, false otherwise. 3154 **/ 3155 bool GPUShaderFP64Test1::verifyErrorGenerationWhenUniformFunctionsCalledWithoutActivePO() 3156 { 3157 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3158 bool result = true; 3159 3160 for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST); function < static_cast<int>(UNIFORM_FUNCTION_COUNT); 3161 function++) 3162 { 3163 const double data[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0 }; 3164 3165 switch (static_cast<_uniform_function>(function)) 3166 { 3167 case UNIFORM_FUNCTION_1D: 3168 gl.uniform1d(m_po_double_uniform_location, 0.0); 3169 break; 3170 case UNIFORM_FUNCTION_1DV: 3171 gl.uniform1dv(m_po_double_uniform_location, 1, data); 3172 break; 3173 case UNIFORM_FUNCTION_2D: 3174 gl.uniform2d(m_po_dvec2_uniform_location, 0.0, 1.0); 3175 break; 3176 case UNIFORM_FUNCTION_2DV: 3177 gl.uniform2dv(m_po_dvec2_uniform_location, 1, data); 3178 break; 3179 case UNIFORM_FUNCTION_3D: 3180 gl.uniform3d(m_po_dvec3_uniform_location, 0.0, 1.0, 2.0); 3181 break; 3182 case UNIFORM_FUNCTION_3DV: 3183 gl.uniform3dv(m_po_dvec3_uniform_location, 1, data); 3184 break; 3185 case UNIFORM_FUNCTION_4D: 3186 gl.uniform4d(m_po_dvec4_uniform_location, 0.0, 1.0, 2.0, 3.0); 3187 break; 3188 case UNIFORM_FUNCTION_4DV: 3189 gl.uniform4dv(m_po_dvec4_uniform_location, 1, data); 3190 break; 3191 3192 case UNIFORM_FUNCTION_MATRIX2DV: 3193 gl.uniformMatrix2dv(m_po_dmat2_uniform_location, 1, GL_FALSE /* transpose */, data); 3194 break; 3195 case UNIFORM_FUNCTION_MATRIX2X3DV: 3196 gl.uniformMatrix2x3dv(m_po_dmat2x3_uniform_location, 1, GL_FALSE /* transpose */, data); 3197 break; 3198 case UNIFORM_FUNCTION_MATRIX2X4DV: 3199 gl.uniformMatrix2x4dv(m_po_dmat2x4_uniform_location, 1, GL_FALSE /* transpose */, data); 3200 break; 3201 case UNIFORM_FUNCTION_MATRIX3DV: 3202 gl.uniformMatrix3dv(m_po_dmat3_uniform_location, 1, GL_FALSE /* transpose */, data); 3203 break; 3204 case UNIFORM_FUNCTION_MATRIX3X2DV: 3205 gl.uniformMatrix3x2dv(m_po_dmat3x2_uniform_location, 1, GL_FALSE /* transpose */, data); 3206 break; 3207 case UNIFORM_FUNCTION_MATRIX3X4DV: 3208 gl.uniformMatrix3x4dv(m_po_dmat3x4_uniform_location, 1, GL_FALSE /* transpose */, data); 3209 break; 3210 case UNIFORM_FUNCTION_MATRIX4DV: 3211 gl.uniformMatrix4dv(m_po_dmat4_uniform_location, 1, GL_FALSE /* transpose */, data); 3212 break; 3213 case UNIFORM_FUNCTION_MATRIX4X2DV: 3214 gl.uniformMatrix4x2dv(m_po_dmat4x2_uniform_location, 1, GL_FALSE /* transpose */, data); 3215 break; 3216 case UNIFORM_FUNCTION_MATRIX4X3DV: 3217 gl.uniformMatrix4x3dv(m_po_dmat4x3_uniform_location, 1, GL_FALSE /* transpose */, data); 3218 break; 3219 3220 default: 3221 { 3222 TCU_FAIL("Unrecognized uniform function"); 3223 } 3224 } /* switch (func) */ 3225 3226 /* Query the error code */ 3227 glw::GLenum error_code = gl.getError(); 3228 3229 if (error_code != GL_INVALID_OPERATION) 3230 { 3231 m_testCtx.getLog() << tcu::TestLog::Message << "Implementation did not return GL_INVALID_OPERATION when " 3232 << getUniformFunctionString(static_cast<_uniform_function>(function)) 3233 << "() was called without an active program object" << tcu::TestLog::EndMessage; 3234 3235 result = false; 3236 } 3237 } /* for (all uniform functions) */ 3238 3239 return result; 3240 } 3241 3242 /* Defeinitions of static const symbols declared in GPUShaderFP64Test2 */ 3243 const glw::GLuint GPUShaderFP64Test2::m_n_captured_results = 1024; 3244 const glw::GLint GPUShaderFP64Test2::m_result_failure = 2; 3245 const glw::GLint GPUShaderFP64Test2::m_result_success = 1; 3246 const glw::GLuint GPUShaderFP64Test2::m_texture_width = 32; 3247 const glw::GLuint GPUShaderFP64Test2::m_texture_height = m_n_captured_results / m_texture_width; 3248 const glw::GLuint GPUShaderFP64Test2::m_transform_feedback_buffer_size = 3249 m_n_captured_results * sizeof(captured_varying_type); 3250 const glw::GLchar* GPUShaderFP64Test2::m_uniform_block_name = "UniformBlock"; 3251 const glw::GLenum GPUShaderFP64Test2::ARB_MAX_COMPUTE_UNIFORM_COMPONENTS = 0x8263; 3252 3253 /** Constructor 3254 * 3255 * @param context Test context 3256 **/ 3257 GPUShaderFP64Test2::GPUShaderFP64Test2(deqp::Context& context) 3258 : TestCase(context, "max_uniform_components", 3259 "Verifies that maximum allowed uniform components can be used as double-precision float types") 3260 , m_pDispatchCompute(0) 3261 , m_framebuffer_id(0) 3262 , m_texture_id(0) 3263 , m_transform_feedback_buffer_id(0) 3264 , m_uniform_buffer_id(0) 3265 , m_vertex_array_object_id(0) 3266 { 3267 /* Nothing to be done */ 3268 } 3269 3270 /** Deinitialize test 3271 * 3272 **/ 3273 void GPUShaderFP64Test2::deinit() 3274 { 3275 /* GL entry points */ 3276 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3277 3278 /* Clean frambuffer */ 3279 if (0 != m_framebuffer_id) 3280 { 3281 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 3282 gl.deleteFramebuffers(1, &m_framebuffer_id); 3283 m_framebuffer_id = 0; 3284 } 3285 3286 /* Clean texture */ 3287 if (0 != m_texture_id) 3288 { 3289 gl.bindTexture(GL_TEXTURE_2D, 0); 3290 gl.bindImageTexture(0 /* unit */, 0 /* texture */, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */, 3291 GL_READ_ONLY, GL_RGBA8); 3292 gl.deleteTextures(1, &m_texture_id); 3293 m_texture_id = 0; 3294 } 3295 3296 /* Clean buffers */ 3297 if (0 != m_transform_feedback_buffer_id) 3298 { 3299 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); 3300 gl.deleteBuffers(1, &m_transform_feedback_buffer_id); 3301 m_transform_feedback_buffer_id = 0; 3302 } 3303 3304 if (0 != m_uniform_buffer_id) 3305 { 3306 gl.bindBuffer(GL_UNIFORM_BUFFER, 0); 3307 gl.deleteBuffers(1, &m_uniform_buffer_id); 3308 m_uniform_buffer_id = 0; 3309 } 3310 3311 /* Clean VAO */ 3312 if (0 != m_vertex_array_object_id) 3313 { 3314 gl.bindVertexArray(0); 3315 gl.deleteVertexArrays(1, &m_vertex_array_object_id); 3316 m_vertex_array_object_id = 0; 3317 } 3318 } 3319 3320 /** Execute test 3321 * 3322 * @return tcu::TestNode::STOP 3323 **/ 3324 tcu::TestNode::IterateResult GPUShaderFP64Test2::iterate() 3325 { 3326 bool result = true; 3327 3328 /* Check if extension is supported */ 3329 if (false == m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64")) 3330 { 3331 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported"); 3332 } 3333 3334 /* Initialize test */ 3335 testInit(); 3336 3337 prepareShaderStages(); 3338 prepareUniformTypes(); 3339 3340 /* For all shaders and uniform type combinations */ 3341 for (std::vector<shaderStage>::const_iterator shader_stage = m_shader_stages.begin(); 3342 m_shader_stages.end() != shader_stage; ++shader_stage) 3343 { 3344 for (std::vector<uniformTypeDetails>::const_iterator uniform_type = m_uniform_types.begin(); 3345 m_uniform_types.end() != uniform_type; ++uniform_type) 3346 { 3347 /* Execute test */ 3348 if (false == test(*shader_stage, *uniform_type)) 3349 { 3350 result = false; 3351 } 3352 } 3353 } 3354 3355 /* Set result */ 3356 if (true == result) 3357 { 3358 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3359 } 3360 else 3361 { 3362 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3363 } 3364 3365 /* Done */ 3366 return tcu::TestNode::STOP; 3367 } 3368 3369 /** Constructor 3370 * 3371 * @param n_columns Number of columns 3372 * @param n_rows Number of rows 3373 **/ 3374 GPUShaderFP64Test2::uniformTypeDetails::uniformTypeDetails(glw::GLuint n_columns, glw::GLuint n_rows) 3375 : m_n_columns(n_columns), m_n_rows(n_rows) 3376 { 3377 Utils::_variable_type type = Utils::getDoubleVariableType(n_columns, n_rows); 3378 3379 m_type_name = Utils::getVariableTypeString(type); 3380 m_type = Utils::getGLDataTypeOfVariableType(type); 3381 } 3382 3383 /** Get primitive type captured with transform feedback 3384 * 3385 * @param shader_stage Tested shader stage id 3386 * 3387 * @return Primitive type 3388 **/ 3389 glw::GLenum GPUShaderFP64Test2::getCapturedPrimitiveType(shaderStage shader_stage) const 3390 { 3391 switch (shader_stage) 3392 { 3393 case GEOMETRY_SHADER: 3394 case TESS_CTRL_SHADER: 3395 case TESS_EVAL_SHADER: 3396 case VERTEX_SHADER: 3397 return GL_POINTS; 3398 break; 3399 3400 default: 3401 return GL_NONE; 3402 break; 3403 } 3404 } 3405 3406 /** Get primitive type drawn with DrawArrays 3407 * 3408 * @param shader_stage Tested shader stage id 3409 * 3410 * @return Primitive type 3411 **/ 3412 glw::GLenum GPUShaderFP64Test2::getDrawPrimitiveType(shaderStage shader_stage) const 3413 { 3414 switch (shader_stage) 3415 { 3416 case FRAGMENT_SHADER: 3417 return GL_TRIANGLE_FAN; 3418 break; 3419 3420 case GEOMETRY_SHADER: 3421 case VERTEX_SHADER: 3422 return GL_POINTS; 3423 break; 3424 3425 case TESS_CTRL_SHADER: 3426 case TESS_EVAL_SHADER: 3427 return GL_PATCHES; 3428 break; 3429 3430 default: 3431 return GL_NONE; 3432 break; 3433 } 3434 } 3435 3436 /** Get maximum allowed number of uniform components 3437 * 3438 * @param shader_stage Tested shader stage id 3439 * 3440 * @return Maxmimum uniform components 3441 **/ 3442 glw::GLuint GPUShaderFP64Test2::getMaxUniformComponents(shaderStage shader_stage) const 3443 { 3444 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3445 glw::GLint max_uniform_components = 0; 3446 glw::GLenum pname = 0; 3447 3448 switch (shader_stage) 3449 { 3450 case COMPUTE_SHADER: 3451 pname = ARB_MAX_COMPUTE_UNIFORM_COMPONENTS; 3452 break; 3453 case FRAGMENT_SHADER: 3454 pname = GL_MAX_FRAGMENT_UNIFORM_COMPONENTS; 3455 break; 3456 case GEOMETRY_SHADER: 3457 pname = GL_MAX_GEOMETRY_UNIFORM_COMPONENTS; 3458 break; 3459 case TESS_CTRL_SHADER: 3460 pname = GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS; 3461 break; 3462 case TESS_EVAL_SHADER: 3463 pname = GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS; 3464 break; 3465 case VERTEX_SHADER: 3466 pname = GL_MAX_VERTEX_UNIFORM_COMPONENTS; 3467 break; 3468 } 3469 3470 gl.getIntegerv(pname, &max_uniform_components); 3471 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 3472 3473 return max_uniform_components; 3474 } 3475 3476 /** Get maximum size allowed for an uniform block 3477 * 3478 * @return Maxmimum uniform block size 3479 **/ 3480 glw::GLuint GPUShaderFP64Test2::getMaxUniformBlockSize() const 3481 { 3482 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3483 glw::GLint max_uniform_block_size = 0; 3484 3485 gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_uniform_block_size); 3486 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 3487 3488 return max_uniform_block_size; 3489 } 3490 3491 /** Get number of components required to store single uniform of given type 3492 * 3493 * @param uniform_type Tested uniform type 3494 * 3495 * @return Number of components 3496 **/ 3497 glw::GLuint GPUShaderFP64Test2::getRequiredComponentsNumber(const uniformTypeDetails& uniform_type) const 3498 { 3499 static const glw::GLuint type_size = 2; /* double takes 2 N */ 3500 const glw::GLuint column_length = uniform_type.m_n_rows; 3501 3502 if (1 == uniform_type.m_n_columns) 3503 { 3504 return type_size * column_length; 3505 } 3506 else 3507 { 3508 const glw::GLuint alignment = type_size * ((3 == column_length) ? 4 : column_length); 3509 3510 return alignment * uniform_type.m_n_columns; 3511 } 3512 } 3513 3514 /** Get size used for each member of a uniform array of a given type in a std140 column-major layout 3515 * 3516 * @param uniform_type Tested uniform type 3517 * 3518 * @return Size of a single member 3519 **/ 3520 glw::GLuint GPUShaderFP64Test2::getUniformTypeMemberSize(const uniformTypeDetails& uniform_type) const 3521 { 3522 static const glw::GLuint vec4_size = 4 * Utils::getBaseVariableTypeComponentSize(Utils::VARIABLE_TYPE_FLOAT); 3523 const glw::GLuint column_length = uniform_type.m_n_rows; 3524 3525 /** Size for a layout(std140, column_major) uniform_type uniform[] **/ 3526 return vec4_size * ((column_length + 1) / 2) * uniform_type.m_n_columns; 3527 } 3528 3529 /** Get the maximum amount of uniforms to be used in a shader stage for a given type 3530 * 3531 * @param shader_stage Tested shader stage id 3532 * @param uniform_type Tested uniform type 3533 * 3534 * @return Number of components 3535 **/ 3536 glw::GLuint GPUShaderFP64Test2::getAmountUniforms(shaderStage shader_stage, 3537 const uniformTypeDetails& uniform_type) const 3538 { 3539 const glw::GLuint max_uniform_components = getMaxUniformComponents(shader_stage); 3540 const glw::GLuint required_components = getRequiredComponentsNumber(uniform_type); 3541 const glw::GLuint n_uniforms = max_uniform_components / required_components; 3542 const glw::GLuint max_uniform_block_size = getMaxUniformBlockSize(); 3543 const glw::GLuint uniform_type_member_size = getUniformTypeMemberSize(uniform_type); 3544 const glw::GLuint max_uniforms = max_uniform_block_size / uniform_type_member_size; 3545 3546 return max_uniforms < n_uniforms ? max_uniforms : n_uniforms; 3547 } 3548 3549 /** Get name of shader stage 3550 * 3551 * @param shader_stage Tested shader stage id 3552 * 3553 * @return Name 3554 **/ 3555 const glw::GLchar* GPUShaderFP64Test2::getShaderStageName(shaderStage shader_stage) const 3556 { 3557 switch (shader_stage) 3558 { 3559 case COMPUTE_SHADER: 3560 return "compute shader"; 3561 break; 3562 case FRAGMENT_SHADER: 3563 return "fragment shader"; 3564 break; 3565 case GEOMETRY_SHADER: 3566 return "geometry shader"; 3567 break; 3568 case TESS_CTRL_SHADER: 3569 return "tesselation control shader"; 3570 break; 3571 case TESS_EVAL_SHADER: 3572 return "tesselation evaluation shader"; 3573 break; 3574 case VERTEX_SHADER: 3575 return "vertex shader"; 3576 break; 3577 } 3578 3579 return 0; 3580 } 3581 3582 /** Inspect program to get: buffer_size, offset, strides and block index 3583 * 3584 * @param program_id Program id 3585 * @param out_buffer_size Size of uniform buffer 3586 * @param out_uniform_details Uniform offset and strides 3587 * @param uniform_block_index Uniform block index 3588 **/ 3589 void GPUShaderFP64Test2::inspectProgram(glw::GLuint program_id, glw::GLint n_uniforms, 3590 const uniformTypeDetails& uniform_type, glw::GLint& out_buffer_size, 3591 uniformDetails& out_uniform_details, glw::GLuint uniform_block_index) const 3592 { 3593 glw::GLint array_stride = 0; 3594 std::vector<glw::GLchar> extracted_uniform_name; 3595 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3596 glw::GLuint index = 0; 3597 glw::GLint matrix_stride = 0; 3598 glw::GLint offset = 0; 3599 glw::GLsizei size = 0; 3600 glw::GLenum type = 0; 3601 const glw::GLchar* uniform_name = 0; 3602 std::string uniform_name_str; 3603 std::stringstream uniform_name_stream; 3604 3605 /* Get index of uniform block */ 3606 uniform_block_index = gl.getUniformBlockIndex(program_id, m_uniform_block_name); 3607 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformBlockIndex"); 3608 3609 if (GL_INVALID_INDEX == uniform_block_index) 3610 { 3611 TCU_FAIL("Unifom block is inactive"); 3612 } 3613 3614 /* Get size of uniform block */ 3615 gl.getActiveUniformBlockiv(program_id, uniform_block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &out_buffer_size); 3616 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformBlockiv"); 3617 3618 if (0 == out_buffer_size) 3619 { 3620 TCU_FAIL("Unifom block size is 0"); 3621 } 3622 3623 /* Prepare uniform name */ 3624 uniform_name_stream << "uniform_array"; 3625 3626 uniform_name_str = uniform_name_stream.str(); 3627 uniform_name = uniform_name_str.c_str(); 3628 3629 /* Get index of uniform */ 3630 gl.getUniformIndices(program_id, 1 /* count */, &uniform_name, &index); 3631 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices"); 3632 3633 if (GL_INVALID_INDEX == index) 3634 { 3635 TCU_FAIL("Unifom is inactive"); 3636 } 3637 3638 /* Verify getActiveUniform results */ 3639 extracted_uniform_name.resize(uniform_name_str.length() * 2); 3640 3641 gl.getActiveUniform(program_id, index, (glw::GLsizei)(uniform_name_str.length() * 2) /* bufSize */, 0, &size, &type, 3642 &extracted_uniform_name[0]); 3643 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniform"); 3644 3645 if ((n_uniforms != size) || (uniform_type.m_type != type)) 3646 { 3647 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid GetActiveUniform results." 3648 << " Size: " << size << " expected: " << n_uniforms << ". Type: " << type 3649 << " expected: " << uniform_type.m_type 3650 << ". Name: " << &extracted_uniform_name[0] << tcu::TestLog::EndMessage; 3651 3652 TCU_FAIL("Invalid GetActiveUniform results"); 3653 } 3654 3655 /* Get offset of uniform */ 3656 gl.getActiveUniformsiv(program_id, 1 /* count */, &index, GL_UNIFORM_OFFSET, &offset); 3657 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv"); 3658 3659 if (-1 == offset) 3660 { 3661 TCU_FAIL("Unifom has invalid offset"); 3662 } 3663 3664 out_uniform_details.m_offset = offset; 3665 3666 /* Get matrix stride of uniform */ 3667 gl.getActiveUniformsiv(program_id, 1 /* count */, &index, GL_UNIFORM_MATRIX_STRIDE, &matrix_stride); 3668 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv"); 3669 3670 if (-1 == matrix_stride) 3671 { 3672 TCU_FAIL("Unifom has invalid matrix stride"); 3673 } 3674 3675 out_uniform_details.m_matrix_stride = matrix_stride; 3676 3677 /* Get array stride of uniform */ 3678 gl.getActiveUniformsiv(program_id, 1 /* count */, &index, GL_UNIFORM_ARRAY_STRIDE, &array_stride); 3679 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv"); 3680 3681 if (-1 == matrix_stride) 3682 { 3683 TCU_FAIL("Unifom has invalid matrix stride"); 3684 } 3685 3686 out_uniform_details.m_array_stride = array_stride; 3687 } 3688 3689 /** Prepare source code for "boilerplate" shaders 3690 * 3691 * @param stage_specific_layout String that will replace STAGE_SPECIFIC_LAYOUT token 3692 * @param stage_specific_main_body String that will replace STAGE_SPECIFIC_MAIN_BODY token 3693 * @param out_source_code Source code 3694 **/ 3695 void GPUShaderFP64Test2::prepareBoilerplateShader(const glw::GLchar* stage_specific_layout, 3696 const glw::GLchar* stage_specific_main_body, 3697 std::string& out_source_code) const 3698 { 3699 /* Shader template */ 3700 static const glw::GLchar* boilerplate_shader_template_code = "#version 400 core\n" 3701 "\n" 3702 "precision highp float;\n" 3703 "\n" 3704 "STAGE_SPECIFIC_LAYOUT" 3705 "void main()\n" 3706 "{\n" 3707 "STAGE_SPECIFIC_MAIN_BODY" 3708 "}\n" 3709 "\n"; 3710 3711 std::string string = boilerplate_shader_template_code; 3712 3713 /* Tokens */ 3714 static const glw::GLchar* body_token = "STAGE_SPECIFIC_MAIN_BODY"; 3715 static const glw::GLchar* layout_token = "STAGE_SPECIFIC_LAYOUT"; 3716 3717 size_t search_position = 0; 3718 3719 /* Replace tokens */ 3720 Utils::replaceToken(layout_token, search_position, stage_specific_layout, string); 3721 Utils::replaceToken(body_token, search_position, stage_specific_main_body, string); 3722 3723 /* Store resuls */ 3724 out_source_code = string; 3725 } 3726 3727 /** Prepare program for given combination of shader stage and uniform type 3728 * 3729 * @param shader_stage Shader stage 3730 * @param uniform_type Uniform type 3731 * @param out_program_info Instance of programInfo 3732 **/ 3733 void GPUShaderFP64Test2::prepareProgram(shaderStage shader_stage, const uniformTypeDetails& uniform_type, 3734 Utils::programInfo& out_program_info) const 3735 { 3736 /* Stage specific layouts */ 3737 static const glw::GLchar* geometry_shader_layout_code = "layout(points) in;\n" 3738 "layout(points, max_vertices = 1) out;\n" 3739 "\n"; 3740 3741 static const glw::GLchar* tess_ctrl_shader_layout_code = "layout(vertices = 1) out;\n" 3742 "\n"; 3743 3744 static const glw::GLchar* tess_eval_shader_layout_code = "layout(isolines, point_mode) in;\n" 3745 "\n"; 3746 3747 /* Stage specific main body */ 3748 static const glw::GLchar* boilerplate_fragment_shader_body_code = " discard;\n"; 3749 3750 static const glw::GLchar* boilerplate_tess_ctrl_shader_body_code = " gl_TessLevelOuter[0] = 1.0;\n" 3751 " gl_TessLevelOuter[1] = 1.0;\n" 3752 " gl_TessLevelOuter[2] = 1.0;\n" 3753 " gl_TessLevelOuter[3] = 1.0;\n" 3754 " gl_TessLevelInner[0] = 1.0;\n" 3755 " gl_TessLevelInner[1] = 1.0;\n"; 3756 3757 static const glw::GLchar* boilerplate_vertex_shader_body_code = " gl_Position = vec4(1, 0, 0, 1);\n"; 3758 3759 static const glw::GLchar* corner_vertex_shader_body_code = " if (0 == gl_VertexID)\n" 3760 " {\n" 3761 " gl_Position = vec4(-1, -1, 0, 1);\n" 3762 " }\n" 3763 " else if (1 == gl_VertexID)\n" 3764 " {\n" 3765 " gl_Position = vec4(-1, 1, 0, 1);\n" 3766 " }\n" 3767 " else if (2 == gl_VertexID)\n" 3768 " {\n" 3769 " gl_Position = vec4(1, 1, 0, 1);\n" 3770 " }\n" 3771 " else if (3 == gl_VertexID)\n" 3772 " {\n" 3773 " gl_Position = vec4(1, -1, 0, 1);\n" 3774 " }\n"; 3775 3776 static const glw::GLchar* passthrough_tess_eval_shader_body_code = " result = tcs_tes_result[0];\n"; 3777 3778 static const glw::GLchar* test_shader_body_code = "\n result = verification_result;\n"; 3779 3780 static const glw::GLchar* test_geometry_shader_body_code = "\n result = verification_result;\n" 3781 "\n" 3782 " EmitVertex();\n" 3783 " EndPrimitive();\n"; 3784 3785 static const glw::GLchar* test_tess_ctrl_shader_body_code = 3786 "\n tcs_tes_result[gl_InvocationID] = verification_result;\n" 3787 "\n" 3788 " gl_TessLevelOuter[0] = 1.0;\n" 3789 " gl_TessLevelOuter[1] = 1.0;\n" 3790 " gl_TessLevelOuter[2] = 1.0;\n" 3791 " gl_TessLevelOuter[3] = 1.0;\n" 3792 " gl_TessLevelInner[0] = 1.0;\n" 3793 " gl_TessLevelInner[1] = 1.0;\n"; 3794 3795 /* In variables */ 3796 static const glw::GLchar* test_tess_ctrl_shader_in_variable = "in int tcs_tes_result[];\n"; 3797 3798 /* Out variables */ 3799 static const glw::GLchar* test_fragment_shader_out_variable = "layout(location = 0) out int result;\n"; 3800 3801 static const glw::GLchar* test_tess_ctrl_shader_out_variable = "out int tcs_tes_result[];\n"; 3802 3803 static const glw::GLchar* test_shader_out_variable = "out int result;\n"; 3804 3805 /* Varying name */ 3806 static const glw::GLchar* varying_name = "result"; 3807 glw::GLuint n_varyings = 1; 3808 3809 /* Storage for ready shaders */ 3810 std::string compute_shader_code; 3811 std::string fragment_shader_code; 3812 std::string geometry_shader_code; 3813 std::string tess_ctrl_shader_code; 3814 std::string tess_eval_shader_code; 3815 std::string vertex_shader_code; 3816 3817 /* Storage for uniform definition and verification code */ 3818 std::string uniform_definitions; 3819 std::string uniform_verification; 3820 3821 /* Get uniform definition and verification code */ 3822 prepareUniformDefinitions(shader_stage, uniform_type, uniform_definitions); 3823 prepareUniformVerification(shader_stage, uniform_type, uniform_verification); 3824 3825 /* Prepare vertex shader */ 3826 switch (shader_stage) 3827 { 3828 case FRAGMENT_SHADER: 3829 3830 prepareBoilerplateShader("", corner_vertex_shader_body_code, vertex_shader_code); 3831 3832 break; 3833 3834 case GEOMETRY_SHADER: 3835 case TESS_CTRL_SHADER: 3836 case TESS_EVAL_SHADER: 3837 3838 prepareBoilerplateShader("", boilerplate_vertex_shader_body_code, vertex_shader_code); 3839 3840 break; 3841 3842 case VERTEX_SHADER: 3843 3844 prepareTestShader("" /* layout */, uniform_definitions.c_str() /* uniforms */, "" /* in var */, 3845 test_shader_out_variable /* out var */, uniform_verification.c_str() /* verification */, 3846 test_shader_body_code /* body */, vertex_shader_code); 3847 3848 break; 3849 3850 default: 3851 break; 3852 } 3853 3854 /* Prepare fragment shader */ 3855 switch (shader_stage) 3856 { 3857 case FRAGMENT_SHADER: 3858 3859 prepareTestShader("" /* layout */, uniform_definitions.c_str() /* uniforms */, "" /* in var */, 3860 test_fragment_shader_out_variable /* out var */, 3861 uniform_verification.c_str() /* verification */, test_shader_body_code /* body */, 3862 fragment_shader_code); 3863 3864 break; 3865 3866 case GEOMETRY_SHADER: 3867 case TESS_CTRL_SHADER: 3868 case TESS_EVAL_SHADER: 3869 case VERTEX_SHADER: 3870 3871 prepareBoilerplateShader("" /* layout */, boilerplate_fragment_shader_body_code /* body */, 3872 fragment_shader_code); 3873 3874 break; 3875 3876 default: 3877 break; 3878 } 3879 3880 /* Prepare compute, tess_ctrl, tess_eval, geometry shaders */ 3881 switch (shader_stage) 3882 { 3883 case COMPUTE_SHADER: 3884 3885 prepareTestComputeShader(uniform_definitions.c_str(), uniform_verification.c_str(), compute_shader_code); 3886 3887 break; 3888 3889 case GEOMETRY_SHADER: 3890 3891 prepareTestShader(geometry_shader_layout_code /* layout */, uniform_definitions.c_str() /* uniforms */, 3892 "" /* in var */, test_shader_out_variable /* out var */, 3893 uniform_verification.c_str() /* verification */, test_geometry_shader_body_code /* body */, 3894 geometry_shader_code); 3895 3896 break; 3897 3898 case TESS_CTRL_SHADER: 3899 3900 prepareTestShader(tess_ctrl_shader_layout_code /* layout */, uniform_definitions.c_str() /* uniforms */, 3901 "" /* in var */, test_tess_ctrl_shader_out_variable /* out var */, 3902 uniform_verification.c_str() /* verification */, test_tess_ctrl_shader_body_code /* body */, 3903 tess_ctrl_shader_code); 3904 3905 prepareTestShader(tess_eval_shader_layout_code /* layout */, "" /* uniforms */, 3906 test_tess_ctrl_shader_in_variable /* in var */, test_shader_out_variable /* out var */, 3907 "" /* verification */, passthrough_tess_eval_shader_body_code /* body */, 3908 tess_eval_shader_code); 3909 3910 break; 3911 3912 case TESS_EVAL_SHADER: 3913 3914 prepareBoilerplateShader(tess_ctrl_shader_layout_code /* layout */, 3915 boilerplate_tess_ctrl_shader_body_code /* body */, tess_ctrl_shader_code); 3916 3917 prepareTestShader(tess_eval_shader_layout_code /* layout */, uniform_definitions.c_str() /* uniforms */, 3918 "" /* in var */, test_shader_out_variable /* out var */, 3919 uniform_verification.c_str() /* verification */, test_shader_body_code /* body */, 3920 tess_eval_shader_code); 3921 3922 break; 3923 3924 default: 3925 break; 3926 }; 3927 3928 /* Select shaders that will be used by program */ 3929 const glw::GLchar* cs_c_str = 0; 3930 const glw::GLchar* fs_c_str = 0; 3931 const glw::GLchar* gs_c_str = 0; 3932 const glw::GLchar* tcs_c_str = 0; 3933 const glw::GLchar* tes_c_str = 0; 3934 const glw::GLchar* vs_c_str = 0; 3935 3936 if (false == compute_shader_code.empty()) 3937 { 3938 cs_c_str = compute_shader_code.c_str(); 3939 } 3940 3941 if (false == fragment_shader_code.empty()) 3942 { 3943 fs_c_str = fragment_shader_code.c_str(); 3944 } 3945 3946 if (false == geometry_shader_code.empty()) 3947 { 3948 gs_c_str = geometry_shader_code.c_str(); 3949 } 3950 3951 if (false == tess_ctrl_shader_code.empty()) 3952 { 3953 tcs_c_str = tess_ctrl_shader_code.c_str(); 3954 } 3955 3956 if (false == tess_eval_shader_code.empty()) 3957 { 3958 tes_c_str = tess_eval_shader_code.c_str(); 3959 } 3960 3961 if (false == vertex_shader_code.empty()) 3962 { 3963 vs_c_str = vertex_shader_code.c_str(); 3964 } 3965 3966 /* Compute and fragment shader results are stored in texture, do not set varyings for transfrom feedback */ 3967 if ((COMPUTE_SHADER == shader_stage) || (FRAGMENT_SHADER == shader_stage)) 3968 { 3969 n_varyings = 0; 3970 } 3971 3972 /* Build */ 3973 out_program_info.build(cs_c_str, fs_c_str, gs_c_str, tcs_c_str, tes_c_str, vs_c_str, &varying_name, n_varyings); 3974 } 3975 3976 /** Prepare collection of tested shader stages 3977 * 3978 */ 3979 void GPUShaderFP64Test2::prepareShaderStages() 3980 { 3981 /* m_pDispatchCompute is initialized only if compute_shader are supproted and context is at least 4.2 */ 3982 if (0 != m_pDispatchCompute) 3983 { 3984 m_shader_stages.push_back(COMPUTE_SHADER); 3985 } 3986 3987 m_shader_stages.push_back(FRAGMENT_SHADER); 3988 m_shader_stages.push_back(GEOMETRY_SHADER); 3989 m_shader_stages.push_back(TESS_CTRL_SHADER); 3990 m_shader_stages.push_back(TESS_EVAL_SHADER); 3991 m_shader_stages.push_back(VERTEX_SHADER); 3992 } 3993 3994 /** Prepare source code for "tested" shader stage 3995 * 3996 * @param stage_specific_layout String that will replace STAGE_SPECIFIC_LAYOUT token 3997 * @param uniform_definitions String that will replace UNIFORM_DEFINITIONS token 3998 * @param in_variable_definitions String that will replace IN_VARIABLE_DEFINITION token 3999 * @param out_variable_definitions String that will replace OUT_VARIABLE_DEFINITION token 4000 * @param uniform_verification String that will replace UNIFORM_VERIFICATION token 4001 * @param stage_specific_main_body String that will replace STAGE_SPECIFIC_MAIN_BODY token 4002 * @param out_source_code Shader source code 4003 **/ 4004 void GPUShaderFP64Test2::prepareTestShader(const glw::GLchar* stage_specific_layout, 4005 const glw::GLchar* uniform_definitions, 4006 const glw::GLchar* in_variable_definitions, 4007 const glw::GLchar* out_variable_definitions, 4008 const glw::GLchar* uniform_verification, 4009 const glw::GLchar* stage_specific_main_body, 4010 std::string& out_source_code) const 4011 { 4012 /* Shader template */ 4013 static const glw::GLchar* test_shader_template_code = "#version 400 core\n" 4014 "\n" 4015 "precision highp float;\n" 4016 "\n" 4017 "STAGE_SPECIFIC_LAYOUT" 4018 "UNIFORM_DEFINITIONS" 4019 "IN_VARIABLE_DEFINITION" 4020 "OUT_VARIABLE_DEFINITION" 4021 "\n" 4022 "void main()\n" 4023 "{\n" 4024 "UNIFORM_VERIFICATION" 4025 "STAGE_SPECIFIC_MAIN_BODY" 4026 "}\n" 4027 "\n"; 4028 4029 std::string string = test_shader_template_code; 4030 4031 /* Tokens */ 4032 static const glw::GLchar* body_token = "STAGE_SPECIFIC_MAIN_BODY"; 4033 static const glw::GLchar* in_var_token = "IN_VARIABLE_DEFINITION"; 4034 static const glw::GLchar* layout_token = "STAGE_SPECIFIC_LAYOUT"; 4035 static const glw::GLchar* out_var_token = "OUT_VARIABLE_DEFINITION"; 4036 static const glw::GLchar* uni_def_token = "UNIFORM_DEFINITIONS"; 4037 static const glw::GLchar* uni_ver_token = "UNIFORM_VERIFICATION"; 4038 4039 size_t search_position = 0; 4040 4041 /* Replace tokens */ 4042 Utils::replaceToken(layout_token, search_position, stage_specific_layout, string); 4043 Utils::replaceToken(uni_def_token, search_position, uniform_definitions, string); 4044 Utils::replaceToken(in_var_token, search_position, in_variable_definitions, string); 4045 Utils::replaceToken(out_var_token, search_position, out_variable_definitions, string); 4046 Utils::replaceToken(uni_ver_token, search_position, uniform_verification, string); 4047 Utils::replaceToken(body_token, search_position, stage_specific_main_body, string); 4048 4049 /* Store resuls */ 4050 out_source_code = string; 4051 } 4052 4053 /** Prepare source code for "tested" compute shaders 4054 * 4055 * @param uniform_definitions String that will replace UNIFORM_DEFINITIONS token 4056 * @param uniform_verification String that will replace UNIFORM_VERIFICATION token 4057 * @param out_source_code Source code 4058 **/ 4059 void GPUShaderFP64Test2::prepareTestComputeShader(const glw::GLchar* uniform_definitions, 4060 const glw::GLchar* uniform_verification, 4061 std::string& out_source_code) const 4062 { 4063 /* Shader template */ 4064 static const glw::GLchar* test_shader_template_code = 4065 "#version 420 core\n" 4066 "#extension GL_ARB_compute_shader : require\n" 4067 "#extension GL_ARB_shader_image_load_store : require\n" 4068 "\n" 4069 "precision highp float;\n" 4070 "\n" 4071 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 4072 "\n" 4073 "UNIFORM_DEFINITIONS" 4074 "layout(r32i) writeonly uniform iimage2D result;\n" 4075 "\n" 4076 "void main()\n" 4077 "{\n" 4078 "UNIFORM_VERIFICATION" 4079 "\n" 4080 " imageStore(result, ivec2(gl_WorkGroupID.xy), ivec4(verification_result, 0, 0, 0));\n" 4081 "}\n" 4082 "\n"; 4083 4084 std::string string = test_shader_template_code; 4085 4086 /* Tokens */ 4087 static const glw::GLchar* uni_def_token = "UNIFORM_DEFINITIONS"; 4088 static const glw::GLchar* uni_ver_token = "UNIFORM_VERIFICATION"; 4089 4090 size_t search_position = 0; 4091 4092 /* Replace tokens */ 4093 Utils::replaceToken(uni_def_token, search_position, uniform_definitions, string); 4094 Utils::replaceToken(uni_ver_token, search_position, uniform_verification, string); 4095 4096 /* Store resuls */ 4097 out_source_code = string; 4098 } 4099 4100 /** Prepare source code which defines uniforms for tested shader stage 4101 * 4102 * @param shader_stage Shader stage id 4103 * @param uniform_type Details of uniform type 4104 * @param out_source_code Source code 4105 **/ 4106 void GPUShaderFP64Test2::prepareUniformDefinitions(shaderStage shader_stage, const uniformTypeDetails& uniform_type, 4107 std::string& out_source_code) const 4108 { 4109 const glw::GLuint n_uniforms = getAmountUniforms(shader_stage, uniform_type); 4110 std::stringstream stream; 4111 4112 /* 4113 * layout(std140) uniform M_UNIFORM_BLOCK_NAME 4114 * { 4115 * TYPE_NAME uniform_array[N_UNIFORMS]; 4116 * }; 4117 */ 4118 stream << "layout(std140) uniform " << m_uniform_block_name << "\n" 4119 "{\n"; 4120 4121 stream << " " << uniform_type.m_type_name << " uniform_array[" << n_uniforms << "];\n"; 4122 4123 stream << "};\n\n"; 4124 4125 out_source_code = stream.str(); 4126 } 4127 4128 /** Prepare uniform buffer for test 4129 * 4130 * @param shader_stage Shader stage id 4131 * @param uniform_type Details of uniform type 4132 * @param program_info Program object info 4133 **/ 4134 void GPUShaderFP64Test2::prepareUniforms(shaderStage shader_stage, const uniformTypeDetails& uniform_type, 4135 const Utils::programInfo& program_info) const 4136 { 4137 glw::GLint buffer_size = 0; 4138 glw::GLuint element_ordinal = 1; 4139 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4140 const glw::GLuint n_columns = uniform_type.m_n_columns; 4141 const glw::GLuint n_rows = uniform_type.m_n_rows; 4142 const glw::GLuint n_elements = n_columns * n_rows; 4143 uniformDetails uniform_details; 4144 const glw::GLuint program_id = program_info.m_program_object_id; 4145 const glw::GLint n_uniforms = getAmountUniforms(shader_stage, uniform_type); 4146 std::vector<glw::GLubyte> uniform_buffer_data; 4147 glw::GLuint uniform_block_index = 0; 4148 4149 /* Get uniform details */ 4150 inspectProgram(program_id, n_uniforms, uniform_type, buffer_size, uniform_details, uniform_block_index); 4151 4152 /* Uniform offset and strides */ 4153 const glw::GLuint array_stride = uniform_details.m_array_stride; 4154 const glw::GLuint matrix_stride = uniform_details.m_matrix_stride; 4155 const glw::GLuint uniform_offset = uniform_details.m_offset; 4156 4157 /* Prepare storage for buffer data */ 4158 uniform_buffer_data.resize(buffer_size); 4159 4160 /* Prepare uniform data */ 4161 for (glw::GLint i = 0; i < n_uniforms; ++i) 4162 { 4163 const glw::GLuint array_entry_offset = uniform_offset + i * array_stride; 4164 4165 for (glw::GLuint element = 0; element < n_elements; ++element, ++element_ordinal) 4166 { 4167 const glw::GLuint column = element / n_rows; 4168 const glw::GLuint column_elem = element % n_rows; 4169 const glw::GLdouble value = element_ordinal; 4170 const glw::GLuint value_offset = static_cast<glw::GLuint>(array_entry_offset + column * matrix_stride + 4171 column_elem * sizeof(glw::GLdouble)); 4172 glw::GLdouble* value_dst = (glw::GLdouble*)&uniform_buffer_data[value_offset]; 4173 4174 *value_dst = value; 4175 } 4176 } 4177 4178 /* Update uniform buffer with new set of data */ 4179 gl.bindBuffer(GL_UNIFORM_BUFFER, m_uniform_buffer_id); 4180 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer"); 4181 4182 gl.bufferData(GL_UNIFORM_BUFFER, buffer_size, &uniform_buffer_data[0], GL_STATIC_DRAW); 4183 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData"); 4184 4185 /* Bind uniform block to uniform buffer */ 4186 gl.bindBufferRange(GL_UNIFORM_BUFFER, 0 /* index */, m_uniform_buffer_id, 0 /* offset */, buffer_size); 4187 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange"); 4188 4189 gl.uniformBlockBinding(program_id, uniform_block_index, 0 /* binding */); 4190 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformBlockBinding"); 4191 } 4192 4193 /** Prepare collection of tested uniform types 4194 * 4195 **/ 4196 void GPUShaderFP64Test2::prepareUniformTypes() 4197 { 4198 m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 1 /* n_rows */)); 4199 m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 2 /* n_rows */)); 4200 m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 3 /* n_rows */)); 4201 m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 4 /* n_rows */)); 4202 m_uniform_types.push_back(uniformTypeDetails(2 /* n_columns */, 2 /* n_rows */)); 4203 m_uniform_types.push_back(uniformTypeDetails(2 /* n_columns */, 3 /* n_rows */)); 4204 m_uniform_types.push_back(uniformTypeDetails(2 /* n_columns */, 4 /* n_rows */)); 4205 m_uniform_types.push_back(uniformTypeDetails(3 /* n_columns */, 2 /* n_rows */)); 4206 m_uniform_types.push_back(uniformTypeDetails(3 /* n_columns */, 3 /* n_rows */)); 4207 m_uniform_types.push_back(uniformTypeDetails(3 /* n_columns */, 4 /* n_rows */)); 4208 m_uniform_types.push_back(uniformTypeDetails(4 /* n_columns */, 2 /* n_rows */)); 4209 m_uniform_types.push_back(uniformTypeDetails(4 /* n_columns */, 3 /* n_rows */)); 4210 m_uniform_types.push_back(uniformTypeDetails(4 /* n_columns */, 4 /* n_rows */)); 4211 } 4212 4213 /** Prepare source code that verifes uniform values 4214 * 4215 * @param shader_stage Shader stage id 4216 * @param uniform_type Details of uniform type 4217 * @param out_source_code Source code 4218 **/ 4219 void GPUShaderFP64Test2::prepareUniformVerification(shaderStage shader_stage, const uniformTypeDetails& uniform_type, 4220 std::string& out_source_code) const 4221 { 4222 glw::GLuint element_ordinal = 1; 4223 const glw::GLuint n_columns = uniform_type.m_n_columns; 4224 const glw::GLuint n_rows = uniform_type.m_n_rows; 4225 const glw::GLuint n_elements = n_columns * n_rows; 4226 const glw::GLuint n_uniforms = getAmountUniforms(shader_stage, uniform_type); 4227 std::stringstream stream; 4228 4229 /* 4230 * int verification_result = M_RESULT_SUCCESS; 4231 * 4232 * for (int i = 0; i < N_UNIFORMS; ++i) 4233 * { 4234 * if (TYPE_NAME(i * (N_ELEMENTS) + 1) != uniform_array[i]) 4235 * { 4236 * verification_result = M_RESULT_FAILURE 4237 * } 4238 * } 4239 */ 4240 stream << " int verification_result = " << m_result_success << ";\n" 4241 "\n" 4242 " for (int i = 0; i < " 4243 << n_uniforms << "; ++i)\n" 4244 " {\n" 4245 " if (" 4246 << uniform_type.m_type_name << "("; 4247 4248 for (glw::GLuint element = 0; element < n_elements; ++element, ++element_ordinal) 4249 { 4250 stream << "i * (" << n_elements << ") + " << element + 1; 4251 4252 if (n_elements != element + 1) 4253 { 4254 stream << ", "; 4255 } 4256 } 4257 4258 stream << ") != uniform_array[i])\n" 4259 " {\n" 4260 " verification_result = " 4261 << m_result_failure << ";\n" 4262 " }\n" 4263 " }\n"; 4264 4265 out_source_code = stream.str(); 4266 } 4267 4268 /** Execute test for given combination of "tested" shader stage and uniform type 4269 * 4270 * @param shader_stage Tested shader stage id 4271 * @param uniform_type Tested uniform type 4272 * 4273 * @return true if test passed, false otherwise 4274 **/ 4275 bool GPUShaderFP64Test2::test(shaderStage shader_stage, const uniformTypeDetails& uniform_type) const 4276 { 4277 const glw::GLenum draw_primitive = getDrawPrimitiveType(shader_stage); 4278 static const glw::GLint first_vertex = 0; 4279 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4280 const glw::GLsizei n_vertices = (FRAGMENT_SHADER == shader_stage) ? 4 : m_n_captured_results; 4281 Utils::programInfo program_info(m_context); 4282 bool result = true; 4283 4284 /* Prepare program */ 4285 prepareProgram(shader_stage, uniform_type, program_info); 4286 4287 gl.useProgram(program_info.m_program_object_id); 4288 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram"); 4289 4290 /* Prepare uniform buffer and bind it with uniform block */ 4291 prepareUniforms(shader_stage, uniform_type, program_info); 4292 4293 /* Prepare storage for test results */ 4294 testBegin(program_info.m_program_object_id, shader_stage); 4295 4296 /* Execute */ 4297 if (COMPUTE_SHADER == shader_stage) 4298 { 4299 m_pDispatchCompute(m_texture_width, m_texture_height, 1); 4300 GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute"); 4301 } 4302 else 4303 { 4304 gl.drawArrays(draw_primitive, first_vertex, n_vertices); 4305 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 4306 } 4307 4308 /* Clean after test */ 4309 testEnd(shader_stage); 4310 4311 /* Check results */ 4312 if (false == verifyResults(shader_stage)) 4313 { 4314 m_context.getTestContext().getLog() 4315 << tcu::TestLog::Message << "Shader stage: " << getShaderStageName(shader_stage) 4316 << ". Uniform type: " << uniform_type.m_type_name << tcu::TestLog::EndMessage; 4317 4318 result = false; 4319 } 4320 4321 return result; 4322 } 4323 4324 /** Prepare transform feedback buffer, framebuffer or image unit for test results 4325 * 4326 * @param program_id Program object id 4327 * @param shader_stage Tested shader stage id 4328 **/ 4329 void GPUShaderFP64Test2::testBegin(glw::GLuint program_id, shaderStage shader_stage) const 4330 { 4331 std::vector<glw::GLint> buffer_data; 4332 const glw::GLenum captured_primitive = getCapturedPrimitiveType(shader_stage); 4333 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4334 4335 /* Prepare buffer filled with m_result_failure */ 4336 buffer_data.resize(m_n_captured_results); 4337 for (glw::GLuint i = 0; i < m_n_captured_results; ++i) 4338 { 4339 buffer_data[i] = m_result_failure; 4340 } 4341 4342 /* Prepare buffer for test results */ 4343 switch (shader_stage) 4344 { 4345 case GEOMETRY_SHADER: 4346 case TESS_CTRL_SHADER: 4347 case TESS_EVAL_SHADER: 4348 case VERTEX_SHADER: 4349 4350 /* Verify getTransformFeedbackVarying results */ 4351 { 4352 glw::GLsizei size = 0; 4353 glw::GLenum type = 0; 4354 glw::GLchar name[16]; 4355 4356 gl.getTransformFeedbackVarying(program_id, 0 /* index */, 16 /* bufSize */, 0 /* length */, &size, &type, 4357 name); 4358 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTransformFeedbackVarying"); 4359 4360 if ((1 != size) || (GL_INT != type) || (0 != strcmp("result", name))) 4361 { 4362 m_context.getTestContext().getLog() 4363 << tcu::TestLog::Message << "Error. Invalid GetTransformFeedbackVarying results." 4364 << " Size: " << size << " expected: " << 1 << ". Type: " << type << " expected: " << GL_INT 4365 << ". Name: " << name << " expected: result" << tcu::TestLog::EndMessage; 4366 4367 TCU_FAIL("Invalid GetTransformFeedbackVarying results"); 4368 } 4369 } 4370 4371 /* Create/clean transform feedback buffer */ 4372 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id); 4373 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer"); 4374 4375 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_size, &buffer_data[0], GL_DYNAMIC_COPY); 4376 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData"); 4377 4378 /* Set up transform feedback buffer */ 4379 gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_transform_feedback_buffer_id, 0 /* offset */, 4380 m_transform_feedback_buffer_size); 4381 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange"); 4382 4383 gl.beginTransformFeedback(captured_primitive); 4384 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 4385 4386 break; 4387 4388 case FRAGMENT_SHADER: 4389 4390 /* Clean texture */ 4391 gl.bindTexture(GL_TEXTURE_2D, m_texture_id); 4392 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 4393 4394 gl.texSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, m_texture_width, m_texture_height, 4395 GL_RED_INTEGER, GL_INT, &buffer_data[0]); 4396 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D"); 4397 4398 /* Set up texture as color attachment 0 */ 4399 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_id); 4400 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer"); 4401 4402 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0 /* level */); 4403 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D"); 4404 4405 gl.viewport(0 /* x */, 0 /* y */, m_texture_width, m_texture_height); 4406 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport"); 4407 4408 break; 4409 4410 case COMPUTE_SHADER: 4411 4412 /* Clean texture */ 4413 gl.bindTexture(GL_TEXTURE_2D, m_texture_id); 4414 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 4415 4416 gl.texSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, m_texture_width, m_texture_height, 4417 GL_RED_INTEGER, GL_INT, &buffer_data[0]); 4418 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D"); 4419 4420 glw::GLint location = gl.getUniformLocation(program_id, "result"); 4421 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D"); 4422 4423 if (-1 == location) 4424 { 4425 TCU_FAIL("Inactive uniform \"result\""); 4426 } 4427 4428 gl.uniform1i(location, 0 /* first image unit */); 4429 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D"); 4430 4431 /* Bind texture to first image unit */ 4432 gl.bindImageTexture(0 /* first image unit */, m_texture_id, 0 /* level */, GL_FALSE /* layered */, 4433 0 /* layer */, GL_WRITE_ONLY, GL_R32I); 4434 GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture"); 4435 4436 break; 4437 } 4438 } 4439 4440 /** Unbind transform feedback buffer, framebuffer or image unit 4441 * 4442 * @param shader_stage Tested shader stage id 4443 **/ 4444 void GPUShaderFP64Test2::testEnd(shaderStage shader_stage) const 4445 { 4446 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4447 4448 switch (shader_stage) 4449 { 4450 case GEOMETRY_SHADER: 4451 case TESS_CTRL_SHADER: 4452 case TESS_EVAL_SHADER: 4453 case VERTEX_SHADER: 4454 4455 gl.endTransformFeedback(); 4456 4457 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); 4458 4459 break; 4460 4461 case FRAGMENT_SHADER: 4462 4463 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0 /* texture_id */, 4464 0 /* level */); 4465 4466 gl.bindTexture(GL_TEXTURE_2D, 0); 4467 4468 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 4469 4470 break; 4471 4472 case COMPUTE_SHADER: 4473 4474 gl.bindImageTexture(0 /* first image unit */, 0 /* texture_id */, 0 /* level */, GL_FALSE /* layered */, 4475 0 /* layer */, GL_WRITE_ONLY, GL_R32I); 4476 4477 break; 4478 } 4479 } 4480 4481 /** Initialize OpenGL objects for test 4482 * 4483 **/ 4484 void GPUShaderFP64Test2::testInit() 4485 { 4486 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4487 4488 /* The test is in 4.0 group. However: 4489 * - compute_shader is core since 4.3 4490 * - compute_shader require at least version 4.2 of GL */ 4491 if ((true == m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader")) && 4492 (true == Utils::isGLVersionAtLeast(gl, 4 /* major */, 2 /* minor */))) 4493 { 4494 m_pDispatchCompute = (arbDispatchComputeFunc)gl.dispatchCompute; 4495 } 4496 4497 /* Tesselation patch set up */ 4498 gl.patchParameteri(GL_PATCH_VERTICES, 1); 4499 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri"); 4500 4501 /* Generate FBO */ 4502 gl.genFramebuffers(1, &m_framebuffer_id); 4503 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers"); 4504 4505 /* Prepare texture */ 4506 gl.genTextures(1, &m_texture_id); 4507 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures"); 4508 4509 gl.bindTexture(GL_TEXTURE_2D, m_texture_id); 4510 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 4511 4512 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32I, m_texture_width, m_texture_height); 4513 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D"); 4514 4515 /* Prepare transform feedback buffer */ 4516 gl.genBuffers(1, &m_transform_feedback_buffer_id); 4517 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers"); 4518 4519 /* Generate uniform buffer */ 4520 gl.genBuffers(1, &m_uniform_buffer_id); 4521 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers"); 4522 4523 /* Prepare VAO */ 4524 gl.genVertexArrays(1, &m_vertex_array_object_id); 4525 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays"); 4526 4527 gl.bindVertexArray(m_vertex_array_object_id); 4528 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray"); 4529 } 4530 4531 /** Result verification, expected result is that whole buffer is filled with m_result_success 4532 * 4533 * @param shader_stage Tested shader stage id 4534 **/ 4535 bool GPUShaderFP64Test2::verifyResults(shaderStage shader_stage) const 4536 { 4537 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4538 4539 if ((FRAGMENT_SHADER == shader_stage) || (COMPUTE_SHADER == shader_stage)) 4540 { 4541 /* Verify contents of texture */ 4542 4543 /* Prepare storage for testure data */ 4544 std::vector<glw::GLint> image_data; 4545 image_data.resize(m_texture_width * m_texture_height); 4546 4547 /* Get texture contents */ 4548 gl.bindTexture(GL_TEXTURE_2D, m_texture_id); 4549 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 4550 4551 gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, GL_RED_INTEGER, GL_INT, &image_data[0]); 4552 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage"); 4553 4554 for (glw::GLuint y = 0; y < m_texture_width; ++y) 4555 { 4556 for (glw::GLuint x = 0; x < m_texture_height; ++x) 4557 { 4558 const glw::GLuint offset = y * m_texture_width + x; 4559 const glw::GLint value = image_data[offset]; 4560 4561 if (m_result_success != value) 4562 { 4563 m_context.getTestContext().getLog() 4564 << tcu::TestLog::Message << "Error. Texture contents are wrong at (" << x << ", " << y << ")" 4565 << tcu::TestLog::EndMessage; 4566 4567 return false; 4568 } 4569 } 4570 } 4571 4572 return true; 4573 } 4574 else 4575 { 4576 /* Verify contents of transform feedback buffer */ 4577 4578 bool result = true; 4579 4580 /* Get transform feedback data */ 4581 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id); 4582 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer"); 4583 4584 glw::GLint* feedback_data = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 4585 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 4586 4587 for (glw::GLuint i = 0; i < m_n_captured_results; ++i) 4588 { 4589 const glw::GLint value = feedback_data[i]; 4590 4591 if (m_result_success != value) 4592 { 4593 m_context.getTestContext().getLog() << tcu::TestLog::Message 4594 << "Error. Transform feedback buffer contents are wrong at " << i 4595 << tcu::TestLog::EndMessage; 4596 4597 result = false; 4598 break; 4599 } 4600 } 4601 4602 /* Unmap transform feedback buffer */ 4603 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 4604 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 4605 4606 return result; 4607 } 4608 } 4609 4610 /* Definitions of static const fields declared in GPUShaderFP64Test3 */ 4611 const glw::GLuint GPUShaderFP64Test3::m_result_failure = 0; 4612 const glw::GLuint GPUShaderFP64Test3::m_result_success = 1; 4613 4614 const glw::GLchar* GPUShaderFP64Test3::m_uniform_block_name = "UniformBlock"; 4615 const glw::GLchar* GPUShaderFP64Test3::m_uniform_block_instance_name = "uniform_block"; 4616 4617 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_fs_out_fs_result = "fs_out_fs_result"; 4618 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_gs_result = "gs_fs_gs_result"; 4619 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_tcs_result = "gs_fs_tcs_result"; 4620 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_tes_result = "gs_fs_tes_result"; 4621 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_vs_result = "gs_fs_vs_result"; 4622 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tcs_tes_tcs_result = "tcs_tes_tcs_result"; 4623 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tcs_tes_vs_result = "tcs_tes_vs_result"; 4624 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tes_gs_tcs_result = "tes_gs_tcs_result"; 4625 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tes_gs_tes_result = "tes_gs_tes_result"; 4626 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tes_gs_vs_result = "tes_gs_vs_result"; 4627 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_vs_tcs_vs_result = "vs_tcs_vs_result"; 4628 4629 /* Definitions of static const fields declared in GPUShaderFP64Test3::programInfo */ 4630 const glw::GLint GPUShaderFP64Test3::programInfo::m_invalid_uniform_offset = -1; 4631 const glw::GLint GPUShaderFP64Test3::programInfo::m_invalid_uniform_matrix_stride = -1; 4632 const glw::GLint GPUShaderFP64Test3::programInfo::m_non_matrix_uniform_matrix_stride = 0; 4633 4634 /** Constructor 4635 * 4636 * @param context Test context 4637 **/ 4638 GPUShaderFP64Test3::GPUShaderFP64Test3(deqp::Context& context) 4639 : TestCase(context, "named_uniform_blocks", 4640 "Verifies usage of \"double precision\" floats in \"named uniform block\"") 4641 { 4642 /* Nothing to be done */ 4643 } 4644 4645 /** Deinitialize test 4646 * 4647 **/ 4648 void GPUShaderFP64Test3::deinit() 4649 { 4650 /* GL entry points */ 4651 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4652 4653 /* Clean programs */ 4654 m_packed_program.deinit(m_context); 4655 m_shared_program.deinit(m_context); 4656 m_std140_program.deinit(m_context); 4657 4658 /* Clean frambuffer */ 4659 if (0 != m_framebuffer_id) 4660 { 4661 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 4662 gl.deleteFramebuffers(1, &m_framebuffer_id); 4663 4664 m_framebuffer_id = 0; 4665 } 4666 4667 /* Clean texture */ 4668 if (0 != m_color_texture_id) 4669 { 4670 gl.bindTexture(GL_TEXTURE_2D, 0); 4671 gl.deleteTextures(1, &m_color_texture_id); 4672 4673 m_color_texture_id = 0; 4674 } 4675 4676 /* Clean buffers */ 4677 if (0 != m_transform_feedback_buffer_id) 4678 { 4679 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); 4680 gl.deleteBuffers(1, &m_transform_feedback_buffer_id); 4681 4682 m_transform_feedback_buffer_id = 0; 4683 } 4684 4685 if (0 != m_uniform_buffer_id) 4686 { 4687 gl.bindBuffer(GL_UNIFORM_BUFFER, 0); 4688 gl.deleteBuffers(1, &m_uniform_buffer_id); 4689 4690 m_uniform_buffer_id = 0; 4691 } 4692 4693 /* Clean VAO */ 4694 if (0 != m_vertex_array_object_id) 4695 { 4696 gl.bindVertexArray(0); 4697 gl.deleteVertexArrays(1, &m_vertex_array_object_id); 4698 4699 m_vertex_array_object_id = 0; 4700 } 4701 } 4702 4703 /** Execute test 4704 * 4705 * @return tcu::TestNode::STOP 4706 **/ 4707 tcu::TestNode::IterateResult GPUShaderFP64Test3::iterate() 4708 { 4709 bool result = true; 4710 4711 /* Check if extension is supported */ 4712 if (false == m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64")) 4713 { 4714 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported"); 4715 } 4716 4717 /* Initialize test */ 4718 testInit(); 4719 4720 /* Test "packed" uniform buffer layout */ 4721 if (false == test(PACKED)) 4722 { 4723 result = false; 4724 } 4725 4726 /* Test "shared" uniform buffer layout */ 4727 if (false == test(SHARED)) 4728 { 4729 result = false; 4730 } 4731 4732 /* Test "std140" uniform buffer layout */ 4733 if (false == test(STD140)) 4734 { 4735 result = false; 4736 } 4737 4738 /* Set result */ 4739 if (true == result) 4740 { 4741 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 4742 } 4743 else 4744 { 4745 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 4746 } 4747 4748 /* Done */ 4749 return tcu::TestNode::STOP; 4750 } 4751 4752 /** Constructor 4753 * 4754 **/ 4755 GPUShaderFP64Test3::programInfo::programInfo() 4756 : m_fragment_shader_id(0) 4757 , m_geometry_shader_id(0) 4758 , m_program_object_id(0) 4759 , m_tesselation_control_shader_id(0) 4760 , m_tesselation_evaluation_shader_id(0) 4761 , m_vertex_shader_id(0) 4762 , m_buffer_size(0) 4763 , m_uniform_block_index(0) 4764 { 4765 /* Nothing to be done here */ 4766 } 4767 4768 /** Compile shader 4769 * 4770 * @param context Test context 4771 * @param shader_id Shader object id 4772 * @param shader_code Shader source code 4773 **/ 4774 void GPUShaderFP64Test3::programInfo::compile(deqp::Context& context, glw::GLuint shader_id, 4775 const glw::GLchar* shader_code) const 4776 { 4777 /* GL entry points */ 4778 const glw::Functions& gl = context.getRenderContext().getFunctions(); 4779 4780 /* Compilation status */ 4781 glw::GLint status = GL_FALSE; 4782 4783 /* Set source code */ 4784 gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0); 4785 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource"); 4786 4787 /* Compile */ 4788 gl.compileShader(shader_id); 4789 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader"); 4790 4791 /* Get compilation status */ 4792 gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status); 4793 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 4794 4795 /* Log compilation error */ 4796 if (GL_TRUE != status) 4797 { 4798 glw::GLint length = 0; 4799 std::vector<glw::GLchar> message; 4800 4801 /* Error log length */ 4802 gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length); 4803 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 4804 4805 /* Prepare storage */ 4806 message.resize(length); 4807 4808 /* Get error log */ 4809 gl.getShaderInfoLog(shader_id, length, 0, &message[0]); 4810 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog"); 4811 4812 /* Log */ 4813 context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n" 4814 << &message[0] << "\nShader source\n" 4815 << shader_code << tcu::TestLog::EndMessage; 4816 4817 TCU_FAIL("Failed to compile shader"); 4818 } 4819 } 4820 4821 /** Cleans program and attached shaders 4822 * 4823 * @param context Test context 4824 **/ 4825 void GPUShaderFP64Test3::programInfo::deinit(deqp::Context& context) 4826 { 4827 /* GL entry points */ 4828 const glw::Functions& gl = context.getRenderContext().getFunctions(); 4829 4830 /* Restore default program */ 4831 gl.useProgram(0); 4832 4833 /* Clean program object */ 4834 if (0 != m_program_object_id) 4835 { 4836 gl.deleteProgram(m_program_object_id); 4837 m_program_object_id = 0; 4838 } 4839 4840 /* Clean shaders */ 4841 if (0 != m_fragment_shader_id) 4842 { 4843 gl.deleteShader(m_fragment_shader_id); 4844 m_fragment_shader_id = 0; 4845 } 4846 4847 if (0 != m_geometry_shader_id) 4848 { 4849 gl.deleteShader(m_geometry_shader_id); 4850 m_geometry_shader_id = 0; 4851 } 4852 4853 if (0 != m_tesselation_control_shader_id) 4854 { 4855 gl.deleteShader(m_tesselation_control_shader_id); 4856 m_tesselation_control_shader_id = 0; 4857 } 4858 4859 if (0 != m_tesselation_evaluation_shader_id) 4860 { 4861 gl.deleteShader(m_tesselation_evaluation_shader_id); 4862 m_tesselation_evaluation_shader_id = 0; 4863 } 4864 4865 if (0 != m_vertex_shader_id) 4866 { 4867 gl.deleteShader(m_vertex_shader_id); 4868 m_vertex_shader_id = 0; 4869 } 4870 } 4871 4872 /** Build program and query for uniform layout 4873 * 4874 * @param context Test context 4875 * @param uniform_details Collection of uniform details 4876 * @param fragment_shader_code Fragment shader source code 4877 * @param geometry_shader_code Geometry shader source code 4878 * @param tesselation_control_shader_code Tesselation control shader source code 4879 * @param tesselation_evaluation_shader_code Tesselation evaluation shader source code 4880 * @param vertex_shader_code Vertex shader source code 4881 **/ 4882 void GPUShaderFP64Test3::programInfo::init(deqp::Context& context, const std::vector<uniformDetails> uniform_details, 4883 const glw::GLchar* fragment_shader_code, 4884 const glw::GLchar* geometry_shader_code, 4885 const glw::GLchar* tesselation_control_shader_code, 4886 const glw::GLchar* tesselation_evaluation_shader_code, 4887 const glw::GLchar* vertex_shader_code) 4888 { 4889 /* GL entry points */ 4890 const glw::Functions& gl = context.getRenderContext().getFunctions(); 4891 4892 /* Names of varyings to be captured with transform feedback */ 4893 static const glw::GLchar* varying_names[] = { m_varying_name_gs_fs_gs_result, m_varying_name_gs_fs_tcs_result, 4894 m_varying_name_gs_fs_tes_result, m_varying_name_gs_fs_vs_result }; 4895 static const glw::GLuint n_varying_names = sizeof(varying_names) / sizeof(varying_names[0]); 4896 4897 /* Create shader objects */ 4898 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER); 4899 m_geometry_shader_id = gl.createShader(GL_GEOMETRY_SHADER); 4900 m_tesselation_control_shader_id = gl.createShader(GL_TESS_CONTROL_SHADER); 4901 m_tesselation_evaluation_shader_id = gl.createShader(GL_TESS_EVALUATION_SHADER); 4902 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER); 4903 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 4904 4905 /* Create program object */ 4906 m_program_object_id = gl.createProgram(); 4907 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram"); 4908 4909 /* Set up names of varyings to be captured with transform feedback */ 4910 gl.transformFeedbackVaryings(m_program_object_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS); 4911 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings"); 4912 4913 /* Compile shaders */ 4914 compile(context, m_fragment_shader_id, fragment_shader_code); 4915 compile(context, m_geometry_shader_id, geometry_shader_code); 4916 compile(context, m_tesselation_control_shader_id, tesselation_control_shader_code); 4917 compile(context, m_tesselation_evaluation_shader_id, tesselation_evaluation_shader_code); 4918 compile(context, m_vertex_shader_id, vertex_shader_code); 4919 4920 /* Link program */ 4921 link(context); 4922 4923 /* Inspect program object */ 4924 /* Get index of named uniform block */ 4925 m_uniform_block_index = gl.getUniformBlockIndex(m_program_object_id, m_uniform_block_name); 4926 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformBlockIndex"); 4927 4928 if (GL_INVALID_INDEX == m_uniform_block_index) 4929 { 4930 TCU_FAIL("Unifom block is inactive"); 4931 } 4932 4933 /* Get size of named uniform block */ 4934 gl.getActiveUniformBlockiv(m_program_object_id, m_uniform_block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &m_buffer_size); 4935 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformBlockiv"); 4936 4937 if (0 == m_buffer_size) 4938 { 4939 TCU_FAIL("Unifom block size is 0"); 4940 } 4941 4942 /* Get information about "double precision" uniforms */ 4943 for (std::vector<uniformDetails>::const_iterator it = uniform_details.begin(), end = uniform_details.end(); 4944 end != it; ++it) 4945 { 4946 const glw::GLchar* uniform_name = 0; 4947 std::string uniform_name_str; 4948 std::stringstream uniform_name_stream; 4949 glw::GLuint index = 0; 4950 glw::GLint offset = 0; 4951 glw::GLint matrix_stride = 0; 4952 4953 /* Uniform name = UNIFORM_BLOCK_NAME.UNIFORM_NAME */ 4954 uniform_name_stream << m_uniform_block_name << "." << it->m_name; 4955 4956 uniform_name_str = uniform_name_stream.str(); 4957 uniform_name = uniform_name_str.c_str(); 4958 4959 /* Get index of uniform */ 4960 gl.getUniformIndices(m_program_object_id, 1 /* count */, &uniform_name, &index); 4961 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices"); 4962 4963 if (GL_INVALID_INDEX == index) 4964 { 4965 TCU_FAIL("Unifom is inactive"); 4966 } 4967 4968 /* Get offset of uniform */ 4969 gl.getActiveUniformsiv(m_program_object_id, 1 /* count */, &index, GL_UNIFORM_OFFSET, &offset); 4970 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv"); 4971 4972 if (m_invalid_uniform_offset == offset) 4973 { 4974 TCU_FAIL("Unifom has invalid offset"); 4975 } 4976 4977 m_uniform_offsets.push_back(offset); 4978 4979 /* Get matrix stride of uniform */ 4980 gl.getActiveUniformsiv(m_program_object_id, 1 /* count */, &index, GL_UNIFORM_MATRIX_STRIDE, &matrix_stride); 4981 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv"); 4982 4983 if (m_invalid_uniform_matrix_stride == offset) 4984 { 4985 TCU_FAIL("Unifom has invalid matrix stride"); 4986 } 4987 4988 m_uniform_matrix_strides.push_back(matrix_stride); 4989 } 4990 } 4991 4992 /** Attach shaders and link program 4993 * 4994 * @param context Test context 4995 **/ 4996 void GPUShaderFP64Test3::programInfo::link(deqp::Context& context) const 4997 { 4998 /* GL entry points */ 4999 const glw::Functions& gl = context.getRenderContext().getFunctions(); 5000 5001 /* Link status */ 5002 glw::GLint status = GL_FALSE; 5003 5004 /* Attach shaders */ 5005 gl.attachShader(m_program_object_id, m_fragment_shader_id); 5006 gl.attachShader(m_program_object_id, m_geometry_shader_id); 5007 gl.attachShader(m_program_object_id, m_tesselation_control_shader_id); 5008 gl.attachShader(m_program_object_id, m_tesselation_evaluation_shader_id); 5009 gl.attachShader(m_program_object_id, m_vertex_shader_id); 5010 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 5011 5012 /* Link */ 5013 gl.linkProgram(m_program_object_id); 5014 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram"); 5015 5016 /* Get link status */ 5017 gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status); 5018 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 5019 5020 /* Log link error */ 5021 if (GL_TRUE != status) 5022 { 5023 glw::GLint length = 0; 5024 std::vector<glw::GLchar> message; 5025 5026 /* Get error log length */ 5027 gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length); 5028 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 5029 5030 message.resize(length); 5031 5032 /* Get error log */ 5033 gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]); 5034 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog"); 5035 5036 /* Log */ 5037 context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n" 5038 << &message[0] << tcu::TestLog::EndMessage; 5039 5040 TCU_FAIL("Failed to link program"); 5041 } 5042 } 5043 5044 /** Returns "predefined" values that will be used to fill uniform data 5045 * 5046 * @param type_ordinal Ordinal number of "double precision" uniform type 5047 * @param element Index of element in uniform 5048 * 5049 * @return "Predefined" value 5050 **/ 5051 glw::GLdouble GPUShaderFP64Test3::getExpectedValue(glw::GLuint type_ordinal, glw::GLuint element) const 5052 { 5053 return m_base_type_ordinal + (13.0 * (glw::GLdouble)type_ordinal) + 5054 ((m_base_element - (glw::GLdouble)element) / 4.0); 5055 } 5056 5057 /** Returns a reference of programInfo instance specific for given buffer layout 5058 * 5059 * @param uniform_data_layout Buffer layout 5060 * 5061 * @return Reference to an instance of programInfo 5062 **/ 5063 const GPUShaderFP64Test3::programInfo& GPUShaderFP64Test3::getProgramInfo(uniformDataLayout uniform_data_layout) const 5064 { 5065 const programInfo* program_info = 0; 5066 5067 switch (uniform_data_layout) 5068 { 5069 case PACKED: 5070 5071 program_info = &m_packed_program; 5072 5073 break; 5074 5075 case SHARED: 5076 5077 program_info = &m_shared_program; 5078 5079 break; 5080 5081 case STD140: 5082 5083 program_info = &m_std140_program; 5084 5085 break; 5086 } 5087 5088 return *program_info; 5089 } 5090 5091 /** Get "name" of buffer layout 5092 * 5093 * @param uniform_data_layout Buffer layout 5094 * 5095 * @return "Name" of layout 5096 **/ 5097 const glw::GLchar* GPUShaderFP64Test3::getUniformLayoutName(uniformDataLayout uniform_data_layout) const 5098 { 5099 const glw::GLchar* layout = ""; 5100 5101 switch (uniform_data_layout) 5102 { 5103 case PACKED: 5104 layout = "packed"; 5105 break; 5106 case SHARED: 5107 layout = "shared"; 5108 break; 5109 case STD140: 5110 layout = "std140"; 5111 break; 5112 } 5113 5114 return layout; 5115 } 5116 5117 /** Prepare programInfo instance for specific buffer layout 5118 * 5119 * @param program_info Instance of programInfo 5120 * @param uniform_data_layout Buffer layout 5121 **/ 5122 void GPUShaderFP64Test3::prepareProgram(programInfo& program_info, uniformDataLayout uniform_data_layout) const 5123 { 5124 /* Storage for shader source code */ 5125 std::stringstream fragment_shader_code; 5126 std::stringstream geometry_shader_code; 5127 std::stringstream tess_control_shader_code; 5128 std::stringstream tess_eval_shader_code; 5129 std::stringstream vertex_shader_code; 5130 5131 /* Write preambles */ 5132 writePreamble(fragment_shader_code, FRAGMENT_SHADER); 5133 writePreamble(geometry_shader_code, GEOMETRY_SHADER); 5134 writePreamble(tess_control_shader_code, TESS_CONTROL_SHADER); 5135 writePreamble(tess_eval_shader_code, TESS_EVAL_SHADER); 5136 writePreamble(vertex_shader_code, VERTEX_SHADER); 5137 5138 /* Write definition of named uniform block */ 5139 writeUniformBlock(fragment_shader_code, uniform_data_layout); 5140 writeUniformBlock(geometry_shader_code, uniform_data_layout); 5141 writeUniformBlock(tess_control_shader_code, uniform_data_layout); 5142 writeUniformBlock(tess_eval_shader_code, uniform_data_layout); 5143 writeUniformBlock(vertex_shader_code, uniform_data_layout); 5144 5145 /* Write definitions of varyings */ 5146 writeVaryingDeclarations(fragment_shader_code, FRAGMENT_SHADER); 5147 writeVaryingDeclarations(geometry_shader_code, GEOMETRY_SHADER); 5148 writeVaryingDeclarations(tess_control_shader_code, TESS_CONTROL_SHADER); 5149 writeVaryingDeclarations(tess_eval_shader_code, TESS_EVAL_SHADER); 5150 writeVaryingDeclarations(vertex_shader_code, VERTEX_SHADER); 5151 5152 /* Write main routine */ 5153 writeMainBody(fragment_shader_code, FRAGMENT_SHADER); 5154 writeMainBody(geometry_shader_code, GEOMETRY_SHADER); 5155 writeMainBody(tess_control_shader_code, TESS_CONTROL_SHADER); 5156 writeMainBody(tess_eval_shader_code, TESS_EVAL_SHADER); 5157 writeMainBody(vertex_shader_code, VERTEX_SHADER); 5158 5159 /* Init programInfo instance */ 5160 program_info.init(m_context, m_uniform_details, fragment_shader_code.str().c_str(), 5161 geometry_shader_code.str().c_str(), tess_control_shader_code.str().c_str(), 5162 tess_eval_shader_code.str().c_str(), vertex_shader_code.str().c_str()); 5163 } 5164 5165 /** Prepare uniform buffer 5166 * 5167 * @param program_info Instance of programInfo 5168 * @param verify_offsets If uniform offsets should be verified against expected values 5169 * 5170 * @return false if uniform offsets verification result is failure, true otherwise 5171 **/ 5172 bool GPUShaderFP64Test3::prepareUniformBuffer(const programInfo& program_info, bool verify_offsets) const 5173 { 5174 const glw::GLuint buffer_size = program_info.m_buffer_size; 5175 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5176 bool offset_verification_result = true; 5177 glw::GLuint type_ordinal = 1; 5178 std::vector<uniformDetails>::const_iterator it_uniform_details = m_uniform_details.begin(); 5179 std::vector<glw::GLint>::const_iterator it_uniform_offsets = program_info.m_uniform_offsets.begin(); 5180 std::vector<glw::GLint>::const_iterator it_uniform_matrix_strides = program_info.m_uniform_matrix_strides.begin(); 5181 5182 /* Prepare storage for uniform buffer data */ 5183 std::vector<glw::GLubyte> buffer_data; 5184 buffer_data.resize(buffer_size); 5185 5186 /* For each "double precision" uniform */ 5187 for (/* start conditions already set up */; m_uniform_details.end() != it_uniform_details; 5188 ++it_uniform_details, ++it_uniform_offsets, ++it_uniform_matrix_strides, ++type_ordinal) 5189 { 5190 const glw::GLint matrix_stride = *it_uniform_matrix_strides; 5191 const glw::GLuint n_columns = it_uniform_details->m_n_columns; 5192 const glw::GLuint n_elements = it_uniform_details->m_n_elements; 5193 const glw::GLuint column_length = n_elements / n_columns; 5194 const glw::GLint uniform_offset = *it_uniform_offsets; 5195 5196 /* For each element of uniform */ 5197 for (glw::GLuint element = 0; element < n_elements; ++element) 5198 { 5199 const glw::GLuint column = element / column_length; 5200 const glw::GLuint column_elem = element % column_length; 5201 const glw::GLdouble value = getExpectedValue(type_ordinal, element); 5202 const glw::GLuint value_offset = 5203 static_cast<glw::GLuint>(uniform_offset + column * matrix_stride + column_elem * sizeof(glw::GLdouble)); 5204 5205 glw::GLdouble* value_dst = (glw::GLdouble*)&buffer_data[value_offset]; 5206 5207 /* Store value */ 5208 *value_dst = value; 5209 } 5210 5211 /* Uniform offset verification */ 5212 if (true == verify_offsets) 5213 { 5214 const glw::GLint expected_offset = it_uniform_details->m_expected_std140_offset; 5215 5216 if (expected_offset != uniform_offset) 5217 { 5218 if (true == offset_verification_result) 5219 { 5220 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error" << tcu::TestLog::EndMessage; 5221 } 5222 5223 m_context.getTestContext().getLog() 5224 << tcu::TestLog::Message << "Uniform: " << it_uniform_details->m_name 5225 << " has offset: " << uniform_offset << ". Expected offset: " << expected_offset 5226 << tcu::TestLog::EndMessage; 5227 5228 offset_verification_result = false; 5229 } 5230 } 5231 } 5232 5233 /* Update uniform buffer with prepared data */ 5234 gl.bindBuffer(GL_UNIFORM_BUFFER, m_uniform_buffer_id); 5235 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer"); 5236 5237 gl.bufferData(GL_UNIFORM_BUFFER, buffer_size, &buffer_data[0], GL_STATIC_DRAW); 5238 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData"); 5239 5240 /* Bind uniform buffer as data source for named uniform block */ 5241 gl.bindBufferRange(GL_UNIFORM_BUFFER, 0 /* index */, m_uniform_buffer_id, 0, buffer_size); 5242 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange"); 5243 5244 gl.uniformBlockBinding(program_info.m_program_object_id, program_info.m_uniform_block_index, 0 /* binding */); 5245 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformBlockBinding"); 5246 5247 /* Done */ 5248 return offset_verification_result; 5249 } 5250 5251 /** Prepare data, execute draw call and verify results 5252 * 5253 * @param uniform_data_layout 5254 * 5255 * @return true if test pass, false otherwise 5256 **/ 5257 bool GPUShaderFP64Test3::test(uniformDataLayout uniform_data_layout) const 5258 { 5259 bool are_offsets_verified = (STD140 == uniform_data_layout); 5260 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5261 bool offset_verification_result = true; 5262 const programInfo& program_info = getProgramInfo(uniform_data_layout); 5263 bool result = true; 5264 5265 /* Set up program */ 5266 gl.useProgram(program_info.m_program_object_id); 5267 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram"); 5268 5269 /* Prepare uniform buffer */ 5270 offset_verification_result = prepareUniformBuffer(program_info, are_offsets_verified); 5271 5272 if (true == are_offsets_verified && false == offset_verification_result) 5273 { 5274 /* Offsets verification failure was already reported, add info about buffer layout */ 5275 m_context.getTestContext().getLog() << tcu::TestLog::Message 5276 << "Uniform buffer layout: " << getUniformLayoutName(uniform_data_layout) 5277 << tcu::TestLog::EndMessage; 5278 5279 result = false; 5280 } 5281 5282 /* Set up transform feedback buffer */ 5283 gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_transform_feedback_buffer_id, 0, 4 * sizeof(glw::GLint)); 5284 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram"); 5285 5286 /* Begin transform feedback */ 5287 gl.beginTransformFeedback(GL_POINTS); 5288 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 5289 5290 /* Execute draw call for singe vertex */ 5291 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 5292 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 5293 5294 /* Stop transform feedback */ 5295 gl.endTransformFeedback(); 5296 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 5297 5298 /* Verify results */ 5299 if (false == verifyResults()) 5300 { 5301 /* Result verificatioon failure was already reported, add info about layout */ 5302 m_context.getTestContext().getLog() << tcu::TestLog::Message 5303 << "Uniform buffer layout: " << getUniformLayoutName(uniform_data_layout) 5304 << tcu::TestLog::EndMessage; 5305 5306 result = false; 5307 } 5308 5309 /* Done */ 5310 return result; 5311 } 5312 5313 void GPUShaderFP64Test3::testInit() 5314 { 5315 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5316 5317 /* Uniform block declaration with std140 offsets calculated 5318 * | align | loc_req | begins | ends | offset in bytes | imp | 5319 * ivec3 dummy1[3] | 4 | 12 | 0 | 12 | 0 | | 5320 * double double_value | 2 | 2 | 12 | 14 | 48 | XXX | 5321 * bool dummy2 | 1 | 1 | 14 | 15 | 56 | | 5322 * dvec2 dvec2_value | 4 | 4 | 16 | 20 | 64 | XXX | 5323 * bvec3 dummy3 | 4 | 4 | 20 | 24 | 80 | | 5324 * dvec3 dvec3_value | 8 | 8 | 24 | 32 | 96 | XXX | 5325 * int dummy4[3] | 4 | 12 | 32 | 44 | 128 | | 5326 * dvec4 dvec4_value | 8 | 8 | 48 | 56 | 192 | XXX | 5327 * bool dummy5 | 1 | 1 | 56 | 57 | 224 | | 5328 * bool dummy6[2] | 4 | 8 | 60 | 68 | 240 | | 5329 * dmat2 dmat2_value | 4 | 8 | 68 | 76 | 272 | XXX | 5330 * dmat3 dmat3_value | 8 | 24 | 80 | 104 | 320 | XXX | 5331 * bool dummy7 | 1 | 1 | 104 | 105 | 416 | | 5332 * dmat4 dmat4_value | 8 | 32 | 112 | 144 | 448 | XXX | 5333 * dmat2x3 dmat2x3_value | 8 | 16 | 144 | 160 | 576 | XXX | 5334 * uvec3 dummy8 | 4 | 4 | 160 | 164 | 640 | | 5335 * dmat2x4 dmat2x4_value | 8 | 16 | 168 | 184 | 672 | XXX | 5336 * dmat3x2 dmat3x2_value | 4 | 12 | 184 | 196 | 736 | XXX | 5337 * bool dummy9 | 1 | 1 | 196 | 197 | 784 | | 5338 * dmat3x4 dmat3x4_value | 8 | 24 | 200 | 224 | 800 | XXX | 5339 * int dummy10 | 1 | 1 | 224 | 225 | 896 | | 5340 * dmat4x2 dmat4x2_value | 4 | 16 | 228 | 244 | 912 | XXX | 5341 * dmat4x3 dmat4x3_value | 8 | 32 | 248 | 280 | 992 | XXX | 5342 */ 5343 5344 /* Prepare "double precision" unfiorms' details */ 5345 m_uniform_details.push_back(uniformDetails(48 /* off */, "double_value" /* name */, 1 /* n_columns */, 5346 1 /* n_elements */, "double" /* type_name */)); 5347 m_uniform_details.push_back(uniformDetails(64 /* off */, "dvec2_value" /* name */, 1 /* n_columns */, 5348 2 /* n_elements */, "dvec2" /* type_name */)); 5349 m_uniform_details.push_back(uniformDetails(96 /* off */, "dvec3_value" /* name */, 1 /* n_columns */, 5350 3 /* n_elements */, "dvec3" /* type_name */)); 5351 m_uniform_details.push_back(uniformDetails(192 /* off */, "dvec4_value" /* name */, 1 /* n_columns */, 5352 4 /* n_elements */, "dvec4" /* type_name */)); 5353 m_uniform_details.push_back(uniformDetails(272 /* off */, "dmat2_value" /* name */, 2 /* n_columns */, 5354 4 /* n_elements */, "dmat2" /* type_name */)); 5355 m_uniform_details.push_back(uniformDetails(320 /* off */, "dmat3_value" /* name */, 3 /* n_columns */, 5356 9 /* n_elements */, "dmat3" /* type_name */)); 5357 m_uniform_details.push_back(uniformDetails(448 /* off */, "dmat4_value" /* name */, 4 /* n_columns */, 5358 16 /* n_elements */, "dmat4" /* type_name */)); 5359 m_uniform_details.push_back(uniformDetails(576 /* off */, "dmat2x3_value" /* name */, 2 /* n_columns */, 5360 6 /* n_elements */, "dmat2x3" /* type_name */)); 5361 m_uniform_details.push_back(uniformDetails(672 /* off */, "dmat2x4_value" /* name */, 2 /* n_columns */, 5362 8 /* n_elements */, "dmat2x4" /* type_name */)); 5363 m_uniform_details.push_back(uniformDetails(736 /* off */, "dmat3x2_value" /* name */, 3 /* n_columns */, 5364 6 /* n_elements */, "dmat3x2" /* type_name */)); 5365 m_uniform_details.push_back(uniformDetails(800 /* off */, "dmat3x4_value" /* name */, 3 /* n_columns */, 5366 12 /* n_elements */, "dmat3x4" /* type_name */)); 5367 m_uniform_details.push_back(uniformDetails(912 /* off */, "dmat4x2_value" /* name */, 4 /* n_columns */, 5368 8 /* n_elements */, "dmat4x2" /* type_name */)); 5369 m_uniform_details.push_back(uniformDetails(992 /* off */, "dmat4x3_value" /* name */, 4 /* n_columns */, 5370 12 /* n_elements */, "dmat4x3" /* type_name */)); 5371 5372 /* Get random values for getExpectedValue */ 5373 m_base_element = (glw::GLdouble)(rand() % 13); 5374 m_base_type_ordinal = (glw::GLdouble)(rand() % 213); 5375 5376 /* Prepare programInfos for all buffer layouts */ 5377 prepareProgram(m_packed_program, PACKED); 5378 prepareProgram(m_shared_program, SHARED); 5379 prepareProgram(m_std140_program, STD140); 5380 5381 /* Generate buffers */ 5382 gl.genBuffers(1, &m_transform_feedback_buffer_id); 5383 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers"); 5384 5385 gl.genBuffers(1, &m_uniform_buffer_id); 5386 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers"); 5387 5388 /* Prepare transform feedback buffer */ 5389 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id); 5390 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer"); 5391 5392 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 4 * sizeof(glw::GLint), 0 /* data */, GL_DYNAMIC_COPY); 5393 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData"); 5394 5395 /* Prepare texture for color attachment 0 */ 5396 gl.genTextures(1, &m_color_texture_id); 5397 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures"); 5398 5399 gl.bindTexture(GL_TEXTURE_2D, m_color_texture_id); 5400 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 5401 5402 gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, GL_R32I, 1 /* width */, 1 /* height */); 5403 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D"); 5404 5405 /* Prepare FBO with color attachment 0 */ 5406 gl.genFramebuffers(1, &m_framebuffer_id); 5407 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers"); 5408 5409 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_id); 5410 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer"); 5411 5412 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_color_texture_id, 5413 0 /* level */); 5414 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D"); 5415 5416 gl.viewport(0 /* x */, 0 /* y */, 1 /* width */, 1 /* height */); 5417 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport"); 5418 5419 /* Prepare VAO */ 5420 gl.genVertexArrays(1, &m_vertex_array_object_id); 5421 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays"); 5422 5423 gl.bindVertexArray(m_vertex_array_object_id); 5424 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray"); 5425 5426 /* Tesselation patch set up */ 5427 gl.patchParameteri(GL_PATCH_VERTICES, 1); 5428 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri"); 5429 } 5430 5431 /** Verify contents of transform feedback buffer and framebuffer's color attachment 0 5432 * 5433 * @return true if all values are as expected, false otherwise 5434 **/ 5435 bool GPUShaderFP64Test3::verifyResults() const 5436 { 5437 glw::GLint* feedback_data = 0; 5438 bool fragment_shader_result = false; 5439 bool geometry_shader_result = false; 5440 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5441 bool tess_ctrl_shader_result = false; 5442 bool tess_eval_shader_result = false; 5443 bool vertex_shader_result = false; 5444 5445 /* Prepare storage for testure data */ 5446 std::vector<glw::GLint> image_data; 5447 image_data.resize(1); 5448 5449 /* Get texture contents */ 5450 gl.bindTexture(GL_TEXTURE_2D, m_color_texture_id); 5451 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 5452 5453 gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, GL_RED_INTEGER, GL_INT, &image_data[0]); 5454 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage"); 5455 5456 /* Get transform feedback data */ 5457 feedback_data = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 5458 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 5459 5460 /* Verify results */ 5461 fragment_shader_result = (m_result_success == image_data[0]); 5462 geometry_shader_result = (m_result_success == feedback_data[0]); 5463 tess_ctrl_shader_result = (m_result_success == feedback_data[1]); 5464 tess_eval_shader_result = (m_result_success == feedback_data[2]); 5465 vertex_shader_result = (m_result_success == feedback_data[3]); 5466 5467 /* Unmap transform feedback buffer */ 5468 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 5469 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 5470 5471 /* Set result */ 5472 if (true != (fragment_shader_result && geometry_shader_result && tess_ctrl_shader_result && 5473 tess_eval_shader_result && vertex_shader_result)) 5474 { 5475 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error" << tcu::TestLog::EndMessage; 5476 5477 m_context.getTestContext().getLog() << tcu::TestLog::Message 5478 << "Vertex shader stage result: " << vertex_shader_result 5479 << tcu::TestLog::EndMessage; 5480 5481 m_context.getTestContext().getLog() << tcu::TestLog::Message 5482 << "Tesselation control shader stage result: " << tess_ctrl_shader_result 5483 << tcu::TestLog::EndMessage; 5484 5485 m_context.getTestContext().getLog() << tcu::TestLog::Message 5486 << "Tesselation evaluation shader stage result: " << tess_eval_shader_result 5487 << tcu::TestLog::EndMessage; 5488 5489 m_context.getTestContext().getLog() << tcu::TestLog::Message 5490 << "Geometry shader stage result: " << geometry_shader_result 5491 << tcu::TestLog::EndMessage; 5492 5493 m_context.getTestContext().getLog() << tcu::TestLog::Message 5494 << "Fragment shader stage result: " << fragment_shader_result 5495 << tcu::TestLog::EndMessage; 5496 5497 return false; 5498 } 5499 else 5500 { 5501 return true; 5502 } 5503 } 5504 5505 /** Write main routine of <shader_stage> shader to stream 5506 * 5507 * @param stream Output stream with source code of shader 5508 * @param shader_stage Shader stage 5509 **/ 5510 void GPUShaderFP64Test3::writeMainBody(std::ostream& stream, shaderStage shader_stage) const 5511 { 5512 glw::GLuint type_ordinal = 1; 5513 const glw::GLchar* varying_name = ""; 5514 5515 /* Select name for varying that will hold result of "that" shader_stage */ 5516 switch (shader_stage) 5517 { 5518 case FRAGMENT_SHADER: 5519 varying_name = m_varying_name_fs_out_fs_result; 5520 break; 5521 case GEOMETRY_SHADER: 5522 varying_name = m_varying_name_gs_fs_gs_result; 5523 break; 5524 case TESS_CONTROL_SHADER: 5525 varying_name = m_varying_name_tcs_tes_tcs_result; 5526 break; 5527 case TESS_EVAL_SHADER: 5528 varying_name = m_varying_name_tes_gs_tes_result; 5529 break; 5530 case VERTEX_SHADER: 5531 varying_name = m_varying_name_vs_tcs_vs_result; 5532 break; 5533 } 5534 5535 /* void main() */ 5536 stream << "void main()\n" 5537 "{\n"; 5538 5539 /* Tesselation levels output */ 5540 if (TESS_CONTROL_SHADER == shader_stage) 5541 { 5542 stream << "gl_TessLevelOuter[0] = 1.0;\n" 5543 "gl_TessLevelOuter[1] = 1.0;\n" 5544 "gl_TessLevelOuter[2] = 1.0;\n" 5545 "gl_TessLevelOuter[3] = 1.0;\n" 5546 "gl_TessLevelInner[0] = 1.0;\n" 5547 "gl_TessLevelInner[1] = 1.0;\n" 5548 "\n"; 5549 } 5550 5551 /* For each "double precision" uniform 5552 * 5553 * [else] if (TYPE_NAME(PREDIFINED_VALUES) != NAMED_UNIFORM_BLOCK_NAME.UNIFORM_NAME) 5554 * { 5555 * VARYING_NAME = m_result_failure; 5556 * } 5557 */ 5558 for (std::vector<uniformDetails>::const_iterator it = m_uniform_details.begin(), end = m_uniform_details.end(); 5559 end != it; ++it, ++type_ordinal) 5560 { 5561 stream << " "; 5562 5563 /* First comparison is done with if, next with else if */ 5564 if (1 != type_ordinal) 5565 { 5566 stream << "else "; 5567 } 5568 5569 /* if (TYPE_NAME( */ 5570 stream << "if (" << it->m_type_name << "("; 5571 5572 /* PREDIFINED_VALUES */ 5573 for (glw::GLuint element = 0; element < it->m_n_elements; ++element) 5574 { 5575 stream << getExpectedValue(type_ordinal, element); 5576 5577 /* Separate with comma */ 5578 if (it->m_n_elements != element + 1) 5579 { 5580 stream << ", "; 5581 } 5582 } 5583 5584 /* 5585 * ) != NAMED_UNIFORM_BLOCK_NAME.UNIFORM_NAME) 5586 * { 5587 * VARYING_NAME 5588 */ 5589 stream << ") != " << m_uniform_block_instance_name << "." << it->m_name << ")\n" 5590 " {\n" 5591 " " 5592 << varying_name; 5593 5594 /* Tesselation control outputs have to be arrays indexed with gl_InvocationID */ 5595 if (TESS_CONTROL_SHADER == shader_stage) 5596 { 5597 stream << "[gl_InvocationID]"; 5598 } 5599 5600 /* 5601 * = m_result_failure; 5602 * } 5603 */ 5604 stream << " = " << m_result_failure << ";\n" 5605 << " }\n"; 5606 } 5607 5608 /* If all comparisons are ok 5609 * 5610 * else 5611 * { 5612 * VARYING_NAME = m_result_success; 5613 * } 5614 */ 5615 5616 /* 5617 * else 5618 * { 5619 * VARYING_NAME 5620 */ 5621 stream << " else\n" 5622 " {\n" 5623 " " 5624 << varying_name; 5625 5626 /* Tesselation control outputs have to be arrays indexed with gl_InvocationID */ 5627 if (TESS_CONTROL_SHADER == shader_stage) 5628 { 5629 stream << "[gl_InvocationID]"; 5630 } 5631 5632 /* 5633 * = m_result_success; 5634 * } 5635 * 5636 */ 5637 stream << " = " << m_result_success << ";\n" 5638 << " }\n" 5639 << "\n"; 5640 5641 /* For each pair of "input/output" varyings 5642 * 5643 * OUTPUT_VARYING_NAME = INPUT_VARYING_NAME; 5644 **/ 5645 writeVaryingPassthrough(stream, shader_stage); 5646 5647 /* Geometry shader have to emit vertex */ 5648 if (GEOMETRY_SHADER == shader_stage) 5649 { 5650 stream << "\n" 5651 "gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);" 5652 "EmitVertex();\n" 5653 "EndPrimitive();\n"; 5654 } 5655 5656 /* Close scope of main */ 5657 stream << "}\n\n"; 5658 } 5659 5660 /** Write shader preamble to stream 5661 * 5662 * @param stream Output stream with source code of shader 5663 * @param shader_stage Shader stage 5664 **/ 5665 void GPUShaderFP64Test3::writePreamble(std::ostream& stream, shaderStage shader_stage) const 5666 { 5667 stream << "#version 400 core\n" 5668 "\n" 5669 "precision highp float;\n" 5670 "\n"; 5671 5672 switch (shader_stage) 5673 { 5674 case FRAGMENT_SHADER: 5675 break; 5676 case GEOMETRY_SHADER: 5677 stream << "layout(points) in;\n" 5678 "layout(points, max_vertices = 1) out;\n" 5679 "\n"; 5680 break; 5681 case TESS_CONTROL_SHADER: 5682 stream << "layout(vertices = 1) out;\n" 5683 "\n"; 5684 break; 5685 case TESS_EVAL_SHADER: 5686 stream << "layout(isolines, point_mode) in;\n" 5687 "\n"; 5688 break; 5689 case VERTEX_SHADER: 5690 break; 5691 } 5692 } 5693 5694 /** Write name uniform blcok definition with specific layout to stream 5695 * 5696 * @param stream Output stream with source code of shader 5697 * @param uniform_data_layout Buffer layout 5698 **/ 5699 void GPUShaderFP64Test3::writeUniformBlock(std::ostream& stream, uniformDataLayout uniform_data_layout) const 5700 { 5701 const glw::GLchar* layout = getUniformLayoutName(uniform_data_layout); 5702 5703 stream << "layout(" << layout << ") uniform " << m_uniform_block_name << "\n" 5704 "{\n" 5705 " ivec3 dummy1[3];\n" 5706 " double double_value;\n" 5707 " bool dummy2;\n" 5708 " dvec2 dvec2_value;\n" 5709 " bvec3 dummy3;\n" 5710 " dvec3 dvec3_value;\n" 5711 " int dummy4[3];\n" 5712 " dvec4 dvec4_value;\n" 5713 " bool dummy5;\n" 5714 " bool dummy6[2];\n" 5715 " dmat2 dmat2_value;\n" 5716 " dmat3 dmat3_value;\n" 5717 " bool dummy7;\n" 5718 " dmat4 dmat4_value;\n" 5719 " dmat2x3 dmat2x3_value;\n" 5720 " uvec3 dummy8;\n" 5721 " dmat2x4 dmat2x4_value;\n" 5722 " dmat3x2 dmat3x2_value;\n" 5723 " bool dummy9;\n" 5724 " dmat3x4 dmat3x4_value;\n" 5725 " int dummy10;\n" 5726 " dmat4x2 dmat4x2_value;\n" 5727 " dmat4x3 dmat4x3_value;\n" 5728 "} " 5729 << m_uniform_block_instance_name << ";\n"; 5730 5731 stream << "\n"; 5732 } 5733 5734 /** Write definitions of varyings specific for given <shader_stage> to stream 5735 * 5736 * @param stream Output stream with source code of shader 5737 * @param shader_stage Shader stage 5738 **/ 5739 void GPUShaderFP64Test3::writeVaryingDeclarations(std::ostream& stream, shaderStage shader_stage) const 5740 { 5741 static const glw::GLchar* const varying_type = "int"; 5742 5743 switch (shader_stage) 5744 { 5745 case FRAGMENT_SHADER: 5746 5747 /* In */ 5748 stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_gs_result << ";\n"; 5749 stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_tcs_result << ";\n"; 5750 stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_tes_result << ";\n"; 5751 stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_vs_result << ";\n"; 5752 5753 stream << "\n"; 5754 5755 /* Out */ 5756 stream << "layout (location = 0) out " << varying_type << " " << m_varying_name_fs_out_fs_result << ";\n"; 5757 5758 break; 5759 5760 case GEOMETRY_SHADER: 5761 5762 /* In */ 5763 stream << "in " << varying_type << " " << m_varying_name_tes_gs_tcs_result << "[];\n"; 5764 stream << "in " << varying_type << " " << m_varying_name_tes_gs_tes_result << "[];\n"; 5765 stream << "in " << varying_type << " " << m_varying_name_tes_gs_vs_result << "[];\n"; 5766 5767 stream << "\n"; 5768 5769 /* Out */ 5770 stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_gs_result << ";\n"; 5771 stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_tcs_result << ";\n"; 5772 stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_tes_result << ";\n"; 5773 stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_vs_result << ";\n"; 5774 5775 break; 5776 5777 case TESS_CONTROL_SHADER: 5778 5779 /* In */ 5780 stream << "in " << varying_type << " " << m_varying_name_vs_tcs_vs_result << "[];\n"; 5781 5782 stream << "\n"; 5783 5784 /* Out */ 5785 stream << "out " << varying_type << " " << m_varying_name_tcs_tes_tcs_result << "[];\n"; 5786 stream << "out " << varying_type << " " << m_varying_name_tcs_tes_vs_result << "[];\n"; 5787 5788 break; 5789 5790 case TESS_EVAL_SHADER: 5791 5792 /* In */ 5793 stream << "in " << varying_type << " " << m_varying_name_tcs_tes_tcs_result << "[];\n"; 5794 stream << "in " << varying_type << " " << m_varying_name_tcs_tes_vs_result << "[];\n"; 5795 5796 stream << "\n"; 5797 5798 /* Out */ 5799 stream << "out " << varying_type << " " << m_varying_name_tes_gs_tcs_result << ";\n"; 5800 stream << "out " << varying_type << " " << m_varying_name_tes_gs_tes_result << ";\n"; 5801 stream << "out " << varying_type << " " << m_varying_name_tes_gs_vs_result << ";\n"; 5802 5803 break; 5804 5805 case VERTEX_SHADER: 5806 5807 /* Out */ 5808 stream << "out " << varying_type << " " << m_varying_name_vs_tcs_vs_result << ";\n"; 5809 5810 break; 5811 } 5812 5813 stream << "\n"; 5814 } 5815 5816 /** Write passthrough code of "input/output" varying pairs to stream 5817 * 5818 * @param stream Output stream with source code of shader 5819 * @param shader_stage Shader stage 5820 **/ 5821 void GPUShaderFP64Test3::writeVaryingPassthrough(std::ostream& stream, shaderStage shader_stage) const 5822 { 5823 switch (shader_stage) 5824 { 5825 case FRAGMENT_SHADER: 5826 break; 5827 5828 case GEOMETRY_SHADER: 5829 5830 stream << " " << m_varying_name_gs_fs_tcs_result << " = " << m_varying_name_tes_gs_tcs_result << "[0];\n"; 5831 stream << " " << m_varying_name_gs_fs_tes_result << " = " << m_varying_name_tes_gs_tes_result << "[0];\n"; 5832 stream << " " << m_varying_name_gs_fs_vs_result << " = " << m_varying_name_tes_gs_vs_result << "[0];\n"; 5833 5834 break; 5835 5836 case TESS_CONTROL_SHADER: 5837 5838 stream << " " << m_varying_name_tcs_tes_vs_result 5839 << "[gl_InvocationID] = " << m_varying_name_vs_tcs_vs_result << "[0];\n"; 5840 5841 break; 5842 5843 case TESS_EVAL_SHADER: 5844 5845 stream << " " << m_varying_name_tes_gs_tcs_result << " = " << m_varying_name_tcs_tes_tcs_result << "[0];\n"; 5846 stream << " " << m_varying_name_tes_gs_vs_result << " = " << m_varying_name_tcs_tes_vs_result << "[0];\n"; 5847 5848 break; 5849 5850 case VERTEX_SHADER: 5851 5852 break; 5853 } 5854 } 5855 5856 /** Constructor. Sets all uniform locations to -1 and sets all 5857 * values to 0. 5858 */ 5859 GPUShaderFP64Test4::_data::_data() 5860 { 5861 memset(&uniform_double, 0, sizeof(uniform_double)); 5862 memset(uniform_dvec2, 0, sizeof(uniform_dvec2)); 5863 memset(uniform_dvec2_arr, 0, sizeof(uniform_dvec2_arr)); 5864 memset(uniform_dvec3, 0, sizeof(uniform_dvec3)); 5865 memset(uniform_dvec3_arr, 0, sizeof(uniform_dvec3_arr)); 5866 memset(uniform_dvec4, 0, sizeof(uniform_dvec4)); 5867 memset(uniform_dvec4_arr, 0, sizeof(uniform_dvec4_arr)); 5868 5869 uniform_location_double = -1; 5870 uniform_location_double_arr[0] = -1; 5871 uniform_location_double_arr[1] = -1; 5872 uniform_location_dvec2 = -1; 5873 uniform_location_dvec2_arr[0] = -1; 5874 uniform_location_dvec2_arr[1] = -1; 5875 uniform_location_dvec3 = -1; 5876 uniform_location_dvec3_arr[0] = -1; 5877 uniform_location_dvec3_arr[1] = -1; 5878 uniform_location_dvec4 = -1; 5879 uniform_location_dvec4_arr[0] = -1; 5880 uniform_location_dvec4_arr[1] = -1; 5881 } 5882 5883 /** Constructor 5884 * 5885 * @param context Rendering context. 5886 */ 5887 GPUShaderFP64Test4::GPUShaderFP64Test4(deqp::Context& context) 5888 : TestCase(context, "state_query", "Verifies glGet*() calls, as well as \"program interface query\"-specific tools" 5889 " report correct properties of & values assigned to double-precision uniforms.") 5890 , m_has_test_passed(true) 5891 , m_uniform_name_buffer(0) 5892 , m_cs_id(0) 5893 , m_fs_id(0) 5894 , m_gs_id(0) 5895 , m_po_cs_id(0) 5896 , m_po_noncs_id(0) 5897 , m_tc_id(0) 5898 , m_te_id(0) 5899 , m_vs_id(0) 5900 { 5901 /* Left blank intentionally */ 5902 } 5903 5904 /** Deinitializes all GL objects, as well as releases all bufers, that may 5905 * have beenallocated or created during test execution. 5906 **/ 5907 void GPUShaderFP64Test4::deinit() 5908 { 5909 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5910 5911 if (m_cs_id != 0) 5912 { 5913 gl.deleteShader(m_cs_id); 5914 5915 m_cs_id = 0; 5916 } 5917 5918 if (m_fs_id != 0) 5919 { 5920 gl.deleteShader(m_fs_id); 5921 5922 m_fs_id = 0; 5923 } 5924 5925 if (m_gs_id != 0) 5926 { 5927 gl.deleteShader(m_gs_id); 5928 5929 m_gs_id = 0; 5930 } 5931 5932 if (m_po_cs_id != 0) 5933 { 5934 gl.deleteProgram(m_po_cs_id); 5935 5936 m_po_cs_id = 0; 5937 } 5938 5939 if (m_po_noncs_id != 0) 5940 { 5941 gl.deleteProgram(m_po_noncs_id); 5942 5943 m_po_noncs_id = 0; 5944 } 5945 5946 if (m_tc_id != 0) 5947 { 5948 gl.deleteShader(m_tc_id); 5949 5950 m_tc_id = 0; 5951 } 5952 5953 if (m_te_id != 0) 5954 { 5955 gl.deleteShader(m_te_id); 5956 5957 m_te_id = 0; 5958 } 5959 5960 if (m_uniform_name_buffer != DE_NULL) 5961 { 5962 delete[] m_uniform_name_buffer; 5963 5964 m_uniform_name_buffer = DE_NULL; 5965 } 5966 5967 if (m_vs_id != 0) 5968 { 5969 gl.deleteShader(m_vs_id); 5970 5971 m_vs_id = 0; 5972 } 5973 } 5974 5975 /** Generates double-precision values for all uniforms defined for all program objects 5976 * used by the test. 5977 * 5978 * This function DOES NOT use any GL API. It only calculates & stores the values 5979 * in internal storage for further usage. 5980 */ 5981 void GPUShaderFP64Test4::generateUniformValues() 5982 { 5983 _stage_data* stages[] = { &m_data_cs, &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs }; 5984 const unsigned int n_stages = sizeof(stages) / sizeof(stages[0]); 5985 5986 for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage) 5987 { 5988 _stage_data* stage_ptr = stages[n_stage]; 5989 5990 /* Iterate through all uniform components and assign them double values */ 5991 double* double_ptrs[] = { 5992 &stage_ptr->uniform_structure_arrays[0].uniform_double, 5993 stage_ptr->uniform_structure_arrays[0].uniform_double_arr + 0, 5994 stage_ptr->uniform_structure_arrays[0].uniform_double_arr + 1, 5995 stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 0, 5996 stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 1, 5997 stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 2, 5998 stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 3, 5999 stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 0, 6000 stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 1, 6001 stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 2, 6002 stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 3, 6003 stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 4, 6004 stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 5, 6005 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 0, 6006 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 1, 6007 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 2, 6008 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 3, 6009 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 4, 6010 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 5, 6011 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 6, 6012 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 7, 6013 &stage_ptr->uniform_structure_arrays[1].uniform_double, 6014 stage_ptr->uniform_structure_arrays[1].uniform_double_arr + 0, 6015 stage_ptr->uniform_structure_arrays[1].uniform_double_arr + 1, 6016 stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 0, 6017 stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 1, 6018 stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 2, 6019 stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 3, 6020 stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 0, 6021 stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 1, 6022 stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 2, 6023 stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 3, 6024 stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 4, 6025 stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 5, 6026 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 0, 6027 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 1, 6028 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 2, 6029 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 3, 6030 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 4, 6031 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 5, 6032 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 6, 6033 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 7, 6034 &stage_ptr->uniforms.uniform_double, 6035 stage_ptr->uniforms.uniform_double_arr + 0, 6036 stage_ptr->uniforms.uniform_double_arr + 1, 6037 stage_ptr->uniforms.uniform_dvec2 + 0, 6038 stage_ptr->uniforms.uniform_dvec2 + 1, 6039 stage_ptr->uniforms.uniform_dvec2_arr + 0, 6040 stage_ptr->uniforms.uniform_dvec2_arr + 1, 6041 stage_ptr->uniforms.uniform_dvec2_arr + 2, 6042 stage_ptr->uniforms.uniform_dvec2_arr + 3, 6043 stage_ptr->uniforms.uniform_dvec3 + 0, 6044 stage_ptr->uniforms.uniform_dvec3 + 1, 6045 stage_ptr->uniforms.uniform_dvec3 + 2, 6046 stage_ptr->uniforms.uniform_dvec3_arr + 0, 6047 stage_ptr->uniforms.uniform_dvec3_arr + 1, 6048 stage_ptr->uniforms.uniform_dvec3_arr + 2, 6049 stage_ptr->uniforms.uniform_dvec3_arr + 3, 6050 stage_ptr->uniforms.uniform_dvec3_arr + 4, 6051 stage_ptr->uniforms.uniform_dvec3_arr + 5, 6052 stage_ptr->uniforms.uniform_dvec4 + 0, 6053 stage_ptr->uniforms.uniform_dvec4 + 1, 6054 stage_ptr->uniforms.uniform_dvec4 + 2, 6055 stage_ptr->uniforms.uniform_dvec4 + 3, 6056 stage_ptr->uniforms.uniform_dvec4_arr + 0, 6057 stage_ptr->uniforms.uniform_dvec4_arr + 1, 6058 stage_ptr->uniforms.uniform_dvec4_arr + 2, 6059 stage_ptr->uniforms.uniform_dvec4_arr + 3, 6060 stage_ptr->uniforms.uniform_dvec4_arr + 4, 6061 stage_ptr->uniforms.uniform_dvec4_arr + 5, 6062 stage_ptr->uniforms.uniform_dvec4_arr + 6, 6063 stage_ptr->uniforms.uniform_dvec4_arr + 7, 6064 }; 6065 const unsigned int n_double_ptrs = sizeof(double_ptrs) / sizeof(double_ptrs[0]); 6066 6067 for (unsigned int n_double_ptr = 0; n_double_ptr < n_double_ptrs; ++n_double_ptr) 6068 { 6069 double* double_ptr = double_ptrs[n_double_ptr]; 6070 6071 /* Generate the value. Use magic numbers to generate a set of double-precision 6072 * floating-point numbers. 6073 */ 6074 static int seed = 16762362; 6075 6076 *double_ptr = ((double)(seed % 1732)) / 125.7 * (((seed % 2) == 0) ? 1 : -1); 6077 6078 seed += 751; 6079 } /* for (all pointers to double variables) */ 6080 } /* for (all stages) */ 6081 } 6082 6083 /** Initializes all program & shader objects required to run the test. The function also 6084 * retrieves locations of all uniforms defined by both program objects. 6085 **/ 6086 void GPUShaderFP64Test4::initProgramObjects() 6087 { 6088 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 6089 6090 /* Create program & shader objects */ 6091 6092 /* Compute shader support and GL 4.2 required */ 6093 if ((true == m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader")) && 6094 (true == Utils::isGLVersionAtLeast(gl, 4 /* major */, 2 /* minor */))) 6095 { 6096 m_cs_id = gl.createShader(GL_COMPUTE_SHADER); 6097 } 6098 6099 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 6100 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 6101 m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER); 6102 m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER); 6103 m_vs_id = gl.createShader(GL_VERTEX_SHADER); 6104 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 6105 6106 /* m_cs_id is initialized only if compute shaders are supported */ 6107 if (0 != m_cs_id) 6108 { 6109 m_po_cs_id = gl.createProgram(); 6110 } 6111 6112 m_po_noncs_id = gl.createProgram(); 6113 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed."); 6114 6115 /* Configure compute shader body */ 6116 const char* cs_body = "#version 420\n" 6117 "#extension GL_ARB_compute_shader : require\n" 6118 "\n" 6119 "layout(local_size_x = 2, local_size_y = 2, local_size_z = 2) in;\n" 6120 "\n" 6121 "layout(rgba32f) uniform image2D testImage;\n" 6122 "\n" 6123 "uniform double cs_double;\n" 6124 "uniform dvec2 cs_dvec2;\n" 6125 "uniform dvec3 cs_dvec3;\n" 6126 "uniform dvec4 cs_dvec4;\n" 6127 "uniform double cs_double_arr[2];\n" 6128 "uniform dvec2 cs_dvec2_arr [2];\n" 6129 "uniform dvec3 cs_dvec3_arr [2];\n" 6130 "uniform dvec4 cs_dvec4_arr [2];\n" 6131 "\n" 6132 "uniform struct cs_struct\n" 6133 "{\n" 6134 " double struct_double;\n" 6135 " dvec2 struct_dvec2;\n" 6136 " dvec3 struct_dvec3;\n" 6137 " dvec4 struct_dvec4;\n" 6138 "} cs_array[2];\n" 6139 "\n" 6140 "void main()\n" 6141 "{\n" 6142 " double tmp = cs_double * cs_dvec2.x * cs_dvec3.y " 6143 " * cs_dvec4.z *\n" 6144 " cs_double_arr[0] * cs_dvec2_arr[0].x * " 6145 "cs_dvec3_arr[0].z * cs_dvec4_arr[0].w *\n" 6146 " cs_double_arr[1] * cs_dvec2_arr[1].x * " 6147 "cs_dvec3_arr[1].z * cs_dvec4_arr[1].w *\n" 6148 " cs_array[0].struct_double * cs_array[0].struct_dvec2.y * " 6149 "cs_array[0].struct_dvec3.z * cs_array[0].struct_dvec4.w *\n" 6150 " cs_array[1].struct_double * cs_array[1].struct_dvec2.y * " 6151 "cs_array[1].struct_dvec3.z * cs_array[1].struct_dvec4.w;\n" 6152 "\n" 6153 " imageStore(testImage, ivec2(0, 0), (tmp > 1.0) ? vec4(1.0) : vec4(0.0) );\n" 6154 "}\n"; 6155 6156 /* m_cs_id is initialized only if compute shaders are supported */ 6157 if (0 != m_cs_id) 6158 { 6159 gl.shaderSource(m_cs_id, 1 /* count */, &cs_body, DE_NULL /* length */); 6160 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 6161 } 6162 6163 /* Configure vertex shader body */ 6164 const char* vs_body = "#version 400\n" 6165 "\n" 6166 "uniform double vs_double;\n" 6167 "uniform dvec2 vs_dvec2;\n" 6168 "uniform dvec3 vs_dvec3;\n" 6169 "uniform dvec4 vs_dvec4;\n" 6170 "uniform double vs_double_arr[2];\n" 6171 "uniform dvec2 vs_dvec2_arr [2];\n" 6172 "uniform dvec3 vs_dvec3_arr [2];\n" 6173 "uniform dvec4 vs_dvec4_arr [2];\n" 6174 "\n" 6175 "uniform struct vs_struct\n" 6176 "{\n" 6177 " double struct_double;\n" 6178 " dvec2 struct_dvec2;\n" 6179 " dvec3 struct_dvec3;\n" 6180 " dvec4 struct_dvec4;\n" 6181 "} vs_array[2];\n" 6182 "\n" 6183 "void main()\n" 6184 "{\n" 6185 " if (vs_double * vs_dvec2.x * vs_dvec3.x " 6186 "* vs_dvec4.x *\n" 6187 " vs_double_arr[0] * vs_dvec2_arr[0].x * vs_dvec3_arr[0].x " 6188 "* vs_dvec4_arr[0].x *\n" 6189 " vs_double_arr[1] * vs_dvec2_arr[1].x * vs_dvec3_arr[1].x " 6190 "* vs_dvec4_arr[1].x *\n" 6191 " vs_array[0].struct_double * vs_array[0].struct_dvec2.x * vs_array[0].struct_dvec3.x " 6192 "* vs_array[0].struct_dvec4.x *\n" 6193 " vs_array[1].struct_double * vs_array[1].struct_dvec2.x * vs_array[1].struct_dvec3.x " 6194 "* vs_array[1].struct_dvec4.x > 1.0)\n" 6195 " {\n" 6196 " gl_Position = vec4(0);\n" 6197 " }\n" 6198 " else\n" 6199 " {\n" 6200 " gl_Position = vec4(1);\n" 6201 " }\n" 6202 "}\n"; 6203 6204 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */); 6205 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 6206 6207 /* Configure tessellation control shader body */ 6208 const char* tc_body = "#version 400\n" 6209 "\n" 6210 "uniform double tc_double;\n" 6211 "uniform dvec2 tc_dvec2;\n" 6212 "uniform dvec3 tc_dvec3;\n" 6213 "uniform dvec4 tc_dvec4;\n" 6214 "uniform double tc_double_arr[2];\n" 6215 "uniform dvec2 tc_dvec2_arr [2];\n" 6216 "uniform dvec3 tc_dvec3_arr [2];\n" 6217 "uniform dvec4 tc_dvec4_arr [2];\n" 6218 "\n" 6219 "uniform struct tc_struct\n" 6220 "{\n" 6221 " double struct_double;\n" 6222 " dvec2 struct_dvec2;\n" 6223 " dvec3 struct_dvec3;\n" 6224 " dvec4 struct_dvec4;\n" 6225 "} tc_array[2];\n" 6226 "\n" 6227 "layout(vertices = 4) out;\n" 6228 "\n" 6229 "void main()\n" 6230 "{\n" 6231 " gl_TessLevelOuter[0] = (tc_double > 1.0) ? 2.0 : 3.0;\n" 6232 " gl_TessLevelOuter[1] = (tc_dvec2.x > 1.0) ? 3.0 : 4.0;\n" 6233 " gl_TessLevelOuter[2] = (tc_dvec3.x > 1.0) ? 4.0 : 5.0;\n" 6234 " gl_TessLevelOuter[3] = (tc_dvec4.x > 1.0) ? 5.0 : 6.0;\n" 6235 " gl_TessLevelInner[0] = (tc_double_arr[0] > 1.0) ? 6.0 : 7.0;\n" 6236 " gl_TessLevelInner[1] = (tc_double_arr[1] > 1.0) ? 7.0 : 8.0;\n" 6237 "\n" 6238 " if (tc_dvec2_arr[0].y * tc_dvec2_arr[1].y *\n" 6239 " tc_dvec3_arr[0].z * tc_dvec3_arr[1].z *\n" 6240 " tc_dvec4_arr[0].z * tc_dvec4_arr[1].z *\n" 6241 " tc_array[0].struct_double * tc_array[0].struct_dvec2.x * \n" 6242 " tc_array[0].struct_dvec3.y * tc_array[0].struct_dvec4.z * \n" 6243 " tc_array[1].struct_double * tc_array[1].struct_dvec2.x * \n" 6244 " tc_array[1].struct_dvec3.y * tc_array[1].struct_dvec4.z > 0.0)\n" 6245 " {\n" 6246 " gl_TessLevelInner[1] = 3.0;\n" 6247 " }\n" 6248 "}\n"; 6249 6250 gl.shaderSource(m_tc_id, 1 /* count */, &tc_body, DE_NULL /* length */); 6251 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 6252 6253 /* Configure tessellation evaluation shader body */ 6254 const char* te_body = "#version 400\n" 6255 "\n" 6256 "uniform double te_double;\n" 6257 "uniform dvec2 te_dvec2;\n" 6258 "uniform dvec3 te_dvec3;\n" 6259 "uniform dvec4 te_dvec4;\n" 6260 "uniform double te_double_arr[2];\n" 6261 "uniform dvec2 te_dvec2_arr [2];\n" 6262 "uniform dvec3 te_dvec3_arr [2];\n" 6263 "uniform dvec4 te_dvec4_arr [2];\n" 6264 "\n" 6265 "uniform struct te_struct\n" 6266 "{\n" 6267 " double struct_double;\n" 6268 " dvec2 struct_dvec2;\n" 6269 " dvec3 struct_dvec3;\n" 6270 " dvec4 struct_dvec4;\n" 6271 "} te_array[2];\n" 6272 "\n" 6273 "layout(triangles) in;\n" 6274 "\n" 6275 "void main()\n" 6276 "{\n" 6277 " if (te_double * te_dvec2.x * te_dvec3.x " 6278 "* te_dvec4.x *\n" 6279 " te_double_arr[0] * te_dvec2_arr[0].x * te_dvec3_arr[0].x " 6280 "* te_dvec4_arr[0].x *\n" 6281 " te_double_arr[1] * te_dvec2_arr[1].x * te_dvec3_arr[1].x " 6282 "* te_dvec4_arr[1].x *\n" 6283 " te_array[0].struct_double * te_array[0].struct_dvec2.x * te_array[0].struct_dvec3.x " 6284 "* te_array[0].struct_dvec4.x *\n" 6285 " te_array[1].struct_double * te_array[1].struct_dvec2.x * te_array[1].struct_dvec3.x " 6286 "* te_array[1].struct_dvec4.x > 1.0)\n" 6287 " {\n" 6288 " gl_Position = gl_in[0].gl_Position;\n" 6289 " }\n" 6290 " else\n" 6291 " {\n" 6292 " gl_Position = gl_in[0].gl_Position + vec4(1);\n" 6293 " }\n" 6294 "}\n"; 6295 6296 gl.shaderSource(m_te_id, 1 /* count */, &te_body, DE_NULL /* length */); 6297 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 6298 6299 /* Configure geometry shader body */ 6300 const char* gs_body = "#version 400\n" 6301 "\n" 6302 "uniform double gs_double;\n" 6303 "uniform dvec2 gs_dvec2;\n" 6304 "uniform dvec3 gs_dvec3;\n" 6305 "uniform dvec4 gs_dvec4;\n" 6306 "uniform double gs_double_arr[2];\n" 6307 "uniform dvec2 gs_dvec2_arr [2];\n" 6308 "uniform dvec3 gs_dvec3_arr [2];\n" 6309 "uniform dvec4 gs_dvec4_arr [2];\n" 6310 "\n" 6311 "uniform struct gs_struct\n" 6312 "{\n" 6313 " double struct_double;\n" 6314 " dvec2 struct_dvec2;\n" 6315 " dvec3 struct_dvec3;\n" 6316 " dvec4 struct_dvec4;\n" 6317 "} gs_array[2];\n" 6318 "\n" 6319 "layout (points) in;\n" 6320 "layout (points, max_vertices = 1) out;\n" 6321 "\n" 6322 "void main()\n" 6323 "{\n" 6324 " if (gs_double * gs_dvec2.x * gs_dvec3.x " 6325 "* gs_dvec4.x *\n" 6326 " gs_double_arr[0] * gs_dvec2_arr[0].x * gs_dvec3_arr[0].x " 6327 "* gs_dvec4_arr[0].x *\n" 6328 " gs_double_arr[1] * gs_dvec2_arr[1].x * gs_dvec3_arr[1].x " 6329 "* gs_dvec4_arr[1].x *\n" 6330 " gs_array[0].struct_double * gs_array[0].struct_dvec2.x * gs_array[0].struct_dvec3.x " 6331 "* gs_array[0].struct_dvec4.x *\n" 6332 " gs_array[1].struct_double * gs_array[1].struct_dvec2.x * gs_array[1].struct_dvec3.x " 6333 "* gs_array[1].struct_dvec4.x > 1.0)\n" 6334 " {\n" 6335 " gl_Position = gl_in[0].gl_Position;\n" 6336 " }\n" 6337 " else\n" 6338 " {\n" 6339 " gl_Position = gl_in[0].gl_Position + vec4(1);\n" 6340 " }\n" 6341 "\n" 6342 " EmitVertex();\n" 6343 "}\n"; 6344 6345 gl.shaderSource(m_gs_id, 1 /* count */, &gs_body, DE_NULL /* length */); 6346 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 6347 6348 /* Configure fragment shader body */ 6349 const char* fs_body = "#version 400\n" 6350 "\n" 6351 "uniform double fs_double;\n" 6352 "uniform dvec2 fs_dvec2;\n" 6353 "uniform dvec3 fs_dvec3;\n" 6354 "uniform dvec4 fs_dvec4;\n" 6355 "uniform double fs_double_arr[2];\n" 6356 "uniform dvec2 fs_dvec2_arr [2];\n" 6357 "uniform dvec3 fs_dvec3_arr [2];\n" 6358 "uniform dvec4 fs_dvec4_arr [2];\n" 6359 "\n" 6360 "uniform struct fs_struct\n" 6361 "{\n" 6362 " double struct_double;\n" 6363 " dvec2 struct_dvec2;\n" 6364 " dvec3 struct_dvec3;\n" 6365 " dvec4 struct_dvec4;\n" 6366 "} fs_array[2];\n" 6367 "\n" 6368 "out vec4 result;\n" 6369 "\n" 6370 "void main()\n" 6371 "{\n" 6372 " if (fs_double * fs_dvec2.x * fs_dvec3.x " 6373 "* fs_dvec4.x *\n" 6374 " fs_double_arr[0] * fs_dvec2_arr[0].x * fs_dvec3_arr[0].x " 6375 "* fs_dvec4_arr[0].x *\n" 6376 " fs_double_arr[1] * fs_dvec2_arr[1].x * fs_dvec3_arr[1].x " 6377 "* fs_dvec4_arr[1].x *\n" 6378 " fs_array[0].struct_double * fs_array[0].struct_dvec2.x * fs_array[0].struct_dvec3.x " 6379 "* fs_array[0].struct_dvec4.x *\n" 6380 " fs_array[1].struct_double * fs_array[1].struct_dvec2.x * fs_array[1].struct_dvec3.x " 6381 "* fs_array[1].struct_dvec4.x > 1.0)\n" 6382 " {\n" 6383 " result = vec4(0.0);\n" 6384 " }\n" 6385 " else\n" 6386 " {\n" 6387 " result = vec4(1.0);\n" 6388 " }\n" 6389 "}\n"; 6390 6391 gl.shaderSource(m_fs_id, 1 /* count */, &fs_body, DE_NULL /* length */); 6392 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed"); 6393 6394 /* Compile the shaders */ 6395 const glw::GLuint shaders[] = { m_cs_id, m_fs_id, m_gs_id, m_tc_id, m_te_id, m_vs_id }; 6396 const unsigned int n_shaders = sizeof(shaders) / sizeof(shaders[0]); 6397 6398 for (unsigned int n_shader = 0; n_shader < n_shaders; ++n_shader) 6399 { 6400 glw::GLint compile_status = GL_FALSE; 6401 glw::GLuint so_id = shaders[n_shader]; 6402 6403 /* Skip compute shader if not supported */ 6404 if (0 == so_id) 6405 { 6406 continue; 6407 } 6408 6409 gl.compileShader(so_id); 6410 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed"); 6411 6412 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status); 6413 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed"); 6414 6415 if (compile_status != GL_TRUE) 6416 { 6417 TCU_FAIL("Shader compilation failed"); 6418 } 6419 6420 if (so_id == m_cs_id) 6421 { 6422 gl.attachShader(m_po_cs_id, so_id); 6423 } 6424 else 6425 { 6426 gl.attachShader(m_po_noncs_id, so_id); 6427 } 6428 6429 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed."); 6430 } /* for (all shaders) */ 6431 6432 /* Link the program */ 6433 const glw::GLuint programs[] = { m_po_cs_id, m_po_noncs_id }; 6434 const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]); 6435 glw::GLint link_status = GL_FALSE; 6436 6437 for (unsigned int n_program = 0; n_program < n_programs; ++n_program) 6438 { 6439 glw::GLuint po_id = programs[n_program]; 6440 6441 /* Skip compute shader program if not supported */ 6442 if (0 == po_id) 6443 { 6444 continue; 6445 } 6446 6447 gl.linkProgram(po_id); 6448 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed."); 6449 6450 gl.getProgramiv(po_id, GL_LINK_STATUS, &link_status); 6451 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed"); 6452 6453 if (link_status != GL_TRUE) 6454 { 6455 TCU_FAIL("Program linking failed"); 6456 } 6457 } /* for (both program objects) */ 6458 6459 /* Retrieve uniform locations */ 6460 _stage_data* cs_stage_data[] = { &m_data_cs }; 6461 static const char* cs_uniform_prefixes[] = { "cs_" }; 6462 static const unsigned int n_cs_uniform_prefixes = sizeof(cs_uniform_prefixes) / sizeof(cs_uniform_prefixes[0]); 6463 6464 _stage_data* noncs_stage_data[] = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs }; 6465 static const char* noncs_uniform_prefixes[] = { "fs_", "gs_", "tc_", "te_", "vs_" }; 6466 static const unsigned int n_noncs_uniform_prefixes = 6467 sizeof(noncs_uniform_prefixes) / sizeof(noncs_uniform_prefixes[0]); 6468 6469 for (unsigned int n_program = 0; n_program < n_programs; ++n_program) 6470 { 6471 unsigned int n_uniform_prefixes = DE_NULL; 6472 glw::GLuint po_id = programs[n_program]; 6473 _stage_data** stages_data = DE_NULL; 6474 const char** uniform_prefixes = DE_NULL; 6475 6476 if (n_program == 0) 6477 { 6478 stages_data = cs_stage_data; 6479 uniform_prefixes = cs_uniform_prefixes; 6480 n_uniform_prefixes = n_cs_uniform_prefixes; 6481 } 6482 else 6483 { 6484 stages_data = noncs_stage_data; 6485 uniform_prefixes = noncs_uniform_prefixes; 6486 n_uniform_prefixes = n_noncs_uniform_prefixes; 6487 } 6488 6489 /* Skip compute shader program if not supported */ 6490 if (0 == po_id) 6491 { 6492 continue; 6493 } 6494 6495 /* Uniform names used by the test program consist of a prefix (different for each 6496 * shader stage) and a common part. 6497 */ 6498 for (unsigned int n_uniform_prefix = 0; n_uniform_prefix < n_uniform_prefixes; ++n_uniform_prefix) 6499 { 6500 _stage_data* stage_data = stages_data[n_uniform_prefix]; 6501 std::string uniform_prefix = std::string(uniform_prefixes[n_uniform_prefix]); 6502 std::string uniform_double_name = uniform_prefix + "double"; 6503 std::string uniform_double_arr0_name = uniform_prefix + "double_arr[0]"; 6504 std::string uniform_double_arr1_name = uniform_prefix + "double_arr[1]"; 6505 std::string uniform_dvec2_name = uniform_prefix + "dvec2"; 6506 std::string uniform_dvec2_arr0_name = uniform_prefix + "dvec2_arr[0]"; 6507 std::string uniform_dvec2_arr1_name = uniform_prefix + "dvec2_arr[1]"; 6508 std::string uniform_dvec3_name = uniform_prefix + "dvec3"; 6509 std::string uniform_dvec3_arr0_name = uniform_prefix + "dvec3_arr[0]"; 6510 std::string uniform_dvec3_arr1_name = uniform_prefix + "dvec3_arr[1]"; 6511 std::string uniform_dvec4_name = uniform_prefix + "dvec4"; 6512 std::string uniform_dvec4_arr0_name = uniform_prefix + "dvec4_arr[0]"; 6513 std::string uniform_dvec4_arr1_name = uniform_prefix + "dvec4_arr[1]"; 6514 std::string uniform_arr0_double_name = uniform_prefix + "array[0].struct_double"; 6515 std::string uniform_arr0_dvec2_name = uniform_prefix + "array[0].struct_dvec2"; 6516 std::string uniform_arr0_dvec3_name = uniform_prefix + "array[0].struct_dvec3"; 6517 std::string uniform_arr0_dvec4_name = uniform_prefix + "array[0].struct_dvec4"; 6518 std::string uniform_arr1_double_name = uniform_prefix + "array[1].struct_double"; 6519 std::string uniform_arr1_dvec2_name = uniform_prefix + "array[1].struct_dvec2"; 6520 std::string uniform_arr1_dvec3_name = uniform_prefix + "array[1].struct_dvec3"; 6521 std::string uniform_arr1_dvec4_name = uniform_prefix + "array[1].struct_dvec4"; 6522 6523 /* Retrieve uniform locations */ 6524 stage_data->uniforms.uniform_location_double = gl.getUniformLocation(po_id, uniform_double_name.c_str()); 6525 stage_data->uniforms.uniform_location_double_arr[0] = 6526 gl.getUniformLocation(po_id, uniform_double_arr0_name.c_str()); 6527 stage_data->uniforms.uniform_location_double_arr[1] = 6528 gl.getUniformLocation(po_id, uniform_double_arr1_name.c_str()); 6529 stage_data->uniforms.uniform_location_dvec2 = gl.getUniformLocation(po_id, uniform_dvec2_name.c_str()); 6530 stage_data->uniforms.uniform_location_dvec2_arr[0] = 6531 gl.getUniformLocation(po_id, uniform_dvec2_arr0_name.c_str()); 6532 stage_data->uniforms.uniform_location_dvec2_arr[1] = 6533 gl.getUniformLocation(po_id, uniform_dvec2_arr1_name.c_str()); 6534 stage_data->uniforms.uniform_location_dvec3 = gl.getUniformLocation(po_id, uniform_dvec3_name.c_str()); 6535 stage_data->uniforms.uniform_location_dvec3_arr[0] = 6536 gl.getUniformLocation(po_id, uniform_dvec3_arr0_name.c_str()); 6537 stage_data->uniforms.uniform_location_dvec3_arr[1] = 6538 gl.getUniformLocation(po_id, uniform_dvec3_arr1_name.c_str()); 6539 stage_data->uniforms.uniform_location_dvec4 = gl.getUniformLocation(po_id, uniform_dvec4_name.c_str()); 6540 stage_data->uniforms.uniform_location_dvec4_arr[0] = 6541 gl.getUniformLocation(po_id, uniform_dvec4_arr0_name.c_str()); 6542 stage_data->uniforms.uniform_location_dvec4_arr[1] = 6543 gl.getUniformLocation(po_id, uniform_dvec4_arr1_name.c_str()); 6544 stage_data->uniform_structure_arrays[0].uniform_location_double = 6545 gl.getUniformLocation(po_id, uniform_arr0_double_name.c_str()); 6546 stage_data->uniform_structure_arrays[0].uniform_location_dvec2 = 6547 gl.getUniformLocation(po_id, uniform_arr0_dvec2_name.c_str()); 6548 stage_data->uniform_structure_arrays[0].uniform_location_dvec3 = 6549 gl.getUniformLocation(po_id, uniform_arr0_dvec3_name.c_str()); 6550 stage_data->uniform_structure_arrays[0].uniform_location_dvec4 = 6551 gl.getUniformLocation(po_id, uniform_arr0_dvec4_name.c_str()); 6552 stage_data->uniform_structure_arrays[1].uniform_location_double = 6553 gl.getUniformLocation(po_id, uniform_arr1_double_name.c_str()); 6554 stage_data->uniform_structure_arrays[1].uniform_location_dvec2 = 6555 gl.getUniformLocation(po_id, uniform_arr1_dvec2_name.c_str()); 6556 stage_data->uniform_structure_arrays[1].uniform_location_dvec3 = 6557 gl.getUniformLocation(po_id, uniform_arr1_dvec3_name.c_str()); 6558 stage_data->uniform_structure_arrays[1].uniform_location_dvec4 = 6559 gl.getUniformLocation(po_id, uniform_arr1_dvec4_name.c_str()); 6560 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call(s) failed."); 6561 6562 if (stage_data->uniforms.uniform_location_double == -1 || 6563 stage_data->uniforms.uniform_location_double_arr[0] == -1 || 6564 stage_data->uniforms.uniform_location_double_arr[1] == -1 || 6565 stage_data->uniforms.uniform_location_dvec2 == -1 || 6566 stage_data->uniforms.uniform_location_dvec2_arr[0] == -1 || 6567 stage_data->uniforms.uniform_location_dvec2_arr[1] == -1 || 6568 stage_data->uniforms.uniform_location_dvec3 == -1 || 6569 stage_data->uniforms.uniform_location_dvec3_arr[0] == -1 || 6570 stage_data->uniforms.uniform_location_dvec3_arr[1] == -1 || 6571 stage_data->uniforms.uniform_location_dvec4 == -1 || 6572 stage_data->uniforms.uniform_location_dvec4_arr[0] == -1 || 6573 stage_data->uniforms.uniform_location_dvec4_arr[1] == -1 || 6574 stage_data->uniform_structure_arrays[0].uniform_location_double == -1 || 6575 stage_data->uniform_structure_arrays[0].uniform_location_dvec2 == -1 || 6576 stage_data->uniform_structure_arrays[0].uniform_location_dvec3 == -1 || 6577 stage_data->uniform_structure_arrays[0].uniform_location_dvec4 == -1 || 6578 stage_data->uniform_structure_arrays[1].uniform_location_double == -1 || 6579 stage_data->uniform_structure_arrays[1].uniform_location_dvec2 == -1 || 6580 stage_data->uniform_structure_arrays[1].uniform_location_dvec3 == -1 || 6581 stage_data->uniform_structure_arrays[1].uniform_location_dvec4 == -1) 6582 { 6583 TCU_FAIL("At least one uniform is considered inactive which is invalid."); 6584 } 6585 6586 /* Make sure locations of subsequent items in array uniforms are correct */ 6587 if (stage_data->uniforms.uniform_location_double_arr[1] != 6588 (stage_data->uniforms.uniform_location_double_arr[0] + 1) || 6589 stage_data->uniforms.uniform_location_dvec2_arr[1] != 6590 (stage_data->uniforms.uniform_location_dvec2_arr[0] + 1) || 6591 stage_data->uniforms.uniform_location_dvec3_arr[1] != 6592 (stage_data->uniforms.uniform_location_dvec3_arr[0] + 1) || 6593 stage_data->uniforms.uniform_location_dvec4_arr[1] != 6594 (stage_data->uniforms.uniform_location_dvec4_arr[0] + 1)) 6595 { 6596 m_testCtx.getLog() << tcu::TestLog::Message << "Uniform locations:" 6597 " double_arr[0]:" 6598 << stage_data->uniforms.uniform_location_double_arr[0] 6599 << " double_arr[1]:" << stage_data->uniforms.uniform_location_double_arr[1] 6600 << " dvec2_arr[0]:" << stage_data->uniforms.uniform_location_dvec2_arr[0] 6601 << " dvec2_arr[1]:" << stage_data->uniforms.uniform_location_dvec2_arr[1] 6602 << " dvec3_arr[0]:" << stage_data->uniforms.uniform_location_dvec3_arr[0] 6603 << " dvec3_arr[1]:" << stage_data->uniforms.uniform_location_dvec3_arr[1] 6604 << " dvec4_arr[0]:" << stage_data->uniforms.uniform_location_dvec4_arr[0] 6605 << " dvec4_arr[1]:" << stage_data->uniforms.uniform_location_dvec4_arr[1] 6606 << tcu::TestLog::EndMessage; 6607 6608 TCU_FAIL("Double-precision uniform array item locations are invalid."); 6609 } 6610 } /* for (all uniform prefixes) */ 6611 } /* for (both program objects) */ 6612 } 6613 6614 /** Initializes all objects required to run the test. */ 6615 void GPUShaderFP64Test4::initTest() 6616 { 6617 initProgramObjects(); 6618 6619 generateUniformValues(); 6620 initUniformValues(); 6621 } 6622 6623 /** Assigns values generated by generateUniformValues() to uniforms defined by 6624 * both program objects. 6625 **/ 6626 void GPUShaderFP64Test4::initUniformValues() 6627 { 6628 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 6629 6630 /* Iterate through all programs */ 6631 _stage_data* cs_stages[] = { &m_data_cs }; 6632 _stage_data* noncs_stages[] = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs }; 6633 const unsigned int n_cs_stages = sizeof(cs_stages) / sizeof(cs_stages[0]); 6634 const unsigned int n_noncs_stages = sizeof(noncs_stages) / sizeof(noncs_stages[0]); 6635 6636 const glw::GLuint programs[] = { m_po_cs_id, m_po_noncs_id }; 6637 const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]); 6638 6639 for (unsigned int n_program = 0; n_program < n_programs; ++n_program) 6640 { 6641 glw::GLuint po_id = programs[n_program]; 6642 unsigned int n_stages = 0; 6643 _stage_data** stage_data = DE_NULL; 6644 6645 if (po_id == m_po_cs_id) 6646 { 6647 n_stages = n_cs_stages; 6648 stage_data = cs_stages; 6649 } 6650 else 6651 { 6652 n_stages = n_noncs_stages; 6653 stage_data = noncs_stages; 6654 } 6655 6656 /* Skip compute shader program if not supported */ 6657 if (0 == po_id) 6658 { 6659 continue; 6660 } 6661 6662 gl.useProgram(po_id); 6663 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram"); 6664 6665 for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage) 6666 { 6667 /* Iterate through all uniforms */ 6668 _stage_data* stage_ptr = stage_data[n_stage]; 6669 6670 gl.uniform1d(stage_ptr->uniforms.uniform_location_double, stage_ptr->uniforms.uniform_double); 6671 gl.uniform1d(stage_ptr->uniforms.uniform_location_double_arr[0], stage_ptr->uniforms.uniform_double_arr[0]); 6672 gl.uniform1d(stage_ptr->uniforms.uniform_location_double_arr[1], stage_ptr->uniforms.uniform_double_arr[1]); 6673 gl.uniform1d(stage_ptr->uniform_structure_arrays[0].uniform_location_double, 6674 stage_ptr->uniform_structure_arrays[0].uniform_double); 6675 gl.uniform1d(stage_ptr->uniform_structure_arrays[1].uniform_location_double, 6676 stage_ptr->uniform_structure_arrays[1].uniform_double); 6677 GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform1d() call(s) failed."); 6678 6679 gl.uniform2dv(stage_ptr->uniforms.uniform_location_dvec2, 1 /* count */, stage_ptr->uniforms.uniform_dvec2); 6680 gl.uniform2dv(stage_ptr->uniforms.uniform_location_dvec2_arr[0], 1 /* count */, 6681 stage_ptr->uniforms.uniform_dvec2_arr + 0); 6682 gl.uniform2dv(stage_ptr->uniforms.uniform_location_dvec2_arr[1], 1 /* count */, 6683 stage_ptr->uniforms.uniform_dvec2_arr + 2); 6684 gl.uniform2dv(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec2, 1 /* count */, 6685 stage_ptr->uniform_structure_arrays[0].uniform_dvec2); 6686 gl.uniform2dv(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec2, 1 /* count */, 6687 stage_ptr->uniform_structure_arrays[1].uniform_dvec2); 6688 GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform2dv() call(s) failed."); 6689 6690 gl.uniform3dv(stage_ptr->uniforms.uniform_location_dvec3, 1 /* count */, stage_ptr->uniforms.uniform_dvec3); 6691 gl.uniform3dv(stage_ptr->uniforms.uniform_location_dvec3_arr[0], 1 /* count */, 6692 stage_ptr->uniforms.uniform_dvec3_arr + 0); 6693 gl.uniform3dv(stage_ptr->uniforms.uniform_location_dvec3_arr[1], 1 /* count */, 6694 stage_ptr->uniforms.uniform_dvec3_arr + 3); 6695 gl.uniform3dv(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec3, 1 /* count */, 6696 stage_ptr->uniform_structure_arrays[0].uniform_dvec3); 6697 gl.uniform3dv(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec3, 1 /* count */, 6698 stage_ptr->uniform_structure_arrays[1].uniform_dvec3); 6699 GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform3dv() call(s) failed."); 6700 6701 gl.uniform4dv(stage_ptr->uniforms.uniform_location_dvec4, 1 /* count */, stage_ptr->uniforms.uniform_dvec4); 6702 gl.uniform4dv(stage_ptr->uniforms.uniform_location_dvec4_arr[0], 1 /* count */, 6703 stage_ptr->uniforms.uniform_dvec4_arr + 0); 6704 gl.uniform4dv(stage_ptr->uniforms.uniform_location_dvec4_arr[1], 1 /* count */, 6705 stage_ptr->uniforms.uniform_dvec4_arr + 4); 6706 gl.uniform4dv(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec4, 1 /* count */, 6707 stage_ptr->uniform_structure_arrays[0].uniform_dvec4); 6708 gl.uniform4dv(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec4, 1 /* count */, 6709 stage_ptr->uniform_structure_arrays[1].uniform_dvec4); 6710 GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform4dv() call(s) failed."); 6711 } /* for (all shader stages) */ 6712 } /* for (both program objects) */ 6713 } 6714 6715 /** Executes test iteration. 6716 * 6717 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 6718 */ 6719 tcu::TestNode::IterateResult GPUShaderFP64Test4::iterate() 6720 { 6721 /* This test does not verify GL_ARB_gpu_shader_fp64 support on purpose */ 6722 6723 /* Initialize all objects required to run the test */ 6724 initTest(); 6725 6726 /* Verify the implementation reports correct values for all stages we've configured */ 6727 m_has_test_passed &= verifyUniformValues(); 6728 6729 /* Is this also the case when "program interface query" mechanism is used? */ 6730 if (m_context.getContextInfo().isExtensionSupported("GL_ARB_program_interface_query")) 6731 { 6732 m_has_test_passed &= verifyProgramInterfaceQuerySupport(); 6733 } 6734 6735 /* We're done */ 6736 if (m_has_test_passed) 6737 { 6738 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 6739 } 6740 else 6741 { 6742 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 6743 } 6744 6745 return STOP; 6746 } 6747 6748 /** Verifies that: 6749 * 6750 * a) glGetProgramResourceIndex() 6751 * b) glGetProgramResourceiv() 6752 * c) glGetProgramResourceName() 6753 * 6754 * functions return correct values for double-precision uniforms. 6755 * 6756 * @return true if the verification was passed, false otherwise. 6757 */ 6758 bool GPUShaderFP64Test4::verifyProgramInterfaceQuerySupport() 6759 { 6760 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 6761 bool result = true; 6762 6763 /* Iterate through all programs */ 6764 const char* cs_prefixes[] = { "cs_" }; 6765 _stage_data* cs_stages[] = { &m_data_cs }; 6766 const char* noncs_prefixes[] = { "fs_", "gs_", "tc_", "te_", "vs_" }; 6767 _stage_data* noncs_stages[] = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs }; 6768 const unsigned int n_cs_stages = sizeof(cs_stages) / sizeof(cs_stages[0]); 6769 const unsigned int n_noncs_stages = sizeof(noncs_stages) / sizeof(noncs_stages[0]); 6770 6771 const glw::GLuint programs[] = { m_po_cs_id, m_po_noncs_id }; 6772 const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]); 6773 6774 for (unsigned int n_program = 0; n_program < n_programs; ++n_program) 6775 { 6776 glw::GLuint po_id = programs[n_program]; 6777 unsigned int n_stages = 0; 6778 const char** stage_prefixes = DE_NULL; 6779 _stage_data** stage_data = DE_NULL; 6780 6781 if (po_id == m_po_cs_id) 6782 { 6783 n_stages = n_cs_stages; 6784 stage_data = cs_stages; 6785 stage_prefixes = cs_prefixes; 6786 } 6787 else 6788 { 6789 n_stages = n_noncs_stages; 6790 stage_data = noncs_stages; 6791 stage_prefixes = noncs_prefixes; 6792 } 6793 6794 /* Skip compute shader program if not supported */ 6795 if (0 == po_id) 6796 { 6797 continue; 6798 } 6799 6800 /* Determine maximum uniform name length */ 6801 glw::GLint max_uniform_name_length = 0; 6802 6803 gl.getProgramInterfaceiv(po_id, GL_UNIFORM, GL_MAX_NAME_LENGTH, &max_uniform_name_length); 6804 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInterfaceiv() call failed."); 6805 6806 /* Allocate a buffer we will use to hold uniform names */ 6807 m_uniform_name_buffer = new char[max_uniform_name_length]; 6808 6809 for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage) 6810 { 6811 /* Iterate through all uniforms */ 6812 _stage_data* stage_ptr = stage_data[n_stage]; 6813 const char* stage_prefix = stage_prefixes[n_stage]; 6814 6815 /* Construct an array that will be used to run the test in an automated manner */ 6816 _program_interface_query_test_item uniforms[] = { 6817 /* array size */ /* name */ /* type */ /* location */ 6818 { 1, "double", GL_DOUBLE, stage_ptr->uniforms.uniform_location_double }, 6819 { 2, "double_arr[0]", GL_DOUBLE, stage_ptr->uniforms.uniform_location_double_arr[0] }, 6820 { 1, "dvec2", GL_DOUBLE_VEC2, stage_ptr->uniforms.uniform_location_dvec2 }, 6821 { 2, "dvec2_arr[0]", GL_DOUBLE_VEC2, stage_ptr->uniforms.uniform_location_dvec2_arr[0] }, 6822 { 1, "dvec3", GL_DOUBLE_VEC3, stage_ptr->uniforms.uniform_location_dvec3 }, 6823 { 2, "dvec3_arr[0]", GL_DOUBLE_VEC3, stage_ptr->uniforms.uniform_location_dvec3_arr[0] }, 6824 { 1, "dvec4", GL_DOUBLE_VEC4, stage_ptr->uniforms.uniform_location_dvec4 }, 6825 { 2, "dvec4_arr[0]", GL_DOUBLE_VEC4, stage_ptr->uniforms.uniform_location_dvec4_arr[0] }, 6826 { 1, "array[0].struct_double", GL_DOUBLE, 6827 stage_ptr->uniform_structure_arrays->uniform_location_double }, 6828 { 1, "array[0].struct_dvec2", GL_DOUBLE_VEC2, 6829 stage_ptr->uniform_structure_arrays->uniform_location_dvec2 }, 6830 { 1, "array[0].struct_dvec3", GL_DOUBLE_VEC3, 6831 stage_ptr->uniform_structure_arrays->uniform_location_dvec3 }, 6832 { 1, "array[0].struct_dvec4", GL_DOUBLE_VEC4, 6833 stage_ptr->uniform_structure_arrays->uniform_location_dvec4 }, 6834 { 1, "array[1].struct_double", GL_DOUBLE, 6835 stage_ptr->uniform_structure_arrays->uniform_location_double }, 6836 { 1, "array[1].struct_dvec2", GL_DOUBLE_VEC2, 6837 stage_ptr->uniform_structure_arrays->uniform_location_dvec2 }, 6838 { 1, "array[1].struct_dvec3", GL_DOUBLE_VEC3, 6839 stage_ptr->uniform_structure_arrays->uniform_location_dvec3 }, 6840 { 1, "array[1].struct_dvec4", GL_DOUBLE_VEC4, 6841 stage_ptr->uniform_structure_arrays->uniform_location_dvec4 }, 6842 }; 6843 const unsigned int n_uniforms = sizeof(uniforms) / sizeof(uniforms[0]); 6844 6845 /* Prefix the names with stage-specific string */ 6846 for (unsigned int n_uniform = 0; n_uniform < n_uniforms; ++n_uniform) 6847 { 6848 _program_interface_query_test_item& current_item = uniforms[n_uniform]; 6849 6850 current_item.name = std::string(stage_prefix) + current_item.name; 6851 } /* for (all uniform descriptors) */ 6852 6853 const glw::GLenum properties[] = { GL_ARRAY_SIZE, GL_TYPE }; 6854 const unsigned int n_properties = sizeof(properties) / sizeof(properties[0]); 6855 6856 for (unsigned int n_uniform = 0; n_uniform < n_uniforms; ++n_uniform) 6857 { 6858 _program_interface_query_test_item& current_item = uniforms[n_uniform]; 6859 glw::GLint n_written_items = 0; 6860 glw::GLint retrieved_array_size = 0; 6861 glw::GLint retrieved_name_length = 0; 6862 glw::GLenum retrieved_type = GL_NONE; 6863 glw::GLint temp_buffer[2] = { 0, GL_NONE }; 6864 6865 /* Retrieve index of the iteration-specific uniform */ 6866 glw::GLuint resource_index = gl.getProgramResourceIndex(po_id, GL_UNIFORM, current_item.name.c_str()); 6867 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceIndex() call failed."); 6868 6869 /* Make sure glGetProgramResourceName() returns correct values */ 6870 memset(m_uniform_name_buffer, 0, max_uniform_name_length); 6871 6872 gl.getProgramResourceName(po_id, GL_UNIFORM, /* interface */ 6873 resource_index, max_uniform_name_length, &retrieved_name_length, 6874 m_uniform_name_buffer); 6875 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceName() call failed."); 6876 6877 if (current_item.name.length() != (glw::GLuint)retrieved_name_length || 6878 memcmp(m_uniform_name_buffer, current_item.name.c_str(), retrieved_name_length) != 0) 6879 { 6880 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid uniform name was reported at index [" 6881 << resource_index << "]" 6882 ": expected:[" 6883 << current_item.name << "]" 6884 ", reported:[" 6885 << m_uniform_name_buffer << "]" << tcu::TestLog::EndMessage; 6886 6887 result = false; 6888 continue; 6889 } 6890 6891 /* Make sure glGetProgramResourceiv() returns correct values for GL_TYPE and GL_ARRAY_SIZE queries */ 6892 gl.getProgramResourceiv(po_id, GL_UNIFORM, /* interface */ 6893 resource_index, n_properties, properties, 6894 sizeof(temp_buffer) / sizeof(temp_buffer[0]), &n_written_items, temp_buffer); 6895 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceiv() call failed."); 6896 6897 if (n_written_items != n_properties) 6898 { 6899 TCU_FAIL("Invalid amount of items were reported by glGetProgramResourceiv() call."); 6900 } 6901 6902 /* For clarity, copy the retrieved values to separate variables */ 6903 retrieved_array_size = temp_buffer[0]; 6904 retrieved_type = temp_buffer[1]; 6905 6906 /* Verify the values */ 6907 if (retrieved_array_size != current_item.expected_array_size) 6908 { 6909 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid array size reported for uniform [" 6910 << current_item.name << "]" 6911 << ": expected:[" << current_item.expected_array_size << "]" 6912 ", reported:[" 6913 << retrieved_array_size << "]" << tcu::TestLog::EndMessage; 6914 6915 result = false; 6916 } 6917 6918 if (retrieved_type != current_item.expected_type) 6919 { 6920 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid type reported for uniform [" 6921 << current_item.name << "]" 6922 << ": expected:[" << current_item.expected_type << "]" 6923 ", reported:[" 6924 << retrieved_type << "]" << tcu::TestLog::EndMessage; 6925 6926 result = false; 6927 } 6928 } /* for (all uniforms) */ 6929 } /* for (all shader stages) */ 6930 6931 /* We're now OK to release the buffer we used to hold uniform names for 6932 * the program */ 6933 if (m_uniform_name_buffer != DE_NULL) 6934 { 6935 delete[] m_uniform_name_buffer; 6936 6937 m_uniform_name_buffer = DE_NULL; 6938 } 6939 } /* for (both program objects) */ 6940 6941 return result; 6942 } 6943 6944 /** Verifies glGetUniform*() calls return correct values assigned to 6945 * double-precision uniforms. 6946 * 6947 * @return true if all values reported by OpenGL were found to be correct, 6948 * false otherwise. 6949 **/ 6950 bool GPUShaderFP64Test4::verifyUniformValues() 6951 { 6952 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 6953 bool result = true; 6954 6955 /* Iterate through all programs */ 6956 _stage_data* cs_stages[] = { &m_data_cs }; 6957 _stage_data* noncs_stages[] = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs }; 6958 const unsigned int n_cs_stages = sizeof(cs_stages) / sizeof(cs_stages[0]); 6959 const unsigned int n_noncs_stages = sizeof(noncs_stages) / sizeof(noncs_stages[0]); 6960 6961 const glw::GLuint programs[] = { 6962 m_po_noncs_id, m_po_cs_id, 6963 }; 6964 const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]); 6965 6966 /* Set up rounding for the tests */ 6967 deSetRoundingMode(DE_ROUNDINGMODE_TO_NEAREST_EVEN); 6968 6969 for (unsigned int n_program = 0; n_program < n_programs; ++n_program) 6970 { 6971 glw::GLuint po_id = programs[n_program]; 6972 unsigned int n_stages = 0; 6973 _stage_data** stage_data = DE_NULL; 6974 6975 if (po_id == m_po_cs_id) 6976 { 6977 n_stages = n_cs_stages; 6978 stage_data = cs_stages; 6979 } 6980 else 6981 { 6982 n_stages = n_noncs_stages; 6983 stage_data = noncs_stages; 6984 } 6985 6986 /* Skip compute shader program if not supported */ 6987 if (0 == po_id) 6988 { 6989 continue; 6990 } 6991 6992 for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage) 6993 { 6994 /* Iterate through all uniforms */ 6995 _stage_data* stage_ptr = stage_data[n_stage]; 6996 6997 /* Set up arrays that we will guide the automated testing */ 6998 const uniform_value_pair double_uniforms[] = { 6999 uniform_value_pair(stage_ptr->uniforms.uniform_location_double, &stage_ptr->uniforms.uniform_double), 7000 uniform_value_pair(stage_ptr->uniforms.uniform_location_double_arr[0], 7001 stage_ptr->uniforms.uniform_double_arr + 0), 7002 uniform_value_pair(stage_ptr->uniforms.uniform_location_double_arr[1], 7003 stage_ptr->uniforms.uniform_double_arr + 1), 7004 uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_double, 7005 &stage_ptr->uniform_structure_arrays[0].uniform_double), 7006 uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_double, 7007 &stage_ptr->uniform_structure_arrays[1].uniform_double) 7008 }; 7009 const uniform_value_pair dvec2_uniforms[] = { 7010 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec2, stage_ptr->uniforms.uniform_dvec2), 7011 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec2_arr[0], 7012 stage_ptr->uniforms.uniform_dvec2_arr + 0), 7013 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec2_arr[1], 7014 stage_ptr->uniforms.uniform_dvec2_arr + 2), 7015 uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec2, 7016 stage_ptr->uniform_structure_arrays[0].uniform_dvec2), 7017 uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec2, 7018 stage_ptr->uniform_structure_arrays[1].uniform_dvec2) 7019 }; 7020 const uniform_value_pair dvec3_uniforms[] = { 7021 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec3, stage_ptr->uniforms.uniform_dvec3), 7022 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec3_arr[0], 7023 stage_ptr->uniforms.uniform_dvec3_arr + 0), 7024 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec3_arr[1], 7025 stage_ptr->uniforms.uniform_dvec3_arr + 3), 7026 uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec3, 7027 stage_ptr->uniform_structure_arrays[0].uniform_dvec3), 7028 uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec3, 7029 stage_ptr->uniform_structure_arrays[1].uniform_dvec3) 7030 }; 7031 const uniform_value_pair dvec4_uniforms[] = { 7032 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec4, stage_ptr->uniforms.uniform_dvec4), 7033 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec4_arr[0], 7034 stage_ptr->uniforms.uniform_dvec4_arr + 0), 7035 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec4_arr[1], 7036 stage_ptr->uniforms.uniform_dvec4_arr + 4), 7037 uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec4, 7038 stage_ptr->uniform_structure_arrays[0].uniform_dvec4), 7039 uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec4, 7040 stage_ptr->uniform_structure_arrays[1].uniform_dvec4) 7041 }; 7042 7043 /* Iterate over all uniforms and verify the values reported by the API */ 7044 double returned_double_data[4]; 7045 float returned_float_data[4]; 7046 int returned_int_data[4]; 7047 unsigned int returned_uint_data[4]; 7048 7049 for (unsigned int n_type = 0; n_type < 4 /* double/dvec2/dvec3/dvec4 */; ++n_type) 7050 { 7051 const uniform_value_pair* current_uv_pairs = NULL; 7052 const unsigned int n_components_used = n_type + 1; /* n_type=0: double, n_type=1: dvec2, etc.. */ 7053 unsigned int n_pairs = 0; 7054 7055 switch (n_type) 7056 { 7057 case 0: /* double */ 7058 { 7059 current_uv_pairs = double_uniforms; 7060 n_pairs = sizeof(double_uniforms) / sizeof(double_uniforms[0]); 7061 7062 break; 7063 } 7064 7065 case 1: /* dvec2 */ 7066 { 7067 current_uv_pairs = dvec2_uniforms; 7068 n_pairs = sizeof(dvec2_uniforms) / sizeof(dvec2_uniforms[0]); 7069 7070 break; 7071 } 7072 7073 case 2: /* dvec3 */ 7074 { 7075 current_uv_pairs = dvec3_uniforms; 7076 n_pairs = sizeof(dvec3_uniforms) / sizeof(dvec3_uniforms[0]); 7077 7078 break; 7079 } 7080 7081 case 3: /* dvec4 */ 7082 { 7083 current_uv_pairs = dvec4_uniforms; 7084 n_pairs = sizeof(dvec4_uniforms) / sizeof(dvec4_uniforms[0]); 7085 7086 break; 7087 } 7088 7089 default: 7090 { 7091 TCU_FAIL("Invalid type index requested"); 7092 } 7093 } /* switch (n_type) */ 7094 7095 for (unsigned int n_pair = 0; n_pair < n_pairs; ++n_pair) 7096 { 7097 const uniform_value_pair& current_uv_pair = current_uv_pairs[n_pair]; 7098 glw::GLint uniform_location = current_uv_pair.first; 7099 const double* uniform_value = current_uv_pair.second; 7100 7101 /* Retrieve the values from the GL implementation*/ 7102 gl.getUniformdv(po_id, uniform_location, returned_double_data); 7103 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformdv() call failed."); 7104 7105 gl.getUniformfv(po_id, uniform_location, returned_float_data); 7106 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformfv() call failed."); 7107 7108 gl.getUniformiv(po_id, uniform_location, returned_int_data); 7109 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformiv() call failed."); 7110 7111 gl.getUniformuiv(po_id, uniform_location, returned_uint_data); 7112 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformuiv() call failed."); 7113 7114 /* Make sure the values reported match the reference values */ 7115 bool can_continue = true; 7116 const float epsilon = 1e-5f; 7117 7118 for (unsigned int n_component = 0; n_component < n_components_used && can_continue; ++n_component) 7119 { 7120 if (de::abs(returned_double_data[n_component] - uniform_value[n_component]) > epsilon) 7121 { 7122 m_testCtx.getLog() 7123 << tcu::TestLog::Message 7124 << "Invalid uniform value reported by glGetUniformdv() for uniform location [" 7125 << uniform_location << "]" 7126 " and component [" 7127 << n_component << "]" 7128 ": retrieved:[" 7129 << returned_double_data[n_component] << "]" 7130 ", expected:[" 7131 << uniform_value[n_component] << "]" << tcu::TestLog::EndMessage; 7132 7133 result = false; 7134 } 7135 7136 if (de::abs(returned_float_data[n_component] - uniform_value[n_component]) > epsilon) 7137 { 7138 m_testCtx.getLog() 7139 << tcu::TestLog::Message 7140 << "Invalid uniform value reported by glGetUniformfv() for uniform location [" 7141 << uniform_location << "]" 7142 " and component [" 7143 << n_component << "]" 7144 ": retrieved:[" 7145 << returned_float_data[n_component] << "]" 7146 ", expected:[" 7147 << uniform_value[n_component] << "]" << tcu::TestLog::EndMessage; 7148 7149 result = false; 7150 } 7151 7152 /* ints */ 7153 int rounded_uniform_value_sint = (int)(deFloatRound((float)uniform_value[n_component])); 7154 unsigned int rounded_uniform_value_uint = 7155 (unsigned int)(uniform_value[n_component] > 0.0) ? 7156 ((unsigned int)deFloatRound((float)uniform_value[n_component])) : 7157 0; 7158 7159 if (returned_int_data[n_component] != rounded_uniform_value_sint) 7160 { 7161 m_testCtx.getLog() 7162 << tcu::TestLog::Message 7163 << "Invalid uniform value reported by glGetUniformiv() for uniform location [" 7164 << uniform_location << "]" 7165 " and component [" 7166 << n_component << "]" 7167 ": retrieved:[" 7168 << returned_int_data[n_component] << "]" 7169 ", expected:[" 7170 << rounded_uniform_value_sint << "]" << tcu::TestLog::EndMessage; 7171 7172 result = false; 7173 } 7174 7175 if (returned_uint_data[n_component] != rounded_uniform_value_uint) 7176 { 7177 m_testCtx.getLog() 7178 << tcu::TestLog::Message 7179 << "Invalid uniform value reported by glGetUniformuiv() for uniform location [" 7180 << uniform_location << "]" 7181 " and component [" 7182 << n_component << "]" 7183 ": retrieved:[" 7184 << returned_uint_data[n_component] << "]" 7185 ", expected:[" 7186 << rounded_uniform_value_uint << "]" << tcu::TestLog::EndMessage; 7187 7188 result = false; 7189 } 7190 } /* for (all components) */ 7191 } /* for (all uniform+value pairs) */ 7192 } /* for (all 4 uniform types) */ 7193 } /* for (all shader stages) */ 7194 } /* for (both program objects) */ 7195 7196 /* All done! */ 7197 return result; 7198 } 7199 7200 /** Constructor 7201 * 7202 * @param context Rendering context. 7203 */ 7204 GPUShaderFP64Test5::GPUShaderFP64Test5(deqp::Context& context) 7205 : TestCase(context, "conversions", "Verifies explicit and implicit casts involving double-precision" 7206 " floating-point variables work correctly") 7207 , m_base_value_bo_data(DE_NULL) 7208 , m_base_value_bo_id(0) 7209 , m_has_test_passed(true) 7210 , m_po_base_value_attribute_location(-1) 7211 , m_po_id(0) 7212 , m_vao_id(0) 7213 , m_vs_id(0) 7214 , m_xfb_bo_id(0) 7215 , m_xfb_bo_size(0) 7216 { 7217 /* Set up base value array (as per test spec) */ 7218 m_base_values[0] = -25.12065f; 7219 m_base_values[1] = 0.0f; 7220 m_base_values[2] = 0.001f; 7221 m_base_values[3] = 1.0f; 7222 m_base_values[4] = 256.78901f; 7223 7224 /* Set up swizzle matrix */ 7225 m_swizzle_matrix[0][0] = SWIZZLE_TYPE_NONE; 7226 m_swizzle_matrix[0][1] = SWIZZLE_TYPE_Y; 7227 m_swizzle_matrix[0][2] = SWIZZLE_TYPE_Z; 7228 m_swizzle_matrix[0][3] = SWIZZLE_TYPE_W; 7229 m_swizzle_matrix[1][0] = SWIZZLE_TYPE_NONE; 7230 m_swizzle_matrix[1][1] = SWIZZLE_TYPE_YX; 7231 m_swizzle_matrix[1][2] = SWIZZLE_TYPE_ZY; 7232 m_swizzle_matrix[1][3] = SWIZZLE_TYPE_WX; 7233 m_swizzle_matrix[2][0] = SWIZZLE_TYPE_NONE; 7234 m_swizzle_matrix[2][1] = SWIZZLE_TYPE_YXX; 7235 m_swizzle_matrix[2][2] = SWIZZLE_TYPE_XZY; 7236 m_swizzle_matrix[2][3] = SWIZZLE_TYPE_XWZY; 7237 m_swizzle_matrix[3][0] = SWIZZLE_TYPE_NONE; 7238 m_swizzle_matrix[3][1] = SWIZZLE_TYPE_YXXY; 7239 m_swizzle_matrix[3][2] = SWIZZLE_TYPE_XZXY; 7240 m_swizzle_matrix[3][3] = SWIZZLE_TYPE_XZYW; 7241 } 7242 7243 void GPUShaderFP64Test5::deinit() 7244 { 7245 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 7246 7247 if (m_base_value_bo_data != DE_NULL) 7248 { 7249 delete[] m_base_value_bo_data; 7250 7251 m_base_value_bo_data = DE_NULL; 7252 } 7253 7254 if (m_base_value_bo_id != 0) 7255 { 7256 gl.deleteBuffers(1, &m_base_value_bo_id); 7257 7258 m_base_value_bo_id = 0; 7259 } 7260 7261 if (m_vao_id != 0) 7262 { 7263 gl.deleteVertexArrays(1, &m_vao_id); 7264 7265 m_vao_id = 0; 7266 } 7267 7268 if (m_xfb_bo_id != 0) 7269 { 7270 gl.deleteBuffers(1, &m_xfb_bo_id); 7271 7272 m_xfb_bo_id = 0; 7273 } 7274 7275 /* TCU_FAIL will skip the per sub test iteration de-initialization, we need to 7276 * take care of it here 7277 */ 7278 deinitInteration(); 7279 } 7280 7281 /** Deinitializes all buffers and GL objects that may have been generated 7282 * during test execution. 7283 **/ 7284 void GPUShaderFP64Test5::deinitInteration() 7285 { 7286 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 7287 7288 if (m_po_id != 0) 7289 { 7290 gl.deleteProgram(m_po_id); 7291 7292 m_po_id = 0; 7293 } 7294 7295 if (m_vs_id != 0) 7296 { 7297 gl.deleteShader(m_vs_id); 7298 7299 m_vs_id = 0; 7300 } 7301 } 7302 7303 /** Executes a single test case iteration using user-provided test case descriptor. 7304 * 7305 * This function may throw a TestError exception if GL implementation misbehaves. 7306 * 7307 * @param test_case Test case descriptor to use. 7308 * 7309 * @return true if the values returned by GL implementation were found to be valid, 7310 * false otherwise. 7311 **/ 7312 bool GPUShaderFP64Test5::executeIteration(const _test_case& test_case) 7313 { 7314 bool result = true; 7315 7316 /* Convert the base values array to the type of input attribute we'll be using 7317 * for the iteration. 7318 */ 7319 Utils::_variable_type base_value_type = Utils::getBaseVariableType(test_case.src_type); 7320 7321 if (base_value_type == Utils::VARIABLE_TYPE_BOOL) 7322 { 7323 /* bools are actually represented by ints, since bool varyings are not allowed */ 7324 base_value_type = Utils::VARIABLE_TYPE_INT; 7325 } 7326 7327 const unsigned int base_value_component_size = Utils::getBaseVariableTypeComponentSize(base_value_type); 7328 const unsigned int n_base_values = sizeof(m_base_values) / sizeof(m_base_values[0]); 7329 7330 m_base_value_bo_data = new unsigned char[base_value_component_size * n_base_values]; 7331 7332 unsigned char* base_value_traveller_ptr = m_base_value_bo_data; 7333 7334 for (unsigned int n_base_value = 0; n_base_value < n_base_values; ++n_base_value) 7335 { 7336 switch (base_value_type) 7337 { 7338 case Utils::VARIABLE_TYPE_DOUBLE: 7339 *((double*)base_value_traveller_ptr) = (double)m_base_values[n_base_value]; 7340 break; 7341 case Utils::VARIABLE_TYPE_FLOAT: 7342 *((float*)base_value_traveller_ptr) = (float)m_base_values[n_base_value]; 7343 break; 7344 case Utils::VARIABLE_TYPE_INT: 7345 *((int*)base_value_traveller_ptr) = (int)m_base_values[n_base_value]; 7346 break; 7347 case Utils::VARIABLE_TYPE_UINT: 7348 *((unsigned int*)base_value_traveller_ptr) = (unsigned int)m_base_values[n_base_value]; 7349 break; 7350 7351 default: 7352 { 7353 TCU_FAIL("Unrecognized base value type"); 7354 } 7355 } 7356 7357 base_value_traveller_ptr += base_value_component_size; 7358 } /* for (all base values) */ 7359 7360 /* Update buffer object storage with the data we've just finished preparing. */ 7361 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 7362 7363 gl.bindBuffer(GL_ARRAY_BUFFER, m_base_value_bo_id); 7364 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 7365 7366 gl.bufferSubData(GL_ARRAY_BUFFER, 0 /* offset */, base_value_component_size * n_base_values, m_base_value_bo_data); 7367 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed."); 7368 7369 /* Configure vertex attribute array corresponding to 'base_value' attribute, so that the 7370 * new data is interpreted correctly. 7371 */ 7372 if (base_value_type == Utils::VARIABLE_TYPE_FLOAT) 7373 { 7374 gl.vertexAttribPointer(m_po_base_value_attribute_location, 1, /* size */ 7375 Utils::getGLDataTypeOfBaseVariableType(base_value_type), GL_FALSE, /* normalized */ 7376 0, /* stride */ 7377 DE_NULL); /* pointer */ 7378 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() call failed."); 7379 } 7380 else if (base_value_type == Utils::VARIABLE_TYPE_INT || base_value_type == Utils::VARIABLE_TYPE_UINT) 7381 { 7382 gl.vertexAttribIPointer(m_po_base_value_attribute_location, 1, /* size */ 7383 Utils::getGLDataTypeOfBaseVariableType(base_value_type), 0, /* stride */ 7384 DE_NULL); /* pointer */ 7385 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer() call failed."); 7386 } 7387 else 7388 { 7389 DE_ASSERT(base_value_type == Utils::VARIABLE_TYPE_DOUBLE); 7390 7391 gl.vertexAttribLPointer(m_po_base_value_attribute_location, 1, /* size */ 7392 GL_DOUBLE, 0, /* stride */ 7393 DE_NULL); /* pointer */ 7394 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertxAttribLPointer() call failed."); 7395 } 7396 7397 gl.enableVertexAttribArray(m_po_base_value_attribute_location); 7398 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() call failed."); 7399 7400 /* Execute the draw call */ 7401 gl.useProgram(m_po_id); 7402 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 7403 7404 gl.beginTransformFeedback(GL_POINTS); 7405 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed."); 7406 { 7407 gl.drawArrays(GL_POINTS, 0 /* first */, n_base_values); 7408 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 7409 } 7410 gl.endTransformFeedback(); 7411 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed."); 7412 7413 /* Map the XFB buffer object into process space */ 7414 void* xfb_data_ptr = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 7415 7416 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed."); 7417 DE_ASSERT(xfb_data_ptr != NULL); 7418 7419 /* Verify the data */ 7420 result &= verifyXFBData((const unsigned char*)xfb_data_ptr, test_case); 7421 7422 /* Unmap the XFB BO */ 7423 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 7424 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 7425 7426 /** Good to release the data buffer at this point */ 7427 if (m_base_value_bo_data != DE_NULL) 7428 { 7429 delete[] m_base_value_bo_data; 7430 7431 m_base_value_bo_data = DE_NULL; 7432 } 7433 7434 /* All done */ 7435 return result; 7436 } 7437 7438 /** Returns properties of a swizzle operator described by @param type swizzle type. 7439 * 7440 * @param out_swizzle_string Deref will be used to store a GLSL literal 7441 * corresponding to the specific swizzle operator. 7442 * Must not be NULL. 7443 * @param out_n_components Deref will be used to store the amount of components 7444 * used by the operator. Must not be NULL. 7445 * @param out_component_order Deref will be used to store up to 4 integer values, 7446 * corresponding to component indices described by the 7447 * operator for a particular position. Must not be NULL. 7448 **/ 7449 void GPUShaderFP64Test5::getSwizzleTypeProperties(_swizzle_type type, std::string* out_swizzle_string, 7450 unsigned int* out_n_components, unsigned int* out_component_order) 7451 { 7452 unsigned int result_component_order[4] = { 0 }; 7453 unsigned int result_n_components = 0; 7454 std::string result_swizzle_string; 7455 7456 switch (type) 7457 { 7458 case SWIZZLE_TYPE_NONE: 7459 { 7460 result_swizzle_string = ""; 7461 result_n_components = 0; 7462 7463 break; 7464 } 7465 7466 case SWIZZLE_TYPE_XWZY: 7467 { 7468 result_swizzle_string = "xwzy"; 7469 result_n_components = 4; 7470 result_component_order[0] = 0; 7471 result_component_order[1] = 3; 7472 result_component_order[2] = 2; 7473 result_component_order[3] = 1; 7474 7475 break; 7476 } 7477 7478 case SWIZZLE_TYPE_XZXY: 7479 { 7480 result_swizzle_string = "xzxy"; 7481 result_n_components = 4; 7482 result_component_order[0] = 0; 7483 result_component_order[1] = 2; 7484 result_component_order[2] = 0; 7485 result_component_order[3] = 1; 7486 7487 break; 7488 } 7489 7490 case SWIZZLE_TYPE_XZY: 7491 { 7492 result_swizzle_string = "xzy"; 7493 result_n_components = 3; 7494 result_component_order[0] = 0; 7495 result_component_order[1] = 2; 7496 result_component_order[2] = 1; 7497 7498 break; 7499 } 7500 7501 case SWIZZLE_TYPE_XZYW: 7502 { 7503 result_swizzle_string = "xzyw"; 7504 result_n_components = 4; 7505 result_component_order[0] = 0; 7506 result_component_order[1] = 2; 7507 result_component_order[2] = 1; 7508 result_component_order[3] = 3; 7509 7510 break; 7511 } 7512 7513 case SWIZZLE_TYPE_Y: 7514 { 7515 result_swizzle_string = "y"; 7516 result_n_components = 1; 7517 result_component_order[0] = 1; 7518 7519 break; 7520 } 7521 7522 case SWIZZLE_TYPE_YX: 7523 { 7524 result_swizzle_string = "yx"; 7525 result_n_components = 2; 7526 result_component_order[0] = 1; 7527 result_component_order[1] = 0; 7528 7529 break; 7530 } 7531 7532 case SWIZZLE_TYPE_YXX: 7533 { 7534 result_swizzle_string = "yxx"; 7535 result_n_components = 3; 7536 result_component_order[0] = 1; 7537 result_component_order[1] = 0; 7538 result_component_order[2] = 0; 7539 7540 break; 7541 } 7542 7543 case SWIZZLE_TYPE_YXXY: 7544 { 7545 result_swizzle_string = "yxxy"; 7546 result_n_components = 4; 7547 result_component_order[0] = 1; 7548 result_component_order[1] = 0; 7549 result_component_order[2] = 0; 7550 result_component_order[3] = 1; 7551 7552 break; 7553 } 7554 7555 case SWIZZLE_TYPE_Z: 7556 { 7557 result_swizzle_string = "z"; 7558 result_n_components = 1; 7559 result_component_order[0] = 2; 7560 7561 break; 7562 } 7563 7564 case SWIZZLE_TYPE_ZY: 7565 { 7566 result_swizzle_string = "zy"; 7567 result_n_components = 2; 7568 result_component_order[0] = 2; 7569 result_component_order[1] = 1; 7570 7571 break; 7572 } 7573 7574 case SWIZZLE_TYPE_W: 7575 { 7576 result_swizzle_string = "w"; 7577 result_n_components = 1; 7578 result_component_order[0] = 3; 7579 7580 break; 7581 } 7582 7583 case SWIZZLE_TYPE_WX: 7584 { 7585 result_swizzle_string = "wx"; 7586 result_n_components = 2; 7587 result_component_order[0] = 3; 7588 result_component_order[1] = 0; 7589 7590 break; 7591 } 7592 7593 default: 7594 { 7595 TCU_FAIL("Unrecognized swizzle type"); 7596 } 7597 } /* switch (type) */ 7598 7599 if (out_swizzle_string != DE_NULL) 7600 { 7601 *out_swizzle_string = result_swizzle_string; 7602 } 7603 7604 if (out_n_components != DE_NULL) 7605 { 7606 *out_n_components = result_n_components; 7607 } 7608 7609 if (out_component_order != DE_NULL) 7610 { 7611 memcpy(out_component_order, result_component_order, sizeof(unsigned int) * result_n_components); 7612 } 7613 } 7614 7615 /** Returns body of a vertex shader that should be used for particular test case, 7616 * given user-specified test case descriptor. 7617 * 7618 * @param test_case Descriptor to use for the query. 7619 * 7620 * @return Requested data. 7621 **/ 7622 std::string GPUShaderFP64Test5::getVertexShaderBody(const _test_case& test_case) 7623 { 7624 std::stringstream result; 7625 const std::string base_type_string = Utils::getVariableTypeString(Utils::getBaseVariableType(test_case.src_type)); 7626 const std::string dst_type_string = Utils::getVariableTypeString(test_case.dst_type); 7627 const unsigned int n_dst_components = Utils::getNumberOfComponentsForVariableType(test_case.dst_type); 7628 const unsigned int n_src_components = Utils::getNumberOfComponentsForVariableType(test_case.src_type); 7629 const std::string src_type_string = Utils::getVariableTypeString(test_case.src_type); 7630 7631 /* Add version preamble */ 7632 result << "#version 420\n" 7633 "\n"; 7634 7635 /* Declare output variables. Note that boolean output variables are not supported, so we need 7636 * to handle that special case correctly */ 7637 if (test_case.dst_type == Utils::VARIABLE_TYPE_BOOL) 7638 { 7639 result << "out int result;\n"; 7640 } 7641 else 7642 { 7643 result << "out " << dst_type_string << " result;\n"; 7644 } 7645 7646 /* Declare input variables. Handle the bool case exclusively. */ 7647 if (test_case.src_type == Utils::VARIABLE_TYPE_BOOL) 7648 { 7649 /* Use ints for bools. We will cast them to bool in the code later. */ 7650 result << "in int base_value;\n"; 7651 } 7652 else 7653 { 7654 result << "in " << base_type_string << " base_value;\n"; 7655 } 7656 7657 /* Declare main() and construct the value we will be casting from. 7658 * 7659 * Note: Addition operations on bool values cause an implicit conversion to int 7660 * which is not allowed. Hence, we skip these operations for this special 7661 * case. 7662 */ 7663 result << "void main()\n" 7664 "{\n" 7665 << src_type_string << " lside_value = "; 7666 7667 if (test_case.src_type == Utils::VARIABLE_TYPE_BOOL) 7668 { 7669 result << src_type_string << "(0 != "; 7670 } 7671 else 7672 { 7673 result << src_type_string << "("; 7674 } 7675 7676 if (test_case.src_type != Utils::VARIABLE_TYPE_BOOL) 7677 { 7678 for (unsigned int n_component = 0; n_component < n_src_components; ++n_component) 7679 { 7680 result << "base_value + " << n_component; 7681 7682 if (n_component != (n_src_components - 1)) 7683 { 7684 result << ", "; 7685 } 7686 } /* for (all components) */ 7687 } 7688 else 7689 { 7690 DE_ASSERT(n_src_components == 1); 7691 7692 result << "base_value"; 7693 } 7694 7695 result << ");\n"; 7696 7697 /* Perform the casting operation. Add swizzle operator if possible. */ 7698 if (test_case.dst_type == Utils::VARIABLE_TYPE_BOOL) 7699 { 7700 /* Handle the bool case exclusively */ 7701 if (test_case.type == TEST_CASE_TYPE_EXPLICIT) 7702 { 7703 result << "result = (bool(lside_value) == false) ? 0 : 1"; 7704 } 7705 else 7706 { 7707 result << "result = (lside_value == false) ? 0 : 1"; 7708 } 7709 } 7710 else 7711 { 7712 if (test_case.type == TEST_CASE_TYPE_EXPLICIT) 7713 { 7714 result << "result = " << dst_type_string << "(lside_value)"; 7715 } 7716 else 7717 { 7718 result << "result = lside_value"; 7719 } 7720 } 7721 7722 if (n_src_components > 1 && !Utils::isMatrixVariableType(test_case.src_type)) 7723 { 7724 /* Add a swizzle operator */ 7725 DE_ASSERT(n_dst_components > 0 && n_dst_components <= 4); 7726 DE_ASSERT(n_src_components > 0 && n_src_components <= 4); 7727 7728 unsigned int swizzle_component_order[4] = { 0 }; 7729 unsigned int swizzle_n_components = 0; 7730 _swizzle_type swizzle_operator = m_swizzle_matrix[n_dst_components - 1][n_src_components - 1]; 7731 std::string swizzle_string; 7732 7733 getSwizzleTypeProperties(swizzle_operator, &swizzle_string, &swizzle_n_components, swizzle_component_order); 7734 7735 if (swizzle_n_components > 0) 7736 { 7737 result << "." << swizzle_string; 7738 } 7739 } 7740 7741 /* Close the shader implementation. */ 7742 result << ";\n" 7743 "}\n"; 7744 7745 return result.str(); 7746 } 7747 7748 /** Initializes program & shader objects needed to run the iteration, given 7749 * user-specified test case descriptor. 7750 * 7751 * This function can throw a TestError exception if a GL error is detected 7752 * during execution. 7753 * 7754 * @param test_case Descriptor to use for the iteration. 7755 **/ 7756 void GPUShaderFP64Test5::initIteration(_test_case& test_case) 7757 { 7758 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 7759 7760 /* Create program & shader objects */ 7761 m_po_id = gl.createProgram(); 7762 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 7763 7764 m_vs_id = gl.createShader(GL_VERTEX_SHADER); 7765 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed."); 7766 7767 /* Configure shader body */ 7768 std::string body = getVertexShaderBody(test_case); 7769 const char* body_raw_ptr = body.c_str(); 7770 7771 gl.shaderSource(m_vs_id, 1 /* count */, &body_raw_ptr, DE_NULL /* length */); 7772 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 7773 7774 /* Store it in the test case descriptor for logging purposes */ 7775 test_case.shader_body = body; 7776 7777 /* Compile the shader */ 7778 glw::GLint compile_status = GL_FALSE; 7779 7780 gl.compileShader(m_vs_id); 7781 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); 7782 7783 gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status); 7784 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 7785 7786 if (compile_status != GL_TRUE) 7787 { 7788 TCU_FAIL("Shader compilation failed"); 7789 } 7790 7791 /* Attach the shader to the program obejct */ 7792 gl.attachShader(m_po_id, m_vs_id); 7793 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed."); 7794 7795 /* Configure XFB for the program object */ 7796 const char* xfb_varying_name = "result"; 7797 7798 gl.transformFeedbackVaryings(m_po_id, 1 /* count */, &xfb_varying_name, GL_INTERLEAVED_ATTRIBS); 7799 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed."); 7800 7801 /* Link the program object */ 7802 glw::GLint link_status = GL_FALSE; 7803 7804 gl.linkProgram(m_po_id); 7805 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed."); 7806 7807 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status); 7808 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 7809 7810 if (link_status != GL_TRUE) 7811 { 7812 TCU_FAIL("Program linking failed"); 7813 } 7814 7815 /* Retrieve attribute locations */ 7816 m_po_base_value_attribute_location = gl.getAttribLocation(m_po_id, "base_value"); 7817 GLU_EXPECT_NO_ERROR(gl.getError(), "getAttribLocation() call failed."); 7818 7819 if (m_po_base_value_attribute_location == -1) 7820 { 7821 TCU_FAIL("'base_value' is considered an inactive attribute which is invalid."); 7822 } 7823 } 7824 7825 /** Initializes GL objects used by all test cases. 7826 * 7827 * This function may throw a TestError exception if GL implementation reports 7828 * an error at any point. 7829 **/ 7830 void GPUShaderFP64Test5::initTest() 7831 { 7832 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 7833 7834 /* Generate buffer object IDs */ 7835 gl.genBuffers(1, &m_base_value_bo_id); 7836 gl.genBuffers(1, &m_xfb_bo_id); 7837 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed."); 7838 7839 /* Allocate buffer object storage for 'base_value' input attribute data. All iterations 7840 * will never eat up more than 1 double (as per test spec) and we will be drawing 7841 * as many points in a single draw call as there are defined in m_base_values array. 7842 */ 7843 const unsigned int n_base_values = sizeof(m_base_values) / sizeof(m_base_values[0]); 7844 7845 gl.bindBuffer(GL_ARRAY_BUFFER, m_base_value_bo_id); 7846 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 7847 7848 gl.bufferData(GL_ARRAY_BUFFER, sizeof(double) * n_base_values, DE_NULL /* data */, GL_STATIC_DRAW); 7849 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 7850 7851 /* Allocate buffer object storage for XFB data. For each iteratiom we will be using 7852 * five base values. Each XFBed value can take up to 16 components (eg. mat4) and be 7853 * of double type (eg. dmat4), so make sure a sufficient amount of space is requested. 7854 */ 7855 const unsigned int xfb_bo_size = sizeof(double) * 16 /* components */ * n_base_values; 7856 7857 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id); 7858 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 7859 7860 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id); 7861 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed."); 7862 7863 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_bo_size, DE_NULL /* data */, GL_STATIC_DRAW); 7864 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 7865 7866 /* Allocate a client-side buffer to hold the data we will be mapping from XFB BO */ 7867 m_xfb_bo_size = xfb_bo_size; 7868 7869 /* Generate a vertex array object we will need to use for the draw calls */ 7870 gl.genVertexArrays(1, &m_vao_id); 7871 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 7872 7873 gl.bindVertexArray(m_vao_id); 7874 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 7875 } 7876 7877 /** Executes test iteration. 7878 * 7879 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 7880 */ 7881 tcu::TestNode::IterateResult GPUShaderFP64Test5::iterate() 7882 { 7883 /* Do not execute the test if GL_ARB_texture_view is not supported */ 7884 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64")) 7885 { 7886 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported."); 7887 } 7888 7889 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_vertex_attrib_64bit")) 7890 { 7891 throw tcu::NotSupportedError("GL_ARB_vertex_attrib_64bit is not supported."); 7892 } 7893 7894 /* Initialize GL objects needed to run the tests */ 7895 initTest(); 7896 7897 /* Build iteration array to run the tests in an automated manner */ 7898 _test_case test_cases[] = { 7899 /* test case type */ /* source type */ /* destination type */ 7900 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, "" }, 7901 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_IVEC2, Utils::VARIABLE_TYPE_DVEC2, "" }, 7902 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_IVEC3, Utils::VARIABLE_TYPE_DVEC3, "" }, 7903 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_IVEC4, Utils::VARIABLE_TYPE_DVEC4, "" }, 7904 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, "" }, 7905 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UVEC2, Utils::VARIABLE_TYPE_DVEC2, "" }, 7906 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UVEC3, Utils::VARIABLE_TYPE_DVEC3, "" }, 7907 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UVEC4, Utils::VARIABLE_TYPE_DVEC4, "" }, 7908 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, "" }, 7909 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_VEC2, Utils::VARIABLE_TYPE_DVEC2, "" }, 7910 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_VEC3, Utils::VARIABLE_TYPE_DVEC3, "" }, 7911 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_VEC4, Utils::VARIABLE_TYPE_DVEC4, "" }, 7912 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT2, Utils::VARIABLE_TYPE_DMAT2, "" }, 7913 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT3, Utils::VARIABLE_TYPE_DMAT3, "" }, 7914 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT4, Utils::VARIABLE_TYPE_DMAT4, "" }, 7915 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT2X3, Utils::VARIABLE_TYPE_DMAT2X3, "" }, 7916 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT2X4, Utils::VARIABLE_TYPE_DMAT2X4, "" }, 7917 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT3X2, Utils::VARIABLE_TYPE_DMAT3X2, "" }, 7918 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT3X4, Utils::VARIABLE_TYPE_DMAT3X4, "" }, 7919 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT4X2, Utils::VARIABLE_TYPE_DMAT4X2, "" }, 7920 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT4X3, Utils::VARIABLE_TYPE_DMAT4X3, "" }, 7921 7922 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, "" }, 7923 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, "" }, 7924 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, "" }, 7925 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_INT, "" }, 7926 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_UINT, "" }, 7927 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_FLOAT, "" }, 7928 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_BOOL, "" }, 7929 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_BOOL, Utils::VARIABLE_TYPE_DOUBLE, "" } 7930 }; 7931 const unsigned int n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]); 7932 7933 /* Execute all iterations */ 7934 for (unsigned int n_test_case = 0; n_test_case < n_test_cases; ++n_test_case) 7935 { 7936 _test_case& test_case = test_cases[n_test_case]; 7937 7938 /* Initialize a program object we will use to perform the casting */ 7939 initIteration(test_case); 7940 7941 /* Use the program object to XFB the results */ 7942 m_has_test_passed &= executeIteration(test_case); 7943 7944 /* Release the GL Resource for this sub test */ 7945 deinitInteration(); 7946 7947 } /* for (all test cases) */ 7948 /* We're done */ 7949 if (m_has_test_passed) 7950 { 7951 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 7952 } 7953 else 7954 { 7955 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 7956 } 7957 7958 return STOP; 7959 } 7960 7961 /** Verifies if data XFBed out by the vertex shader are valid, given test case descriptor, 7962 * for which the data have been generated. 7963 * 7964 * @param data_ptr Buffer holding the data XFBed out by the shader. 7965 * @param test_case Descriptor of the test case, for which the vertex shader was 7966 * generated. 7967 * 7968 * @return true if the data were found to be valid, false otherwise. 7969 **/ 7970 bool GPUShaderFP64Test5::verifyXFBData(const unsigned char* data_ptr, const _test_case& test_case) 7971 { 7972 const Utils::_variable_type base_dst_type = Utils::getBaseVariableType(test_case.dst_type); 7973 const Utils::_variable_type base_src_type = Utils::getBaseVariableType(test_case.src_type); 7974 const float epsilon = 1e-5f; 7975 const unsigned int n_base_values = sizeof(m_base_values) / sizeof(m_base_values[0]); 7976 const unsigned int n_result_components = Utils::getNumberOfComponentsForVariableType(test_case.dst_type); 7977 const unsigned int n_src_components = Utils::getNumberOfComponentsForVariableType(test_case.src_type); 7978 bool result = true; 7979 _swizzle_type swizzle_operator = SWIZZLE_TYPE_NONE; 7980 unsigned int swizzle_order[4] = { 0 }; 7981 const unsigned char* traveller_ptr = data_ptr; 7982 7983 if (!Utils::isMatrixVariableType(test_case.src_type)) 7984 { 7985 DE_ASSERT(n_result_components >= 1 && n_result_components <= 4); 7986 DE_ASSERT(n_src_components >= 1 && n_src_components <= 4); 7987 7988 swizzle_operator = m_swizzle_matrix[n_result_components - 1][n_src_components - 1]; 7989 7990 getSwizzleTypeProperties(swizzle_operator, DE_NULL, /* out_swizzle_string */ 7991 DE_NULL, /* out_n_components */ 7992 swizzle_order); 7993 } 7994 7995 for (unsigned int n_base_value = 0; n_base_value < n_base_values; ++n_base_value) 7996 { 7997 for (unsigned int n_result_component = 0; n_result_component < n_result_components; ++n_result_component) 7998 { 7999 unsigned int n_swizzled_component = n_result_component; 8000 8001 if (swizzle_operator != SWIZZLE_TYPE_NONE) 8002 { 8003 n_swizzled_component = 8004 (n_result_component / n_result_components) * n_result_component + swizzle_order[n_result_component]; 8005 } 8006 8007 switch (base_dst_type) 8008 { 8009 case Utils::VARIABLE_TYPE_BOOL: 8010 case Utils::VARIABLE_TYPE_INT: 8011 { 8012 double ref_expected_value = (m_base_values[n_base_value]) + static_cast<float>(n_swizzled_component); 8013 double expected_value = ref_expected_value; 8014 int result_value = *((int*)traveller_ptr); 8015 8016 if (base_dst_type == Utils::VARIABLE_TYPE_BOOL) 8017 { 8018 if (expected_value != 0.0) 8019 { 8020 expected_value = 1.0; 8021 } 8022 } 8023 8024 if (result_value != (int)expected_value) 8025 { 8026 m_testCtx.getLog() << tcu::TestLog::Message 8027 << "Invalid boolean/integer value obtained when doing an " 8028 << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit") 8029 << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type) 8030 << "]" 8031 ", component index: [" 8032 << n_swizzled_component << "]" 8033 ", value: [" 8034 << ref_expected_value << "]" 8035 " to GLSL type [" 8036 << Utils::getVariableTypeString(test_case.dst_type) << "]" 8037 ", retrieved value: [" 8038 << result_value << "]" 8039 ", expected value: [" 8040 << (int)expected_value << "]" 8041 ", shader used:\n" 8042 << test_case.shader_body.c_str() << tcu::TestLog::EndMessage; 8043 8044 result = false; 8045 } 8046 8047 traveller_ptr += sizeof(int); 8048 break; 8049 } /* VARIABLE_TYPE_BOOL or VARIABLE_TYPE_INT cases */ 8050 8051 case Utils::VARIABLE_TYPE_DOUBLE: 8052 { 8053 double ref_expected_value = m_base_values[n_base_value] + (double)n_swizzled_component; 8054 double expected_value = ref_expected_value; 8055 double result_value = *((double*)traveller_ptr); 8056 8057 if (base_src_type == Utils::VARIABLE_TYPE_BOOL) 8058 { 8059 expected_value = ((int)expected_value != 0.0) ? 1.0 : 0.0; 8060 } 8061 else if (base_src_type == Utils::VARIABLE_TYPE_INT) 8062 { 8063 expected_value = (int)expected_value; 8064 } 8065 else if (base_src_type == Utils::VARIABLE_TYPE_UINT) 8066 { 8067 // Negative values in base values array when converted to unsigned int will be ZERO 8068 // Addition operations done inside the shader in such cases will operate on ZERO rather 8069 // than the negative value being passed. 8070 // Replicate the sequence of conversion and addition operations done on the 8071 // shader input, to calculate the expected values in XFB data in the 8072 // problematic cases. 8073 if (expected_value < 0) 8074 { 8075 expected_value = (unsigned int)m_base_values[n_base_value] + n_swizzled_component; 8076 } 8077 expected_value = (unsigned int)expected_value; 8078 } 8079 8080 traveller_ptr += sizeof(double); 8081 if (de::abs(result_value - expected_value) > epsilon) 8082 { 8083 m_testCtx.getLog() << tcu::TestLog::Message 8084 << "Invalid double-precision floating-point value obtained when doing an " 8085 << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit") 8086 << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type) 8087 << "]" 8088 ", component index: [" 8089 << n_swizzled_component << "]" 8090 ", value: [" 8091 << ref_expected_value << "]" 8092 " to GLSL type [" 8093 << Utils::getVariableTypeString(test_case.dst_type) << "]" 8094 ", retrieved value: [" 8095 << std::setprecision(16) << result_value << "]" 8096 ", expected value: [" 8097 << std::setprecision(16) << expected_value << "]" 8098 ", shader used:\n" 8099 << test_case.shader_body.c_str() << tcu::TestLog::EndMessage; 8100 8101 result = false; 8102 } 8103 8104 break; 8105 } /* VARIABLE_TYPE_DOUBLE case */ 8106 8107 case Utils::VARIABLE_TYPE_FLOAT: 8108 { 8109 float ref_expected_value = (float)m_base_values[n_base_value] + (float)n_swizzled_component; 8110 float expected_value = ref_expected_value; 8111 float result_value = *((float*)traveller_ptr); 8112 8113 if (base_src_type == Utils::VARIABLE_TYPE_BOOL) 8114 { 8115 expected_value = (expected_value != 0.0f) ? 1.0f : 0.0f; 8116 } 8117 else if (base_src_type == Utils::VARIABLE_TYPE_INT) 8118 { 8119 expected_value = (float)((int)expected_value); 8120 } 8121 else if (base_src_type == Utils::VARIABLE_TYPE_UINT) 8122 { 8123 expected_value = (float)((unsigned int)expected_value); 8124 } 8125 8126 traveller_ptr += sizeof(float); 8127 if (de::abs(result_value - expected_value) > epsilon) 8128 { 8129 m_testCtx.getLog() << tcu::TestLog::Message 8130 << "Invalid single-precision floating-point value obtained when doing an " 8131 << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit") 8132 << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type) 8133 << "]" 8134 ", component index: [" 8135 << n_swizzled_component << "]" 8136 ", value: [" 8137 << ref_expected_value << "]" 8138 " to GLSL type [" 8139 << Utils::getVariableTypeString(test_case.dst_type) << "]" 8140 ", retrieved value: [" 8141 << std::setprecision(16) << result_value << "]" 8142 ", expected value: [" 8143 << std::setprecision(16) << expected_value << "]" 8144 ", shader used:\n" 8145 << test_case.shader_body.c_str() << tcu::TestLog::EndMessage; 8146 8147 result = false; 8148 } 8149 8150 break; 8151 } /* VARIABLE_TYPE_FLOAT case */ 8152 8153 case Utils::VARIABLE_TYPE_UINT: 8154 { 8155 double ref_expected_value = (m_base_values[n_base_value]) + static_cast<float>(n_swizzled_component); 8156 double expected_value = ref_expected_value; 8157 unsigned int result_value = *((unsigned int*)traveller_ptr); 8158 8159 traveller_ptr += sizeof(unsigned int); 8160 if (result_value != (unsigned int)expected_value) 8161 { 8162 if (expected_value < 0.0) 8163 { 8164 // It is undefined to convert a negative floating-point value to an uint. 8165 break; 8166 } 8167 8168 m_testCtx.getLog() << tcu::TestLog::Message 8169 << "Invalid unsigned integer value obtained when doing an " 8170 << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit") 8171 << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type) 8172 << "]" 8173 ", component index: [" 8174 << n_swizzled_component << "]" 8175 ", value: [" 8176 << ref_expected_value << "]" 8177 " to GLSL type [" 8178 << Utils::getVariableTypeString(test_case.dst_type) << "]" 8179 ", retrieved value: [" 8180 << result_value << "]" 8181 ", expected value: [" 8182 << (unsigned int)expected_value << "]" 8183 ", shader used:\n" 8184 << test_case.shader_body.c_str() << tcu::TestLog::EndMessage; 8185 8186 result = false; 8187 } 8188 8189 break; 8190 } /* VARIABLE_TYPE_UINT case */ 8191 8192 default: 8193 { 8194 TCU_FAIL("Unrecognized variable type"); 8195 } 8196 } /* switch (test_case.dst_type) */ 8197 } /* for (all result components) */ 8198 } /* for (all base values) */ 8199 8200 return result; 8201 } 8202 8203 /** Constructor 8204 * 8205 * @param context Rendering context. 8206 */ 8207 GPUShaderFP64Test6::GPUShaderFP64Test6(deqp::Context& context) 8208 : TestCase(context, "illegal_conversions", "Verifies that invalid casts to double-precision variables are detected " 8209 "during compilation time.") 8210 , m_cs_id(0) 8211 , m_fs_id(0) 8212 , m_gs_id(0) 8213 , m_tc_id(0) 8214 , m_te_id(0) 8215 , m_vs_id(0) 8216 , m_has_test_passed(true) 8217 { 8218 } 8219 8220 /** Deinitializes all buffers and GL objects that may have been generated 8221 * during test execution. 8222 **/ 8223 void GPUShaderFP64Test6::deinit() 8224 { 8225 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 8226 8227 if (m_cs_id != 0) 8228 { 8229 gl.deleteShader(m_cs_id); 8230 8231 m_cs_id = 0; 8232 } 8233 8234 if (m_fs_id != 0) 8235 { 8236 gl.deleteShader(m_fs_id); 8237 8238 m_fs_id = 0; 8239 } 8240 8241 if (m_gs_id != 0) 8242 { 8243 gl.deleteShader(m_gs_id); 8244 8245 m_gs_id = 0; 8246 } 8247 8248 if (m_tc_id != 0) 8249 { 8250 gl.deleteShader(m_tc_id); 8251 8252 m_tc_id = 0; 8253 } 8254 8255 if (m_te_id != 0) 8256 { 8257 gl.deleteShader(m_te_id); 8258 8259 m_te_id = 0; 8260 } 8261 8262 if (m_vs_id != 0) 8263 { 8264 gl.deleteShader(m_vs_id); 8265 8266 m_vs_id = 0; 8267 } 8268 } 8269 8270 /** Executes a single test case. 8271 * 8272 * This function can throw TestError exceptions if GL implementation reports 8273 * an error. 8274 * 8275 * @param test_case Test case descriptor. 8276 * 8277 * @return true if test case passed, false otherwise. 8278 **/ 8279 bool GPUShaderFP64Test6::executeIteration(const _test_case& test_case) 8280 { 8281 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 8282 const glw::GLuint so_ids[] = { m_cs_id, m_fs_id, m_gs_id, m_tc_id, m_te_id, m_vs_id }; 8283 const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]); 8284 bool result = true; 8285 const char* stage_body = NULL; 8286 const char* stage_name = NULL; 8287 8288 for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id) 8289 { 8290 const glw::GLuint so_id = so_ids[n_so_id]; 8291 8292 /* Skip compute shader if it is not supported */ 8293 if (0 == so_id) 8294 { 8295 continue; 8296 } 8297 8298 /* Compile the shader */ 8299 gl.compileShader(so_id); 8300 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); 8301 8302