1 /*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2015-2016 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 */ /*! 20 * \file 21 * \brief 22 */ /*-------------------------------------------------------------------*/ 23 24 /** 25 */ /*! 26 * \file gl4cDirectStateAccessQueriesTests.cpp 27 * \brief Conformance tests for the Direct State Access feature functionality (Queries access part). 28 */ /*-----------------------------------------------------------------------------------------------------------*/ 29 30 /* Includes. */ 31 #include "gl4cDirectStateAccessTests.hpp" 32 33 #include "deSharedPtr.hpp" 34 35 #include "gluContextInfo.hpp" 36 #include "gluDefs.hpp" 37 #include "gluPixelTransfer.hpp" 38 #include "gluStrUtil.hpp" 39 40 #include "tcuFuzzyImageCompare.hpp" 41 #include "tcuImageCompare.hpp" 42 #include "tcuRenderTarget.hpp" 43 #include "tcuSurface.hpp" 44 #include "tcuTestLog.hpp" 45 46 #include "glw.h" 47 #include "glwFunctions.hpp" 48 49 /* Define OpenGL enumerations not available in framework. */ 50 #ifndef GL_QUERY_TARGET 51 #define GL_QUERY_TARGET 0x82EA 52 #endif 53 54 namespace gl4cts 55 { 56 namespace DirectStateAccess 57 { 58 namespace Queries 59 { 60 /******************************** Creation Test Implementation ********************************/ 61 62 /** @brief Creation Test constructor. 63 * 64 * @param [in] context OpenGL context. 65 */ 66 CreationTest::CreationTest(deqp::Context& context) 67 : deqp::TestCase(context, "queries_creation", "Query Objects Creation Test") 68 { 69 /* Intentionally left blank. */ 70 } 71 72 /** @brief Iterate Creation Test cases. 73 * 74 * @return Iteration result. 75 */ 76 tcu::TestNode::IterateResult CreationTest::iterate() 77 { 78 /* Shortcut for GL functionality. */ 79 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 80 81 /* Get context setup. */ 82 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 83 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 84 85 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 86 { 87 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 88 89 return STOP; 90 } 91 92 /* Running tests. */ 93 bool is_ok = true; 94 bool is_error = false; 95 96 /* Query targets */ 97 static const glw::GLenum targets[] = { 98 GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_TIME_ELAPSED, 99 GL_TIMESTAMP, GL_PRIMITIVES_GENERATED, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 100 }; 101 static const glw::GLuint targets_count = sizeof(targets) / sizeof(targets[0]); 102 103 /* Queries objects */ 104 static const glw::GLuint queries_count = 2; 105 106 glw::GLuint queries_legacy[queries_count] = {}; 107 glw::GLuint queries_dsa[targets_count][queries_count] = {}; 108 109 try 110 { 111 /* Check legacy state creation. */ 112 gl.genQueries(queries_count, queries_legacy); 113 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries have failed"); 114 115 for (glw::GLuint i = 0; i < queries_count; ++i) 116 { 117 if (gl.isQuery(queries_legacy[i])) 118 { 119 is_ok = false; 120 121 /* Log. */ 122 m_context.getTestContext().getLog() 123 << tcu::TestLog::Message 124 << "GenQueries has created default objects, but it should create only a names." 125 << tcu::TestLog::EndMessage; 126 } 127 } 128 129 /* Check direct state creation. */ 130 for (glw::GLuint i = 0; i < targets_count; ++i) 131 { 132 gl.createQueries(targets[i], queries_count, queries_dsa[i]); 133 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed"); 134 135 for (glw::GLuint j = 0; j < queries_count; ++j) 136 { 137 if (!gl.isQuery(queries_dsa[i][j])) 138 { 139 is_ok = false; 140 141 /* Log. */ 142 m_context.getTestContext().getLog() << tcu::TestLog::Message 143 << "CreateQueries has not created default objects." 144 << tcu::TestLog::EndMessage; 145 } 146 } 147 } 148 } 149 catch (...) 150 { 151 is_ok = false; 152 is_error = true; 153 } 154 155 /* Cleanup. */ 156 for (glw::GLuint j = 0; j < queries_count; ++j) 157 { 158 if (queries_legacy[j]) 159 { 160 gl.deleteQueries(1, &queries_legacy[j]); 161 162 queries_legacy[j] = 0; 163 } 164 165 for (glw::GLuint i = 0; i < targets_count; ++i) 166 { 167 if (queries_dsa[i][j]) 168 { 169 gl.deleteQueries(1, &queries_dsa[i][j]); 170 171 queries_dsa[i][j] = 0; 172 } 173 } 174 } 175 176 /* Result's setup. */ 177 if (is_ok) 178 { 179 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 180 } 181 else 182 { 183 if (is_error) 184 { 185 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 186 } 187 else 188 { 189 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 190 } 191 } 192 193 return STOP; 194 } 195 196 /******************************** Defaults Test Implementation ********************************/ 197 198 /** @brief Defaults Test constructor. 199 * 200 * @param [in] context OpenGL context. 201 */ 202 DefaultsTest::DefaultsTest(deqp::Context& context) 203 : deqp::TestCase(context, "queries_defaults", "Queries Defaults Test"), m_query_dsa(0) 204 { 205 /* Intentionally left blank. */ 206 } 207 208 /** @brief Iterate Defaults Test cases. 209 * 210 * @return Iteration result. 211 */ 212 tcu::TestNode::IterateResult DefaultsTest::iterate() 213 { 214 /* Get context setup. */ 215 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 216 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 217 218 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 219 { 220 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 221 222 return STOP; 223 } 224 225 /* Running tests. */ 226 bool is_ok = true; 227 bool is_error = false; 228 229 /* Query targets. */ 230 static const glw::GLenum targets[] = { 231 GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_TIME_ELAPSED, 232 GL_TIMESTAMP, GL_PRIMITIVES_GENERATED, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 233 }; 234 235 static const glw::GLchar* target_names[] = { 236 "GL_SAMPLES_PASSED", "GL_ANY_SAMPLES_PASSED", "GL_ANY_SAMPLES_PASSED_CONSERVATIVE", "GL_TIME_ELAPSED", 237 "GL_TIMESTAMP", "GL_PRIMITIVES_GENERATED", "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN" 238 }; 239 240 static const glw::GLuint targets_count = sizeof(targets) / sizeof(targets[0]); 241 242 try 243 { 244 /* Check direct state creation. */ 245 for (glw::GLuint i = 0; i < targets_count; ++i) 246 { 247 prepare(targets[i]); 248 249 is_ok &= testQueryParameter(GL_QUERY_RESULT, GL_FALSE, target_names[i]); 250 is_ok &= testQueryParameter(GL_QUERY_RESULT_AVAILABLE, GL_TRUE, target_names[i]); 251 252 clean(); 253 } 254 } 255 catch (...) 256 { 257 is_ok = false; 258 is_error = true; 259 260 clean(); 261 } 262 263 /* Result's setup. */ 264 if (is_ok) 265 { 266 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 267 } 268 else 269 { 270 if (is_error) 271 { 272 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 273 } 274 else 275 { 276 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 277 } 278 } 279 280 return STOP; 281 } 282 283 /** @brief Create Query Objects. 284 * 285 * @note The function may throw if unexpected error has occured. 286 * 287 * @return True if test succeeded, false otherwise. 288 */ 289 void DefaultsTest::prepare(const glw::GLenum target) 290 { 291 /* Shortcut for GL functionality. */ 292 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 293 294 /* Query object creation */ 295 gl.createQueries(target, 1, &m_query_dsa); 296 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed"); 297 } 298 299 /** @brief Test Query Integer Parameter. 300 * 301 * @note The function may throw if unexpected error has occured. 302 * 303 * @param [in] pname Parameter name to be tested. 304 * @param [in] expected_value Expected value for comparison. 305 * @param [in] target_name Target name of the tested query object - for logging purposes. 306 * 307 * @return True if test succeeded, false otherwise. 308 */ 309 bool DefaultsTest::testQueryParameter(const glw::GLenum pname, const glw::GLuint expected_value, 310 const glw::GLchar* target_name) 311 { 312 /* Shortcut for GL functionality. */ 313 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 314 315 /* Get data. */ 316 glw::GLuint value = 0; 317 318 gl.getQueryObjectuiv(m_query_dsa, pname, &value); 319 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv have failed"); 320 321 if (expected_value != value) 322 { 323 m_context.getTestContext().getLog() 324 << tcu::TestLog::Message << "glGetQueryObjectuiv of query object with target " << target_name 325 << " with parameter " << pname << " has returned " << value << ", however " << expected_value 326 << " was expected." << tcu::TestLog::EndMessage; 327 328 return false; 329 } 330 331 return true; 332 } 333 334 /** @brief Release GL objects. 335 */ 336 void DefaultsTest::clean() 337 { 338 /* Shortcut for GL functionality. */ 339 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 340 341 if (m_query_dsa) 342 { 343 gl.deleteQueries(1, &m_query_dsa); 344 345 m_query_dsa = 0; 346 } 347 } 348 349 /******************************** Errors Test Implementation ********************************/ 350 351 /** @brief Errors Test constructor. 352 * 353 * @param [in] context OpenGL context. 354 */ 355 ErrorsTest::ErrorsTest(deqp::Context& context) 356 : deqp::TestCase(context, "queries_errors", "Queries Errors Test") 357 , m_pGetQueryBufferObjectiv(DE_NULL) 358 , m_pGetQueryBufferObjectuiv(DE_NULL) 359 , m_pGetQueryBufferObjecti64v(DE_NULL) 360 , m_pGetQueryBufferObjectui64v(DE_NULL) 361 { 362 /* Intentionally left blank. */ 363 } 364 365 /** @brief Iterate Errors Test cases. 366 * 367 * @return Iteration result. 368 */ 369 tcu::TestNode::IterateResult ErrorsTest::iterate() 370 { 371 /* Shortcut for GL functionality. */ 372 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 373 374 /* Get context setup. */ 375 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 376 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 377 378 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 379 { 380 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 381 382 return STOP; 383 } 384 385 /* Getting function pointers. */ 386 m_pGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectiv; 387 m_pGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectuiv; 388 m_pGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjecti64v; 389 m_pGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectui64v; 390 391 /* Running tests. */ 392 bool is_ok = true; 393 bool is_error = false; 394 395 try 396 { 397 if ((DE_NULL == m_pGetQueryBufferObjectiv) || (DE_NULL == m_pGetQueryBufferObjectuiv) || 398 (DE_NULL == m_pGetQueryBufferObjecti64v) || (DE_NULL == m_pGetQueryBufferObjectui64v)) 399 { 400 m_context.getTestContext().getLog() 401 << tcu::TestLog::Message << "Test could not get the pointers for glGetQueryBufferObject* functions." 402 << tcu::TestLog::EndMessage; 403 404 throw 0; 405 } 406 407 is_ok &= testNegativeNumberOfObjects(); 408 is_ok &= testInvalidTarget(); 409 is_ok &= testInvalidQueryName(); 410 is_ok &= testInvalidBufferName(); 411 is_ok &= testInvalidParameterName(); 412 is_ok &= testBufferOverflow(); 413 is_ok &= testBufferNegativeOffset(); 414 } 415 catch (...) 416 { 417 is_ok = false; 418 is_error = true; 419 } 420 421 /* Result's setup. */ 422 if (is_ok) 423 { 424 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 425 } 426 else 427 { 428 if (is_error) 429 { 430 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 431 } 432 else 433 { 434 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 435 } 436 } 437 438 return STOP; 439 } 440 441 /** @brief Check that CreateQueries generates INVALID_VALUE 442 * error if number of query objects to create is 443 * negative. 444 * 445 * @return True if test succeded, false otherwise. 446 */ 447 bool ErrorsTest::testNegativeNumberOfObjects() 448 { 449 /* Shortcut for GL functionality. */ 450 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 451 452 /* Test for each target. */ 453 for (glw::GLuint i = 0; i < s_targets_count; ++i) 454 { 455 glw::GLuint query = 0; 456 457 gl.createQueries(s_targets[i], -1, &query); /* Create negative number of queries. */ 458 459 glw::GLenum error = gl.getError(); 460 461 if (GL_INVALID_VALUE != error) 462 { 463 m_context.getTestContext().getLog() 464 << tcu::TestLog::Message << "glCreateQueries called with target " << s_target_names[i] 465 << " with negative number of objects to be created (-1) has generated error " << glu::getErrorStr(error) 466 << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage; 467 468 if (query) 469 { 470 gl.deleteQueries(1, &query); 471 472 while (error == gl.getError()) 473 ; 474 475 m_context.getTestContext().getLog() 476 << tcu::TestLog::Message << "glCreateQueries called with target " << s_target_names[i] 477 << " with negative number of objects to be created (-1) has created at least one object." 478 << tcu::TestLog::EndMessage; 479 } 480 481 return false; 482 } 483 } 484 485 return true; 486 } 487 488 /** @brief Check that CreateQueries generates INVALID_ENUM error if target is not 489 * one of accepted values: 490 * - SAMPLES_PASSED, 491 * - ANY_SAMPLES_PASSED, 492 * - ANY_SAMPLES_PASSED_CONSERVATIVE, 493 * - TIME_ELAPSED, 494 * - TIMESTAMP, 495 * - PRIMITIVES_GENERATED or 496 * - TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN. 497 * 498 * @return True if test succeded, false otherwise. 499 */ 500 bool ErrorsTest::testInvalidTarget() 501 { 502 /* Shortcut for GL functionality. */ 503 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 504 505 /* Creating invalid target. */ 506 glw::GLenum invalid_target = 0; 507 508 while (isTarget(++invalid_target)) 509 ; 510 511 /* Test. */ 512 glw::GLuint query = 0; 513 514 gl.createQueries(invalid_target, 1, &query); /* Create negative number of queries. */ 515 516 glw::GLenum error = gl.getError(); 517 518 if (GL_INVALID_ENUM != error) 519 { 520 m_context.getTestContext().getLog() << tcu::TestLog::Message << "glCreateQueries called with invalid target (" 521 << invalid_target << ") has generated error " << glu::getErrorStr(error) 522 << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage; 523 524 if (query) 525 { 526 gl.deleteQueries(1, &query); 527 528 while (error == gl.getError()) 529 ; 530 531 m_context.getTestContext().getLog() << tcu::TestLog::Message 532 << "glCreateQueries called with invalid target (" << invalid_target 533 << ") has created an object." << tcu::TestLog::EndMessage; 534 } 535 536 return false; 537 } 538 539 return true; 540 } 541 542 /** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv, 543 * GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate 544 * INVALID_OPERATION error if <id> is not the name of a query object, or 545 * if the query object named by <id> is currently active. 546 * 547 * @return True if test succeded, false otherwise. 548 */ 549 bool ErrorsTest::testInvalidQueryName() 550 { 551 /* Shortcut for GL functionality. */ 552 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 553 554 /* Creating invalid query name. */ 555 glw::GLuint invalid_query = 0; 556 557 /* Default result. */ 558 bool is_ok = true; 559 bool is_error = false; 560 561 while (gl.isQuery(++invalid_query)) 562 ; 563 564 /* Test's objects. */ 565 glw::GLuint buffer = 0; 566 glw::GLuint query = 0; 567 568 try 569 { 570 /* Creating buffer for the test. */ 571 gl.genBuffers(1, &buffer); 572 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed"); 573 574 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer); 575 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed"); 576 577 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY); 578 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed"); 579 580 /* Test invalid query object name (integer version). */ 581 m_pGetQueryBufferObjectiv(invalid_query, buffer, GL_QUERY_RESULT, 0); 582 583 glw::GLenum error = gl.getError(); 584 585 if (GL_INVALID_OPERATION != error) 586 { 587 m_context.getTestContext().getLog() 588 << tcu::TestLog::Message 589 << "glGetQueryBufferObjectiv called with invalid query name has generated error " 590 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 591 << tcu::TestLog::EndMessage; 592 593 is_ok = false; 594 } 595 596 /* Test invalid query object name (unsigned integer version). */ 597 m_pGetQueryBufferObjectuiv(invalid_query, buffer, GL_QUERY_RESULT, 0); 598 599 error = gl.getError(); 600 601 if (GL_INVALID_OPERATION != error) 602 { 603 m_context.getTestContext().getLog() 604 << tcu::TestLog::Message 605 << "glGetQueryBufferObjectuiv called with invalid query name has generated error " 606 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 607 << tcu::TestLog::EndMessage; 608 609 is_ok = false; 610 } 611 612 /* Test invalid query object name (64-bit integer version). */ 613 m_pGetQueryBufferObjecti64v(invalid_query, buffer, GL_QUERY_RESULT, 0); 614 615 error = gl.getError(); 616 617 if (GL_INVALID_OPERATION != error) 618 { 619 m_context.getTestContext().getLog() 620 << tcu::TestLog::Message 621 << "glGetQueryBufferObjecti64v called with invalid query name has generated error " 622 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 623 << tcu::TestLog::EndMessage; 624 625 is_ok = false; 626 } 627 628 /* Test invalid query object name (64-bit unsigned integer version). */ 629 m_pGetQueryBufferObjectui64v(invalid_query, buffer, GL_QUERY_RESULT, 0); 630 631 error = gl.getError(); 632 633 if (GL_INVALID_OPERATION != error) 634 { 635 m_context.getTestContext().getLog() 636 << tcu::TestLog::Message 637 << "glGetQueryBufferObjectui64v called with invalid query name has generated error " 638 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 639 << tcu::TestLog::EndMessage; 640 641 is_ok = false; 642 } 643 644 /* Create query object for the test. */ 645 gl.createQueries(s_targets[0], 1, &query); 646 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed"); 647 648 gl.beginQuery(s_targets[0], query); 649 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed"); 650 651 /* Test query of active query object name (integer version). */ 652 m_pGetQueryBufferObjectiv(query, buffer, GL_QUERY_RESULT, 0); 653 654 error = gl.getError(); 655 656 if (GL_INVALID_OPERATION != error) 657 { 658 m_context.getTestContext().getLog() 659 << tcu::TestLog::Message 660 << "glGetQueryBufferObjectiv called with active query object has generated error " 661 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 662 << tcu::TestLog::EndMessage; 663 664 is_ok = false; 665 } 666 667 /* Test query of active query object name (unsigned integer version). */ 668 m_pGetQueryBufferObjectuiv(query, buffer, GL_QUERY_RESULT, 0); 669 670 error = gl.getError(); 671 672 if (GL_INVALID_OPERATION != error) 673 { 674 m_context.getTestContext().getLog() 675 << tcu::TestLog::Message 676 << "glGetQueryBufferObjectuiv called with active query object has generated error " 677 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 678 << tcu::TestLog::EndMessage; 679 680 is_ok = false; 681 } 682 683 /* Test query of active query object name (64-bit integer version). */ 684 m_pGetQueryBufferObjecti64v(query, buffer, GL_QUERY_RESULT, 0); 685 686 error = gl.getError(); 687 688 if (GL_INVALID_OPERATION != error) 689 { 690 m_context.getTestContext().getLog() 691 << tcu::TestLog::Message 692 << "glGetQueryBufferObjecti64v called with active query object has generated error " 693 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 694 << tcu::TestLog::EndMessage; 695 696 is_ok = false; 697 } 698 699 /* Test query of active query object name (64-bit unsigned integer version). */ 700 m_pGetQueryBufferObjectui64v(query, buffer, GL_QUERY_RESULT, 0); 701 702 error = gl.getError(); 703 704 if (GL_INVALID_OPERATION != error) 705 { 706 m_context.getTestContext().getLog() 707 << tcu::TestLog::Message 708 << "glGetQueryBufferObjectui64v called with active query object has generated error " 709 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 710 << tcu::TestLog::EndMessage; 711 712 is_ok = false; 713 } 714 } 715 catch (...) 716 { 717 is_error = true; 718 } 719 720 /* Releasing objects. */ 721 if (query) 722 { 723 gl.endQuery(s_targets[0]); 724 725 gl.deleteQueries(1, &query); 726 } 727 728 if (buffer) 729 { 730 gl.deleteBuffers(1, &buffer); 731 } 732 733 /* Error cleanup. */ 734 while (gl.getError()) 735 ; 736 737 if (is_error) 738 { 739 throw 0; 740 } 741 742 return is_ok; 743 } 744 745 /** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv, 746 * GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate 747 * INVALID_OPERATION error if <buffer> is not the name of an existing 748 * buffer object. 749 * 750 * @return True if test succeded, false otherwise. 751 */ 752 bool ErrorsTest::testInvalidBufferName() 753 { 754 /* Shortcut for GL functionality. */ 755 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 756 757 /* Default result. */ 758 bool is_ok = true; 759 bool is_error = false; 760 761 /* Creating invalid buffer name. */ 762 glw::GLuint invalid_buffer = 0; 763 764 while (gl.isBuffer(++invalid_buffer)) 765 ; 766 767 /* Test's objects. */ 768 glw::GLuint query = 0; 769 770 try 771 { 772 /* Create query object for the test. */ 773 gl.createQueries(s_targets[0], 1, &query); 774 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed"); 775 776 /* Test query of invalid buffer name (integer version). */ 777 m_pGetQueryBufferObjectiv(query, invalid_buffer, GL_QUERY_RESULT_AVAILABLE, 0); 778 779 glw::GLenum error = gl.getError(); 780 781 if (GL_INVALID_OPERATION != error) 782 { 783 m_context.getTestContext().getLog() 784 << tcu::TestLog::Message 785 << "glGetQueryBufferObjectiv which could generate buffers overflow generated error " 786 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 787 << tcu::TestLog::EndMessage; 788 789 is_ok = false; 790 } 791 792 /* Test query of invalid buffer name (unsigned integer version). */ 793 m_pGetQueryBufferObjectuiv(query, invalid_buffer, GL_QUERY_RESULT_AVAILABLE, 0); 794 795 error = gl.getError(); 796 797 if (GL_INVALID_OPERATION != error) 798 { 799 m_context.getTestContext().getLog() 800 << tcu::TestLog::Message 801 << "glGetQueryBufferObjectuiv which could generate buffers overflow generated error " 802 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 803 << tcu::TestLog::EndMessage; 804 805 is_ok = false; 806 } 807 808 /* Test query of invalid buffer name (64-bit integer version). */ 809 m_pGetQueryBufferObjecti64v(query, invalid_buffer, GL_QUERY_RESULT_AVAILABLE, 0); 810 811 error = gl.getError(); 812 813 if (GL_INVALID_OPERATION != error) 814 { 815 m_context.getTestContext().getLog() 816 << tcu::TestLog::Message 817 << "glGetQueryBufferObjecti64v which could generate buffers overflow generated error " 818 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 819 << tcu::TestLog::EndMessage; 820 821 is_ok = false; 822 } 823 824 /* Test query of invalid buffer name (64-bit unsigned integer version). */ 825 m_pGetQueryBufferObjectui64v(query, invalid_buffer, GL_QUERY_RESULT_AVAILABLE, 0); 826 827 error = gl.getError(); 828 829 if (GL_INVALID_OPERATION != error) 830 { 831 m_context.getTestContext().getLog() 832 << tcu::TestLog::Message 833 << "glGetQueryBufferObjectui64v which could generate buffers overflow generated error " 834 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 835 << tcu::TestLog::EndMessage; 836 837 is_ok = false; 838 } 839 } 840 catch (...) 841 { 842 is_error = true; 843 } 844 845 /* Releasing objects. */ 846 if (query) 847 { 848 gl.deleteQueries(1, &query); 849 } 850 851 /* Error cleanup. */ 852 while (gl.getError()) 853 ; 854 855 if (is_error) 856 { 857 throw 0; 858 } 859 860 return is_ok; 861 } 862 863 /** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv, 864 * GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate 865 * INVALID_ENUM error if <pname> is not QUERY_RESULT, 866 * QUERY_RESULT_AVAILABLE, QUERY_RESULT_NO_WAIT or QUERY_TARGET. 867 * 868 * @return True if test succeded, false otherwise. 869 */ 870 bool ErrorsTest::testInvalidParameterName() 871 { 872 /* Shortcut for GL functionality. */ 873 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 874 875 /* Creating invalid parameter name. */ 876 glw::GLuint invalid_pname = 0; 877 878 while (isParameterName(++invalid_pname)) 879 ; 880 881 /* Default result. */ 882 bool is_ok = true; 883 bool is_error = false; 884 885 /* Test's objects. */ 886 glw::GLuint buffer = 0; 887 glw::GLuint query = 0; 888 889 try 890 { 891 /* Creating buffer for the test. */ 892 gl.genBuffers(1, &buffer); 893 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed"); 894 895 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer); 896 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed"); 897 898 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY); 899 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed"); 900 901 /* Create query object for the test. */ 902 gl.createQueries(s_targets[0], 1, &query); 903 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed"); 904 905 /* Test query of invalid parameter name (integer version). */ 906 m_pGetQueryBufferObjectiv(query, buffer, invalid_pname, 0); 907 908 glw::GLenum error = gl.getError(); 909 910 if (GL_INVALID_ENUM != error) 911 { 912 m_context.getTestContext().getLog() 913 << tcu::TestLog::Message 914 << "glGetQueryBufferObjectiv called with invalid parameter name has generated error " 915 << glu::getErrorStr(error) << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage; 916 917 is_ok = false; 918 } 919 920 /* Test query of invalid parameter name (unsigned integer version). */ 921 m_pGetQueryBufferObjectuiv(query, buffer, invalid_pname, 0); 922 923 error = gl.getError(); 924 925 if (GL_INVALID_ENUM != error) 926 { 927 m_context.getTestContext().getLog() 928 << tcu::TestLog::Message 929 << "glGetQueryBufferObjectuiv called with invalid parameter name has generated error " 930 << glu::getErrorStr(error) << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage; 931 932 is_ok = false; 933 } 934 935 /* Test query of invalid parameter name (64-bit integer version). */ 936 m_pGetQueryBufferObjecti64v(query, buffer, invalid_pname, 0); 937 938 error = gl.getError(); 939 940 if (GL_INVALID_ENUM != error) 941 { 942 m_context.getTestContext().getLog() 943 << tcu::TestLog::Message 944 << "glGetQueryBufferObjecti64v called with invalid parameter name has generated error " 945 << glu::getErrorStr(error) << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage; 946 947 is_ok = false; 948 } 949 950 /* Test query of invalid parameter name (64-bit unsigned integer version). */ 951 m_pGetQueryBufferObjectui64v(query, buffer, invalid_pname, 0); 952 953 error = gl.getError(); 954 955 if (GL_INVALID_ENUM != error) 956 { 957 m_context.getTestContext().getLog() 958 << tcu::TestLog::Message 959 << "glGetQueryBufferObjectui64v called with invalid parameter name has generated error " 960 << glu::getErrorStr(error) << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage; 961 962 is_ok = false; 963 } 964 } 965 catch (...) 966 { 967 is_error = true; 968 } 969 970 /* Releasing objects. */ 971 if (query) 972 { 973 gl.deleteQueries(1, &query); 974 } 975 976 if (buffer) 977 { 978 gl.deleteBuffers(1, &buffer); 979 } 980 981 /* Error cleanup. */ 982 while (gl.getError()) 983 ; 984 985 if (is_error) 986 { 987 throw 0; 988 } 989 990 return is_ok; 991 } 992 993 /** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv, 994 * GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate 995 * INVALID_OPERATION error if the query writes to a buffer object, and the 996 * specified buffer offset would cause data to be written beyond the bounds 997 * of that buffer object. 998 * 999 * @return True if test succeded, false otherwise. 1000 */ 1001 bool ErrorsTest::testBufferOverflow() 1002 { 1003 /* Shortcut for GL functionality. */ 1004 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1005 1006 /* Default result. */ 1007 bool is_ok = true; 1008 bool is_error = false; 1009 1010 /* Test's objects. */ 1011 glw::GLuint buffer = 0; 1012 glw::GLuint query = 0; 1013 1014 try 1015 { 1016 /* Creating buffer for the test. */ 1017 gl.genBuffers(1, &buffer); 1018 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed"); 1019 1020 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer); 1021 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed"); 1022 1023 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY); 1024 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed"); 1025 1026 /* Create query object for the test. */ 1027 gl.createQueries(s_targets[0], 1, &query); 1028 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed"); 1029 1030 /* Test query of buffer overflow (integer version). */ 1031 m_pGetQueryBufferObjectiv(query, buffer, GL_QUERY_RESULT_AVAILABLE, sizeof(glw::GLint64)); 1032 1033 glw::GLenum error = gl.getError(); 1034 1035 if (GL_INVALID_OPERATION != error) 1036 { 1037 m_context.getTestContext().getLog() 1038 << tcu::TestLog::Message 1039 << "glGetQueryBufferObjectiv which could generate buffers overflow generated error " 1040 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 1041 << tcu::TestLog::EndMessage; 1042 1043 is_ok = false; 1044 } 1045 1046 /* Test query of buffer overflow (unsigned integer version). */ 1047 m_pGetQueryBufferObjectuiv(query, buffer, GL_QUERY_RESULT_AVAILABLE, sizeof(glw::GLint64)); 1048 1049 error = gl.getError(); 1050 1051 if (GL_INVALID_OPERATION != error) 1052 { 1053 m_context.getTestContext().getLog() 1054 << tcu::TestLog::Message 1055 << "glGetQueryBufferObjectuiv which could generate buffers overflow generated error " 1056 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 1057 << tcu::TestLog::EndMessage; 1058 1059 is_ok = false; 1060 } 1061 1062 /* Test query of buffer overflow (64-bit integer version). */ 1063 m_pGetQueryBufferObjecti64v(query, buffer, GL_QUERY_RESULT_AVAILABLE, sizeof(glw::GLint64)); 1064 1065 error = gl.getError(); 1066 1067 if (GL_INVALID_OPERATION != error) 1068 { 1069 m_context.getTestContext().getLog() 1070 << tcu::TestLog::Message 1071 << "glGetQueryBufferObjecti64v which could generate buffers overflow generated error " 1072 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 1073 << tcu::TestLog::EndMessage; 1074 1075 is_ok = false; 1076 } 1077 1078 /* Test query of buffer overflow (64-bit unsigned integer version). */ 1079 m_pGetQueryBufferObjectui64v(query, buffer, GL_QUERY_RESULT_AVAILABLE, sizeof(glw::GLint64)); 1080 1081 error = gl.getError(); 1082 1083 if (GL_INVALID_OPERATION != error) 1084 { 1085 m_context.getTestContext().getLog() 1086 << tcu::TestLog::Message 1087 << "glGetQueryBufferObjectui64v which could generate buffers overflow generated error " 1088 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected." 1089 << tcu::TestLog::EndMessage; 1090 1091 is_ok = false; 1092 } 1093 } 1094 catch (...) 1095 { 1096 is_error = true; 1097 } 1098 1099 /* Releasing objects. */ 1100 if (query) 1101 { 1102 gl.deleteQueries(1, &query); 1103 } 1104 1105 if (buffer) 1106 { 1107 gl.deleteBuffers(1, &buffer); 1108 } 1109 1110 /* Error cleanup. */ 1111 while (gl.getError()) 1112 ; 1113 1114 if (is_error) 1115 { 1116 throw 0; 1117 } 1118 1119 return is_ok; 1120 } 1121 1122 /** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv, 1123 * GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate 1124 * INVALID_VALUE error if <offset> is negative. 1125 * 1126 * @return True if test succeded, false otherwise. 1127 */ 1128 bool ErrorsTest::testBufferNegativeOffset() 1129 { 1130 /* Shortcut for GL functionality. */ 1131 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1132 1133 /* Default result. */ 1134 bool is_ok = true; 1135 bool is_error = false; 1136 1137 /* Test's objects. */ 1138 glw::GLuint buffer = 0; 1139 glw::GLuint query = 0; 1140 1141 try 1142 { 1143 /* Creating buffer for the test. */ 1144 gl.genBuffers(1, &buffer); 1145 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed"); 1146 1147 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer); 1148 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed"); 1149 1150 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY); 1151 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed"); 1152 1153 /* Create query object for the test. */ 1154 gl.createQueries(s_targets[0], 1, &query); 1155 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed"); 1156 1157 /* Test query with negative offset (integer version). */ 1158 m_pGetQueryBufferObjectiv(query, buffer, GL_QUERY_RESULT_AVAILABLE, -1); 1159 1160 glw::GLenum error = gl.getError(); 1161 1162 if (GL_INVALID_VALUE != error) 1163 { 1164 m_context.getTestContext().getLog() 1165 << tcu::TestLog::Message << "glGetQueryBufferObjectiv called with negative offset generated error " 1166 << glu::getErrorStr(error) << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage; 1167 1168 is_ok = false; 1169 } 1170 1171 /* Test query with negative offset (unsigned integer version). */ 1172 m_pGetQueryBufferObjectuiv(query, buffer, GL_QUERY_RESULT_AVAILABLE, -1); 1173 1174 error = gl.getError(); 1175 1176 if (GL_INVALID_VALUE != error) 1177 { 1178 m_context.getTestContext().getLog() 1179 << tcu::TestLog::Message << "glGetQueryBufferObjectuiv called with negative offset generated error " 1180 << glu::getErrorStr(error) << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage; 1181 1182 is_ok = false; 1183 } 1184 1185 /* Test query with negative offset (64-bit integer version). */ 1186 m_pGetQueryBufferObjecti64v(query, buffer, GL_QUERY_RESULT_AVAILABLE, -1); 1187 1188 error = gl.getError(); 1189 1190 if (GL_INVALID_VALUE != error) 1191 { 1192 m_context.getTestContext().getLog() 1193 << tcu::TestLog::Message << "glGetQueryBufferObjecti64v called with negative offset generated error " 1194 << glu::getErrorStr(error) << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage; 1195 1196 is_ok = false; 1197 } 1198 1199 /* Test query with negative offset (64-bit unsigned integer version). */ 1200 m_pGetQueryBufferObjectui64v(query, buffer, GL_QUERY_RESULT_AVAILABLE, -1); 1201 1202 error = gl.getError(); 1203 1204 if (GL_INVALID_VALUE != error) 1205 { 1206 m_context.getTestContext().getLog() 1207 << tcu::TestLog::Message << "glGetQueryBufferObjectui64v called with negative offset generated error " 1208 << glu::getErrorStr(error) << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage; 1209 1210 is_ok = false; 1211 } 1212 } 1213 catch (...) 1214 { 1215 is_error = true; 1216 } 1217 1218 /* Releasing objects. */ 1219 if (query) 1220 { 1221 gl.deleteQueries(1, &query); 1222 } 1223 1224 if (buffer) 1225 { 1226 gl.deleteBuffers(1, &buffer); 1227 } 1228 1229 /* Error cleanup. */ 1230 while (gl.getError()) 1231 ; 1232 1233 if (is_error) 1234 { 1235 throw 0; 1236 } 1237 1238 return is_ok; 1239 } 1240 1241 /** @brief Check if argument is one of the target names: 1242 * - SAMPLES_PASSED, 1243 * - TIME_ELAPSED, 1244 * - PRIMITIVES_GENERATED, 1245 * - TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN. 1246 * 1247 * @param [in] maybe_target Target to be checked. 1248 * 1249 * @return True if argument is one of the listed targets, false otherwise. 1250 */ 1251 bool ErrorsTest::isTarget(glw::GLenum maybe_target) 1252 { 1253 for (glw::GLuint i = 0; i < s_targets_count; ++i) 1254 { 1255 if (maybe_target == s_targets[i]) 1256 { 1257 return true; 1258 } 1259 } 1260 1261 return false; 1262 } 1263 1264 /** @brief Check if argument is one of the parameter names: 1265 * - QUERY_RESULT, 1266 * - QUERY_RESULT_AVAILABLE, 1267 * - QUERY_RESULT_NO_WAIT, 1268 * - QUERY_TARGET. 1269 * 1270 * @param [in] maybe_pname Parameter name to be checked. 1271 * 1272 * @return True if argument is one of the listed parameters, false otherwise. 1273 */ 1274 bool ErrorsTest::isParameterName(glw::GLenum maybe_pname) 1275 { 1276 glw::GLenum pnames[] = { GL_QUERY_RESULT, GL_QUERY_RESULT_AVAILABLE, GL_QUERY_RESULT_NO_WAIT, GL_QUERY_TARGET }; 1277 glw::GLuint pnames_count = sizeof(pnames) / sizeof(pnames[0]); 1278 1279 for (glw::GLuint i = 0; i < pnames_count; ++i) 1280 { 1281 if (maybe_pname == pnames[i]) 1282 { 1283 return true; 1284 } 1285 } 1286 1287 return false; 1288 } 1289 1290 /** Targets to be tested. */ 1291 const glw::GLenum ErrorsTest::s_targets[] = { 1292 GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_TIME_ELAPSED, 1293 GL_TIMESTAMP, GL_PRIMITIVES_GENERATED, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 1294 }; 1295 1296 /** Names of targets to be tested. */ 1297 const glw::GLchar* ErrorsTest::s_target_names[] = { 1298 "GL_SAMPLES_PASSED", "GL_ANY_SAMPLES_PASSED", "GL_ANY_SAMPLES_PASSED_CONSERVATIVE", "GL_TIME_ELAPSED", 1299 "GL_TIMESTAMP", "GL_PRIMITIVES_GENERATED", "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN" 1300 }; 1301 1302 /** Number of targets. */ 1303 const glw::GLuint ErrorsTest::s_targets_count = sizeof(s_targets) / sizeof(s_targets[0]); 1304 1305 /******************************** Functional Test Implementation ********************************/ 1306 1307 /** @brief Functional Test constructor. 1308 * 1309 * @param [in] context OpenGL context. 1310 */ 1311 FunctionalTest::FunctionalTest(deqp::Context& context) 1312 : deqp::TestCase(context, "queries_functional", "Queries Functional Test") 1313 , m_pGetQueryBufferObjectiv(DE_NULL) 1314 , m_pGetQueryBufferObjectuiv(DE_NULL) 1315 , m_pGetQueryBufferObjecti64v(DE_NULL) 1316 , m_pGetQueryBufferObjectui64v(DE_NULL) 1317 , m_fbo(0) 1318 , m_rbo(0) 1319 , m_vao(0) 1320 , m_bo_query(0) 1321 , m_bo_xfb(0) 1322 , m_qo(DE_NULL) 1323 , m_po(0) 1324 { 1325 /* Intentionally left blank. */ 1326 } 1327 1328 /** @brief Do comparison (a == b). 1329 * 1330 * @tparam Type of the values to be compared. 1331 * 1332 * @param [in] a First value to be compared. 1333 * @param [in] b Second value to be compared. 1334 * 1335 * @return Result of the comparison. 1336 */ 1337 template <typename T> 1338 bool FunctionalTest::equal(T a, T b) 1339 { 1340 return (a == b); 1341 } 1342 1343 /** @brief Do comparison (a < b). 1344 * 1345 * @tparam Type of the values to be compared. 1346 * 1347 * @param [in] a First value to be compared. 1348 * @param [in] b Second value to be compared. 1349 * 1350 * @return Result of the comparison. 1351 */ 1352 template <typename T> 1353 bool FunctionalTest::less(T a, T b) 1354 { 1355 return (a < b); 1356 } 1357 1358 /** @brief Template specialization of glGetQueryBufferObject* function for GLint. 1359 * This is pass through function to glGetQueryBufferObjectiv 1360 * 1361 * @param [in] id Query object identifier. 1362 * @param [in] buffer Buffer object identifier. 1363 * @param [in] pname Parameter name to be queried. 1364 * @param [in] offset Offset of the buffer to be saved at. 1365 */ 1366 template <> 1367 void FunctionalTest::GetQueryBufferObject<glw::GLint>(glw::GLuint id, glw::GLuint buffer, glw::GLenum pname, 1368 glw::GLintptr offset) 1369 { 1370 m_pGetQueryBufferObjectiv(id, buffer, pname, offset); 1371 } 1372 1373 /** @brief Template specialization of glGetQueryBufferObject* function for GLuint. 1374 * This is pass through function to glGetQueryBufferObjectuiv 1375 * 1376 * @param [in] id Query object identifier. 1377 * @param [in] buffer Buffer object identifier. 1378 * @param [in] pname Parameter name to be queried. 1379 * @param [in] offset Offset of the buffer to be saved at. 1380 */ 1381 template <> 1382 void FunctionalTest::GetQueryBufferObject<glw::GLuint>(glw::GLuint id, glw::GLuint buffer, glw::GLenum pname, 1383 glw::GLintptr offset) 1384 { 1385 m_pGetQueryBufferObjectuiv(id, buffer, pname, offset); 1386 } 1387 1388 /** @brief Template specialization of glGetQueryBufferObject* function for GLint64. 1389 * This is pass through function to glGetQueryBufferObjecti64v 1390 * 1391 * @param [in] id Query object identifier. 1392 * @param [in] buffer Buffer object identifier. 1393 * @param [in] pname Parameter name to be queried. 1394 * @param [in] offset Offset of the buffer to be saved at. 1395 */ 1396 template <> 1397 void FunctionalTest::GetQueryBufferObject<glw::GLint64>(glw::GLuint id, glw::GLuint buffer, glw::GLenum pname, 1398 glw::GLintptr offset) 1399 { 1400 m_pGetQueryBufferObjecti64v(id, buffer, pname, offset); 1401 } 1402 1403 /** @brief Template specialization of glGetQueryBufferObject* function for GLuint64. 1404 * This is pass through function to glGetQueryBufferObjectui64v 1405 * 1406 * @param [in] id Query object identifier. 1407 * @param [in] buffer Buffer object identifier. 1408 * @param [in] pname Parameter name to be queried. 1409 * @param [in] offset Offset of the buffer to be saved at. 1410 */ 1411 template <> 1412 void FunctionalTest::GetQueryBufferObject<glw::GLuint64>(glw::GLuint id, glw::GLuint buffer, glw::GLenum pname, 1413 glw::GLintptr offset) 1414 { 1415 m_pGetQueryBufferObjectui64v(id, buffer, pname, offset); 1416 } 1417 1418 /** @brief Function template fetches query result to buffer object using 1419 * glGetQueryBufferObject* function (selected on the basis of template parameter). 1420 * Then buffer is mapped and the result is compared with expected_value using comparison function. 1421 * 1422 * @tparam Templated type of fetched data. 1423 * It shall be one of glw::GL[u]int[64]. 1424 * 1425 * @param [in] query Query object to be queried. 1426 * @param [in] pname Parameter name to be queried. 1427 * @param [in] expected_value Reference value to be compared. 1428 * @param [in] comparison Comparison function pointer. 1429 * Comparsion function shall NOT throw. 1430 * 1431 * @note The function may throw if unexpected error has occured. 1432 * 1433 * @return True if comparison succeeded, false otherwise. 1434 */ 1435 template <typename T> 1436 bool FunctionalTest::checkQueryBufferObject(glw::GLuint query, glw::GLenum pname, T expected_value, 1437 bool (*comparison)(T, T)) 1438 { 1439 /* Shortcut for GL functionality. */ 1440 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1441 1442 /* Default result. */ 1443 bool is_ok = true; 1444 1445 /* Saving results to buffer. */ 1446 GetQueryBufferObject<T>(query, m_bo_query, pname, 0); 1447 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryBufferObject* have failed"); 1448 1449 /* Mapping buffer to user space. */ 1450 T* value = (T*)gl.mapBuffer(GL_QUERY_BUFFER, GL_READ_ONLY); 1451 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer have failed"); 1452 1453 /* Doing test. */ 1454 if (!comparison(expected_value, *value)) 1455 { 1456 is_ok = false; 1457 } 1458 1459 /* Cleanup. */ 1460 gl.unmapBuffer(GL_QUERY_BUFFER); 1461 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer have failed"); 1462 1463 /* Return test result. */ 1464 return is_ok; 1465 } 1466 1467 /** @brief Iterate Functional Test cases. 1468 * 1469 * @return Iteration result. 1470 */ 1471 tcu::TestNode::IterateResult FunctionalTest::iterate() 1472 { 1473 /* Shortcut for GL functionality. */ 1474 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1475 1476 /* Get context setup. */ 1477 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 1478 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 1479 1480 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 1481 { 1482 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 1483 1484 return STOP; 1485 } 1486 1487 /* Fetching access point to GL functions. */ 1488 m_pGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectiv; 1489 m_pGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectuiv; 1490 m_pGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjecti64v; 1491 m_pGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectui64v; 1492 1493 /* Running tests. */ 1494 bool is_ok = true; 1495 bool is_error = false; 1496 1497 try 1498 { 1499 if ((DE_NULL == m_pGetQueryBufferObjectiv) || (DE_NULL == m_pGetQueryBufferObjectuiv) || 1500 (DE_NULL == m_pGetQueryBufferObjecti64v) || (DE_NULL == m_pGetQueryBufferObjectui64v)) 1501 { 1502 m_context.getTestContext().getLog() 1503 << tcu::TestLog::Message << "Test could not get the pointers for glGetQueryBufferObject* functions." 1504 << tcu::TestLog::EndMessage; 1505 1506 throw 0; 1507 } 1508 1509 prepareView(); 1510 prepareVertexArray(); 1511 prepareBuffers(); 1512 prepareQueries(); 1513 prepareProgram(); 1514 1515 draw(); 1516 1517 /* Make sure that framebuffer and transform feedback buffer are filled with expectd data. */ 1518 is_ok &= checkView(); 1519 is_ok &= checkXFB(); 1520 1521 /* Make comparisons for each query object. */ 1522 for (glw::GLuint i = 0; i < s_targets_count; ++i) 1523 { 1524 /* Checking targets. */ 1525 is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_TARGET, s_targets[i], 1526 &FunctionalTest::equal<glw::GLint>); 1527 is_ok &= checkQueryBufferObject<glw::GLuint>(m_qo[i], GL_QUERY_TARGET, s_targets[i], 1528 &FunctionalTest::equal<glw::GLuint>); 1529 is_ok &= checkQueryBufferObject<glw::GLint64>(m_qo[i], GL_QUERY_TARGET, s_targets[i], 1530 &FunctionalTest::equal<glw::GLint64>); 1531 is_ok &= checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_TARGET, s_targets[i], 1532 &FunctionalTest::equal<glw::GLuint64>); 1533 1534 /* Checking result availability. */ 1535 is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT_AVAILABLE, GL_TRUE, 1536 &FunctionalTest::equal<glw::GLint>); 1537 is_ok &= checkQueryBufferObject<glw::GLuint>(m_qo[i], GL_QUERY_RESULT_AVAILABLE, GL_TRUE, 1538 &FunctionalTest::equal<glw::GLuint>); 1539 is_ok &= checkQueryBufferObject<glw::GLint64>(m_qo[i], GL_QUERY_RESULT_AVAILABLE, GL_TRUE, 1540 &FunctionalTest::equal<glw::GLint64>); 1541 is_ok &= checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT_AVAILABLE, GL_TRUE, 1542 &FunctionalTest::equal<glw::GLuint64>); 1543 1544 if (GL_TIME_ELAPSED == s_targets[i]) 1545 { 1546 /* Checking result. */ 1547 is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT, (glw::GLint)s_results[i], 1548 &FunctionalTest::less<glw::GLint>); 1549 is_ok &= checkQueryBufferObject<glw::GLuint>(m_qo[i], GL_QUERY_RESULT, (glw::GLuint)s_results[i], 1550 &FunctionalTest::less<glw::GLuint>); 1551 is_ok &= checkQueryBufferObject<glw::GLint64>(m_qo[i], GL_QUERY_RESULT, (glw::GLint64)s_results[i], 1552 &FunctionalTest::less<glw::GLint64>); 1553 is_ok &= checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT, (glw::GLuint64)s_results[i], 1554 &FunctionalTest::less<glw::GLuint64>); 1555 1556 /* Checking result (no-wait). */ 1557 is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLint)s_results[i], 1558 &FunctionalTest::less<glw::GLint>); 1559 is_ok &= checkQueryBufferObject<glw::GLuint>( 1560 m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLuint)s_results[i], &FunctionalTest::less<glw::GLuint>); 1561 is_ok &= checkQueryBufferObject<glw::GLint64>( 1562 m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLint64)s_results[i], &FunctionalTest::less<glw::GLint64>); 1563 is_ok &= 1564 checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLuint64)s_results[i], 1565 &FunctionalTest::less<glw::GLuint64>); 1566 } 1567 else 1568 { 1569 /* Checking result. */ 1570 is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT, (glw::GLint)s_results[i], 1571 &FunctionalTest::equal<glw::GLint>); 1572 is_ok &= checkQueryBufferObject<glw::GLuint>(m_qo[i], GL_QUERY_RESULT, (glw::GLuint)s_results[i], 1573 &FunctionalTest::equal<glw::GLuint>); 1574 is_ok &= checkQueryBufferObject<glw::GLint64>(m_qo[i], GL_QUERY_RESULT, (glw::GLint64)s_results[i], 1575 &FunctionalTest::equal<glw::GLint64>); 1576 is_ok &= checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT, (glw::GLuint64)s_results[i], 1577 &FunctionalTest::equal<glw::GLuint64>); 1578 1579 /* Checking result (no-wait). */ 1580 is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLint)s_results[i], 1581 &FunctionalTest::equal<glw::GLint>); 1582 is_ok &= checkQueryBufferObject<glw::GLuint>( 1583 m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLuint)s_results[i], &FunctionalTest::equal<glw::GLuint>); 1584 is_ok &= checkQueryBufferObject<glw::GLint64>( 1585 m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLint64)s_results[i], &FunctionalTest::equal<glw::GLint64>); 1586 is_ok &= 1587 checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLuint64)s_results[i], 1588 &FunctionalTest::equal<glw::GLuint64>); 1589 } 1590 } 1591 } 1592 catch (...) 1593 { 1594 is_ok = false; 1595 is_error = true; 1596 } 1597 1598 /* Clean up. */ 1599 clean(); 1600 1601 /* Result's setup. */ 1602 if (is_ok) 1603 { 1604 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1605 } 1606 else 1607 { 1608 if (is_error) 1609 { 1610 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 1611 } 1612 else 1613 { 1614 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1615 } 1616 } 1617 1618 return STOP; 1619 } 1620 1621 /** @brief Function prepares framebuffer with RGBA8 color attachment. 1622 * Viewport is set up. Content of the framebuffer is cleared. 1623 * 1624 * @note The function may throw if unexpected error has occured. 1625 */ 1626 void FunctionalTest::prepareView() 1627 { 1628 /* Shortcut for GL functionality. */ 1629 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1630 1631 /* Prepare framebuffer. */ 1632 gl.genFramebuffers(1, &m_fbo); 1633 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed."); 1634 1635 gl.genRenderbuffers(1, &m_rbo); 1636 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed."); 1637 1638 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); 1639 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); 1640 1641 gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo); 1642 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed."); 1643 1644 gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1 /* x size */, 1 /* y size */); 1645 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed."); 1646 1647 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo); 1648 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed."); 1649 1650 if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 1651 { 1652 throw 0; 1653 } 1654 1655 gl.viewport(0, 0, 1, 1); 1656 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed."); 1657 1658 /* Clear framebuffer's content. */ 1659 gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 1660 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed."); 1661 1662 gl.clear(GL_COLOR_BUFFER_BIT); 1663 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed."); 1664 } 1665 1666 /** @brief Function creates and binds empty vertex array. 1667 * 1668 * @note The function may throw if unexpected error has occured. 1669 */ 1670 void FunctionalTest::prepareVertexArray() 1671 { 1672 /* Shortcut for GL functionality. */ 1673 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1674 1675 /* Creating and binding VAO. */ 1676 gl.genVertexArrays(1, &m_vao); 1677 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays have failed"); 1678 1679 gl.bindVertexArray(m_vao); 1680 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray have failed"); 1681 } 1682 1683 /** @brief Function creates buffers for query and transform feedback data storage. 1684 * The storage is allocated and buffers are bound to QUERY_BUFFER and 1685 * TRANSFORM_FEEDBACK_BUFFER binding points respectively. 1686 * 1687 * @note The function may throw if unexpected error has occured. 1688 */ 1689 void FunctionalTest::prepareBuffers() 1690 { 1691 /* Shortcut for GL functionality. */ 1692 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1693 1694 /* Buffer for storing query's result. */ 1695 gl.genBuffers(1, &m_bo_query); 1696 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed"); 1697 1698 gl.bindBuffer(GL_QUERY_BUFFER, m_bo_query); 1699 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed"); 1700 1701 gl.bufferData(GL_QUERY_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY); 1702 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed"); 1703 1704 /* Buffer for storing transform feedback results. */ 1705 gl.genBuffers(1, &m_bo_xfb); 1706 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed"); 1707 1708 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb); 1709 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed"); 1710 1711 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1712 3 /* number of vertices per triangle */ * 2 /* number of triangles */ * sizeof(glw::GLint), DE_NULL, 1713 GL_DYNAMIC_COPY); 1714 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed"); 1715 1716 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb); 1717 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase have failed"); 1718 } 1719 1720 /** @brief Function creates array of query objects using DSA-style method. 1721 * 1722 * @note The function may throw if unexpected error has occured. 1723 */ 1724 void FunctionalTest::prepareQueries() 1725 { 1726 /* Shortcut for GL functionality. */ 1727 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1728 1729 /* Allocating memory for queries array. */ 1730 m_qo = new glw::GLuint[s_targets_count]; 1731 1732 if (DE_NULL == m_qo) 1733 { 1734 throw 0; 1735 } 1736 1737 /* Creating query object for each target. */ 1738 for (glw::GLuint i = 0; i < s_targets_count; ++i) 1739 { 1740 gl.createQueries(s_targets[i], 1, &m_qo[i]); 1741 1742 /* Error checking. */ 1743 if (GL_NO_ERROR != gl.getError()) 1744 { 1745 /* Remove previous. */ 1746 if (i > 0) 1747 { 1748 gl.deleteQueries(i, m_qo); 1749 } 1750 1751 /* Deallocate storage. */ 1752 delete[] m_qo; 1753 1754 m_qo = DE_NULL; 1755 1756 /* Signalise test failure. */ 1757 throw 0; 1758 } 1759 } 1760 } 1761 1762 /** @brief Function builds test's GLSL program. 1763 * If succeded, the program will be set to be used. 1764 * 1765 * @note The function may throw if unexpected error has occured. 1766 */ 1767 void FunctionalTest::prepareProgram() 1768 { 1769 /* Shortcut for GL functionality */ 1770 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1771 1772 struct Shader 1773 { 1774 glw::GLchar const* const source; 1775 glw::GLenum const type; 1776 glw::GLuint id; 1777 } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } }; 1778 1779 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]); 1780 1781 try 1782 { 1783 /* Create program. */ 1784 m_po = gl.createProgram(); 1785 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed."); 1786 1787 /* Shader compilation. */ 1788 1789 for (glw::GLuint i = 0; i < shader_count; ++i) 1790 { 1791 if (DE_NULL != shader[i].source) 1792 { 1793 shader[i].id = gl.createShader(shader[i].type); 1794 1795 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed."); 1796 1797 gl.attachShader(m_po, shader[i].id); 1798 1799 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed."); 1800 1801 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL); 1802 1803 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed."); 1804 1805 gl.compileShader(shader[i].id); 1806 1807 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed."); 1808 1809 glw::GLint status = GL_FALSE; 1810 1811 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status); 1812 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 1813 1814 if (GL_FALSE == status) 1815 { 1816 glw::GLint log_size = 0; 1817 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size); 1818 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 1819 1820 glw::GLchar* log_text = new glw::GLchar[log_size]; 1821 1822 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]); 1823 1824 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n" 1825 << "Shader type: " << glu::getShaderTypeStr(shader[i].type) 1826 << "\n" 1827 << "Shader compilation error log:\n" 1828 << log_text << "\n" 1829 << "Shader source code:\n" 1830 << shader[i].source << "\n" 1831 << tcu::TestLog::EndMessage; 1832 1833 delete[] log_text; 1834 1835 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed."); 1836 1837 throw 0; 1838 } 1839 } 1840 } 1841 1842 /* Transform Feedback setup. */ 1843 gl.transformFeedbackVaryings(m_po, 1, &s_xfb_varying_name, GL_INTERLEAVED_ATTRIBS); 1844 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 1845 1846 /* Link. */ 1847 gl.linkProgram(m_po); 1848 1849 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 1850 1851 glw::GLint status = GL_FALSE; 1852 1853 gl.getProgramiv(m_po, GL_LINK_STATUS, &status); 1854 1855 if (GL_TRUE == status) 1856 { 1857 for (glw::GLuint i = 0; i < shader_count; ++i) 1858 { 1859 if (shader[i].id) 1860 { 1861 gl.detachShader(m_po, shader[i].id); 1862 1863 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed."); 1864 } 1865 } 1866 } 1867 else 1868 { 1869 glw::GLint log_size = 0; 1870 1871 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size); 1872 1873 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed."); 1874 1875 glw::GLchar* log_text = new glw::GLchar[log_size]; 1876 1877 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]); 1878 1879 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n" 1880 << log_text << "\n" 1881 << tcu::TestLog::EndMessage; 1882 1883 delete[] log_text; 1884 1885 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed."); 1886 1887 throw 0; 1888 } 1889 } 1890 catch (...) 1891 { 1892 if (m_po) 1893 { 1894 gl.deleteProgram(m_po); 1895 1896 m_po = 0; 1897 } 1898 } 1899 1900 for (glw::GLuint i = 0; i < shader_count; ++i) 1901 { 1902 if (0 != shader[i].id) 1903 { 1904 gl.deleteShader(shader[i].id); 1905 1906 shader[i].id = 0; 1907 } 1908 } 1909 1910 if (m_po) 1911 { 1912 gl.useProgram(m_po); 1913 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed."); 1914 } 1915 1916 if (0 == m_po) 1917 { 1918 throw 0; 1919 } 1920 } 1921 1922 /** @brief Function draws full screen quad. Queries are measured during the process. 1923 * Also, transform feedback data is captured. 1924 * 1925 * @note The function may throw if unexpected error has occured. 1926 */ 1927 void FunctionalTest::draw() 1928 { 1929 /* Shortcut for GL functionality. */ 1930 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1931 1932 /* Start queries. */ 1933 for (glw::GLuint i = 0; i < s_targets_count; ++i) 1934 { 1935 gl.beginQuery(s_targets[i], m_qo[i]); 1936 } 1937 1938 /* Start XFB. */ 1939 gl.beginTransformFeedback(GL_TRIANGLES); 1940 1941 /* Draw full screen quad. */ 1942 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); 1943 1944 /* Finish XFB. */ 1945 gl.endTransformFeedback(); 1946 1947 /* Finish queries. */ 1948 for (glw::GLuint i = 0; i < s_targets_count; ++i) 1949 { 1950 gl.endQuery(s_targets[i]); 1951 } 1952 1953 /* Make sure OpenGL finished drawing. */ 1954 gl.finish(); 1955 1956 /* Error checking. */ 1957 GLU_EXPECT_NO_ERROR(gl.getError(), "Drawing function have failed."); 1958 } 1959 1960 /** @brief Check that framebuffer is filled with red color. 1961 */ 1962 bool FunctionalTest::checkView() 1963 { 1964 /* Shortcut for GL functionality. */ 1965 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1966 1967 /* Fetch framebuffer data. */ 1968 glw::GLubyte pixel[4] = { 0 }; 1969 1970 gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); 1971 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed"); 1972 1973 /* Comparison with expected values. */ 1974 if ((255 != pixel[0]) || (0 != pixel[1]) || (0 != pixel[2]) || (255 != pixel[3])) 1975 { 1976 m_context.getTestContext().getLog() 1977 << tcu::TestLog::Message << "Frameuffer content (" << (unsigned int)pixel[0] << ", " 1978 << (unsigned int)pixel[1] << ", " << (unsigned int)pixel[2] << ", " << (unsigned int)pixel[3] 1979 << ") is different than expected (255, 0, 0, 255)." << tcu::TestLog::EndMessage; 1980 1981 return false; 1982 } 1983 1984 return true; 1985 } 1986 1987 /** @brief Check that transform feedback buffer 1988 * contains values representing quad. 1989 */ 1990 bool FunctionalTest::checkXFB() 1991 { 1992 /* Shortcut for GL functionality */ 1993 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1994 1995 /* Default result. */ 1996 bool is_ok = true; 1997 1998 /* Mapping buffer object to the user-space. */ 1999 glw::GLint* buffer = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 2000 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed."); 2001 2002 if ((0 != buffer[0]) || (1 != buffer[1]) || (2 != buffer[2]) || 2003 2004 (2 != buffer[3]) || (1 != buffer[4]) || (3 != buffer[5])) 2005 { 2006 is_ok = false; 2007 } 2008 2009 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 2010 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed."); 2011 2012 return is_ok; 2013 } 2014 2015 /** @brief Release all created objects. 2016 */ 2017 void FunctionalTest::clean() 2018 { 2019 /* Shortcut for GL functionality. */ 2020 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2021 2022 /* Releasing queries. */ 2023 if (DE_NULL != m_qo) 2024 { 2025 gl.deleteQueries(s_targets_count, m_qo); 2026 2027 delete[] m_qo; 2028 2029 m_qo = DE_NULL; 2030 } 2031 2032 /* Release framebuffer. */ 2033 if (m_fbo) 2034 { 2035 gl.deleteFramebuffers(1, &m_fbo); 2036 2037 m_fbo = 0; 2038 } 2039 2040 /* Release renderbuffer. */ 2041 if (m_rbo) 2042 { 2043 gl.deleteRenderbuffers(1, &m_rbo); 2044 2045 m_rbo = 0; 2046 } 2047 2048 /* Release vertex array object. */ 2049 if (m_vao) 2050 { 2051 gl.deleteVertexArrays(1, &m_vao); 2052 2053 m_vao = 0; 2054 } 2055 2056 /* Release buffer object for storing queries' results. */ 2057 if (m_bo_query) 2058 { 2059 gl.deleteBuffers(1, &m_bo_query); 2060 2061 m_bo_query = 0; 2062 } 2063 2064 /* Release transform feedback buffer. */ 2065 if (m_bo_xfb) 2066 { 2067 gl.deleteBuffers(1, &m_bo_xfb); 2068 2069 m_bo_xfb = 0; 2070 } 2071 2072 /* Release GLSL program. */ 2073 if (m_po) 2074 { 2075 gl.useProgram(0); 2076 2077 gl.deleteProgram(m_po); 2078 2079 m_po = 0; 2080 } 2081 } 2082 2083 /** Targets to be tested. */ 2084 const glw::GLenum FunctionalTest::s_targets[] = { GL_SAMPLES_PASSED, GL_TIME_ELAPSED, GL_PRIMITIVES_GENERATED, 2085 GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN }; 2086 2087 /** Expected result for each target. */ 2088 const glw::GLint FunctionalTest::s_results[] = { 1, 0, 2, 2 }; 2089 2090 /** Number of targets. */ 2091 const glw::GLuint FunctionalTest::s_targets_count = sizeof(s_targets) / sizeof(s_targets[0]); 2092 2093 /** Vertex shader source code. */ 2094 const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 450\n" 2095 "\n" 2096 "out int xfb_result;\n" 2097 "\n" 2098 "void main()\n" 2099 "{\n" 2100 " switch(gl_VertexID)\n" 2101 " {\n" 2102 " case 0:\n" 2103 " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 2104 " break;\n" 2105 " case 1:\n" 2106 " gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n" 2107 " break;\n" 2108 " case 2:\n" 2109 " gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n" 2110 " break;\n" 2111 " case 3:\n" 2112 " gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n" 2113 " break;\n" 2114 " }\n" 2115 "\n" 2116 " xfb_result = gl_VertexID;\n" 2117 "}\n"; 2118 2119 /** Fragment shader source program. */ 2120 const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 450\n" 2121 "\n" 2122 "out vec4 color;\n" 2123 "\n" 2124 "void main()\n" 2125 "{\n" 2126 " color = vec4(1.0, 0.0, 0.0, 1.0);\n" 2127 "}\n"; 2128 2129 /** Name of transform feedback varying in vertex shader. */ 2130 const glw::GLchar* FunctionalTest::s_xfb_varying_name = "xfb_result"; 2131 2132 } /* Queries namespace. */ 2133 } /* DirectStateAccess namespace. */ 2134 } /* gl4cts namespace. */ 2135