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 gl4cDirectStateAccessXFBTests.cpp 27 * \brief Conformance tests for the Direct State Access feature functionality (Transform Feedbeck 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 namespace gl4cts 50 { 51 namespace DirectStateAccess 52 { 53 namespace TransformFeedback 54 { 55 /******************************** Creation Test Implementation ********************************/ 56 57 /** @brief Creation Test constructor. 58 * 59 * @param [in] context OpenGL context. 60 */ 61 CreationTest::CreationTest(deqp::Context& context) 62 : deqp::TestCase(context, "xfb_creation", "Transform Feedback Creation Test") 63 { 64 /* Intentionally left blank. */ 65 } 66 67 /** @brief Iterate Creation Test cases. 68 * 69 * @return Iteration result. 70 */ 71 tcu::TestNode::IterateResult CreationTest::iterate() 72 { 73 /* Shortcut for GL functionality */ 74 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 75 76 /* Get context setup. */ 77 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 78 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 79 80 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 81 { 82 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 83 84 return STOP; 85 } 86 87 /* Running tests. */ 88 bool is_ok = true; 89 bool is_error = false; 90 91 /* Transform feedback objects */ 92 static const glw::GLuint xfb_count = 2; 93 94 glw::GLuint xfb_dsa[xfb_count] = {}; 95 glw::GLuint xfb_legacy[xfb_count] = {}; 96 97 try 98 { 99 /* Sanity default setup. */ 100 gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); 101 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback have failed"); 102 103 /* Check legacy way. */ 104 gl.genTransformFeedbacks(xfb_count, xfb_legacy); 105 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks have failed"); 106 107 for (glw::GLuint i = 0; i < xfb_count; ++i) 108 { 109 if (gl.isTransformFeedback(xfb_legacy[i])) 110 { 111 is_ok = false; 112 113 /* Log. */ 114 m_context.getTestContext().getLog() 115 << tcu::TestLog::Message 116 << "GenTransformFeedbacks has created defualt objects, but only shall reserve names for them." 117 << tcu::TestLog::EndMessage; 118 } 119 } 120 121 /* Check direct state access way. */ 122 gl.createTransformFeedbacks(xfb_count, xfb_dsa); 123 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed"); 124 125 for (glw::GLuint i = 0; i < xfb_count; ++i) 126 { 127 if (!gl.isTransformFeedback(xfb_dsa[i])) 128 { 129 is_ok = false; 130 131 /* Log. */ 132 m_context.getTestContext().getLog() << tcu::TestLog::Message 133 << "CreateTransformFeedbacks has not created defualt objects." 134 << tcu::TestLog::EndMessage; 135 } 136 } 137 138 /* Check binding point. */ 139 glw::GLint xfb_binding_point = -1; 140 141 gl.getIntegerv(GL_TRANSFORM_FEEDBACK_BINDING, &xfb_binding_point); 142 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv have failed"); 143 144 if (0 != xfb_binding_point) 145 { 146 if (-1 == xfb_binding_point) 147 { 148 m_context.getTestContext().getLog() << tcu::TestLog::Message 149 << "glGetIntegerv used with GL_TRANSFORM_FEEDBACK_BINDING have not " 150 "returned anything and did not generate error." 151 << tcu::TestLog::EndMessage; 152 153 throw 0; 154 } 155 else 156 { 157 m_context.getTestContext().getLog() << tcu::TestLog::Message 158 << "The usage of glCreateTransformFeedbacks have changed " 159 "GL_TRANSFORM_FEEDBACK_BINDING binding point." 160 << tcu::TestLog::EndMessage; 161 162 is_ok = false; 163 } 164 } 165 } 166 catch (...) 167 { 168 is_ok = false; 169 is_error = true; 170 } 171 172 /* Cleanup. */ 173 for (glw::GLuint i = 0; i < xfb_count; ++i) 174 { 175 if (xfb_legacy[i]) 176 { 177 gl.deleteTransformFeedbacks(1, &xfb_legacy[i]); 178 179 xfb_legacy[i] = 0; 180 } 181 182 if (xfb_dsa[i]) 183 { 184 gl.deleteTransformFeedbacks(1, &xfb_dsa[i]); 185 186 xfb_dsa[i] = 0; 187 } 188 } 189 190 /* Result's setup. */ 191 if (is_ok) 192 { 193 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 194 } 195 else 196 { 197 if (is_error) 198 { 199 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 200 } 201 else 202 { 203 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 204 } 205 } 206 207 return STOP; 208 } 209 210 /******************************** Defaults Test Implementation ********************************/ 211 212 /** @brief Defaults Test constructor. 213 * 214 * @param [in] context OpenGL context. 215 */ 216 DefaultsTest::DefaultsTest(deqp::Context& context) 217 : deqp::TestCase(context, "xfb_defaults", "Transform Feedback Defaults Test") 218 , m_gl_getTransformFeedbackiv(DE_NULL) 219 , m_gl_getTransformFeedbacki_v(DE_NULL) 220 , m_gl_getTransformFeedbacki64_v(DE_NULL) 221 , m_xfb_dsa(0) 222 , m_xfb_indexed_binding_points_count(0) 223 { 224 /* Intentionally left blank. */ 225 } 226 227 /** @brief Iterate Defaults Test cases. 228 * 229 * @return Iteration result. 230 */ 231 tcu::TestNode::IterateResult DefaultsTest::iterate() 232 { 233 /* Get context setup. */ 234 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 235 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 236 237 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 238 { 239 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 240 241 return STOP; 242 } 243 244 /* Running tests. */ 245 bool is_ok = true; 246 bool is_error = false; 247 248 try 249 { 250 prepare(); 251 252 is_ok &= testBuffersBindingPoints(); 253 is_ok &= testBuffersDimensions(); 254 is_ok &= testActive(); 255 is_ok &= testPaused(); 256 } 257 catch (...) 258 { 259 is_ok = false; 260 is_error = true; 261 } 262 263 /* Clean up. */ 264 clean(); 265 266 /* Result's setup. */ 267 if (is_ok) 268 { 269 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 270 } 271 else 272 { 273 if (is_error) 274 { 275 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 276 } 277 else 278 { 279 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 280 } 281 } 282 283 return STOP; 284 } 285 286 /** @brief Create XFB and Buffer Objects. Prepare function pointers. 287 * 288 * @note The function may throw if unexpected error has occured. 289 * 290 * @return True if test succeeded, false otherwise. 291 */ 292 void DefaultsTest::prepare() 293 { 294 /* Shortcut for GL functionality */ 295 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 296 297 /* Fetching function pointers. */ 298 m_gl_getTransformFeedbackiv = (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv; 299 m_gl_getTransformFeedbacki_v = (GetTransformFeedbacki_v_ProcAddress)gl.getTransformFeedbacki_v; 300 m_gl_getTransformFeedbacki64_v = (GetTransformFeedbacki64_v_ProcAddress)gl.getTransformFeedbacki64_v; 301 302 if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_getTransformFeedbacki_v) || 303 (DE_NULL == m_gl_getTransformFeedbacki64_v)) 304 { 305 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values." 306 << tcu::TestLog::EndMessage; 307 308 throw 0; 309 } 310 311 /* XFB object creation */ 312 gl.createTransformFeedbacks(1, &m_xfb_dsa); 313 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed"); 314 315 /* Query limits. */ 316 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &m_xfb_indexed_binding_points_count); 317 GLU_EXPECT_NO_ERROR(gl.getError(), "glIntegerv have failed"); 318 } 319 320 /** @brief Test default value of GL_TRANSFORM_FEEDBACK_BUFFER_BINDING. 321 * 322 * @note The function may throw if unexpected error has occured. 323 * 324 * @return True if test succeeded, false otherwise. 325 */ 326 bool DefaultsTest::testBuffersBindingPoints() 327 { 328 /* Shortcut for GL functionality */ 329 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 330 331 /* Check default binding points value. */ 332 for (glw::GLint i = 0; i < m_xfb_indexed_binding_points_count; ++i) 333 { 334 glw::GLint buffer_binding = -1; 335 336 m_gl_getTransformFeedbacki_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, &buffer_binding); 337 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed"); 338 339 if (-1 == buffer_binding) 340 { 341 m_context.getTestContext().getLog() 342 << tcu::TestLog::Message 343 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING has not returned " 344 "anything and error has not been generated." 345 << tcu::TestLog::EndMessage; 346 347 return false; 348 } 349 else 350 { 351 if (0 != buffer_binding) 352 { 353 m_context.getTestContext().getLog() 354 << tcu::TestLog::Message 355 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING has returned " 356 << buffer_binding << ", however 0 is expected." << tcu::TestLog::EndMessage; 357 358 return false; 359 } 360 } 361 } 362 363 return true; 364 } 365 366 /** @brief Test default values of GL_TRANSFORM_FEEDBACK_START and GL_TRANSFORM_FEEDBACK_SIZE. 367 * 368 * @note The function may throw if unexpected error has occured. 369 * 370 * @return True if test succeeded, false otherwise. 371 */ 372 bool DefaultsTest::testBuffersDimensions() 373 { 374 /* Shortcut for GL functionality */ 375 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 376 377 /* Check default buffers' start value. */ 378 for (glw::GLint i = 0; i < m_xfb_indexed_binding_points_count; ++i) 379 { 380 glw::GLint64 buffer_start = -1; 381 382 m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_START, i, &buffer_start); 383 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed"); 384 385 if (-1 == buffer_start) 386 { 387 m_context.getTestContext().getLog() 388 << tcu::TestLog::Message 389 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START has not returned " 390 "anything and error has not been generated." 391 << tcu::TestLog::EndMessage; 392 393 return false; 394 } 395 else 396 { 397 if (0 != buffer_start) 398 { 399 m_context.getTestContext().getLog() 400 << tcu::TestLog::Message 401 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START has returned " 402 << buffer_start << ", however 0 is expected." << tcu::TestLog::EndMessage; 403 404 return false; 405 } 406 } 407 } 408 409 /** @brief Check default buffers' size value. 410 * 411 * @note The function may throw if unexpected error has occured. 412 */ 413 for (glw::GLint i = 0; i < m_xfb_indexed_binding_points_count; ++i) 414 { 415 glw::GLint64 buffer_size = -1; 416 417 m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i, &buffer_size); 418 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed"); 419 420 if (-1 == buffer_size) 421 { 422 m_context.getTestContext().getLog() 423 << tcu::TestLog::Message 424 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE has not returned " 425 "anything and error has not been generated." 426 << tcu::TestLog::EndMessage; 427 428 return false; 429 } 430 else 431 { 432 if (0 != buffer_size) 433 { 434 m_context.getTestContext().getLog() 435 << tcu::TestLog::Message 436 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE has returned " 437 << buffer_size << ", however 0 is expected." << tcu::TestLog::EndMessage; 438 439 return false; 440 } 441 } 442 } 443 444 return true; 445 } 446 447 /** @brief Test default value of GL_TRANSFORM_FEEDBACK_ACTIVE. 448 * 449 * @return True if test succeeded, false otherwise. 450 */ 451 bool DefaultsTest::testActive() 452 { 453 /* Check that it is not active. */ 454 glw::GLint is_active = -1; 455 m_gl_getTransformFeedbackiv(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_ACTIVE, &is_active); 456 457 if (-1 == is_active) 458 { 459 m_context.getTestContext().getLog() << tcu::TestLog::Message 460 << "glGetTransformFeedbackiv with parameter GL_TRANSFORM_FEEDBACK_ACTIVE " 461 "has not returned anything and error has not been generated." 462 << tcu::TestLog::EndMessage; 463 464 return false; 465 } 466 else 467 { 468 if (0 != is_active) 469 { 470 m_context.getTestContext().getLog() 471 << tcu::TestLog::Message 472 << "glGetTransformFeedbackiv with parameter GL_TRANSFORM_FEEDBACK_ACTIVE has returned " << is_active 473 << ", however FALSE is expected." << tcu::TestLog::EndMessage; 474 475 return false; 476 } 477 } 478 479 return true; 480 } 481 482 /** @brief Test default value of GL_TRANSFORM_FEEDBACK_PAUSED. 483 * 484 * @return True if test succeeded, false otherwise. 485 */ 486 bool DefaultsTest::testPaused() 487 { 488 /* Check that it is not paused. */ 489 glw::GLint is_paused = -1; 490 m_gl_getTransformFeedbackiv(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_PAUSED, &is_paused); 491 492 if (-1 == is_paused) 493 { 494 m_context.getTestContext().getLog() << tcu::TestLog::Message 495 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_PAUSED " 496 "has not returned anything and error has not been generated." 497 << tcu::TestLog::EndMessage; 498 499 return false; 500 } 501 else 502 { 503 if (0 != is_paused) 504 { 505 m_context.getTestContext().getLog() 506 << tcu::TestLog::Message 507 << "glGetTransformFeedbackiv with parameter GL_TRANSFORM_FEEDBACK_PAUSED has returned " << is_paused 508 << ", however FALSE is expected." << tcu::TestLog::EndMessage; 509 510 return false; 511 } 512 } 513 514 return true; 515 } 516 517 /** @brief Release GL objects. 518 */ 519 void DefaultsTest::clean() 520 { 521 /* Shortcut for GL functionality */ 522 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 523 524 if (m_xfb_dsa) 525 { 526 gl.deleteTransformFeedbacks(1, &m_xfb_dsa); 527 528 m_xfb_dsa = 0; 529 } 530 } 531 532 /******************************** Buffers Test Implementation ********************************/ 533 534 /** @brief Buffers Test constructor. 535 * 536 * @param [in] context OpenGL context. 537 */ 538 BuffersTest::BuffersTest(deqp::Context& context) 539 : deqp::TestCase(context, "xfb_buffers", "Transform Feedback Buffers Test") 540 , m_gl_getTransformFeedbacki_v(DE_NULL) 541 , m_gl_getTransformFeedbacki64_v(DE_NULL) 542 , m_gl_TransformFeedbackBufferBase(DE_NULL) 543 , m_gl_TransformFeedbackBufferRange(DE_NULL) 544 , m_xfb_dsa(0) 545 , m_bo_a(0) 546 , m_bo_b(0) 547 { 548 /* Intentionally left blank. */ 549 } 550 551 /** @brief Iterate Buffers Test cases. 552 * 553 * @return Iteration result. 554 */ 555 tcu::TestNode::IterateResult BuffersTest::iterate() 556 { 557 /* Get context setup. */ 558 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 559 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 560 561 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 562 { 563 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 564 565 return STOP; 566 } 567 568 /* Running tests. */ 569 bool is_ok = true; 570 bool is_error = false; 571 572 try 573 { 574 /* Prepare function pointers, transform feedback and buffer objects. */ 575 prepareObjects(); 576 577 /* Setup transform feedback object binding points with buffer objects. */ 578 is_ok = prepareTestSetup(); 579 580 /* Continue only if test setup succeeded */ 581 if (is_ok) 582 { 583 is_ok &= testBindingPoint(0, m_bo_a, "glTransformFeedbackBufferBase"); 584 is_ok &= testBindingPoint(1, m_bo_b, "glTransformFeedbackBufferRange"); 585 is_ok &= testBindingPoint(2, m_bo_b, "glTransformFeedbackBufferRange"); 586 587 is_ok &= testStart(0, 0, "glTransformFeedbackBufferBase"); 588 is_ok &= testStart(1, 0, "glTransformFeedbackBufferRange"); 589 is_ok &= testStart(2, s_bo_size / 2, "glTransformFeedbackBufferRange"); 590 591 is_ok &= testSize(0, 0, "glTransformFeedbackBufferBase"); 592 is_ok &= testSize(1, s_bo_size / 2, "glTransformFeedbackBufferRange"); 593 is_ok &= testSize(2, s_bo_size / 2, "glTransformFeedbackBufferRange"); 594 } 595 } 596 catch (...) 597 { 598 is_ok = false; 599 is_error = true; 600 } 601 602 /* Clean up. */ 603 clean(); 604 605 /* Result's setup. */ 606 if (is_ok) 607 { 608 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 609 } 610 else 611 { 612 if (is_error) 613 { 614 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 615 } 616 else 617 { 618 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 619 } 620 } 621 622 return STOP; 623 } 624 625 /** @brief Create XFB amd BO objects. Setup function pointers. 626 * 627 * @note The function may throw if unexpected error has occured. 628 */ 629 void BuffersTest::prepareObjects() 630 { 631 /* Shortcut for GL functionality */ 632 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 633 634 /* Fetching function pointers. */ 635 m_gl_getTransformFeedbacki_v = (GetTransformFeedbacki_v_ProcAddress)gl.getTransformFeedbacki_v; 636 m_gl_getTransformFeedbacki64_v = (GetTransformFeedbacki64_v_ProcAddress)gl.getTransformFeedbacki64_v; 637 m_gl_TransformFeedbackBufferBase = (TransformFeedbackBufferBase_ProcAddress)gl.transformFeedbackBufferBase; 638 m_gl_TransformFeedbackBufferRange = (TransformFeedbackBufferRange_ProcAddress)gl.transformFeedbackBufferRange; 639 640 if ((DE_NULL == m_gl_getTransformFeedbacki_v) || (DE_NULL == m_gl_getTransformFeedbacki64_v) || 641 (DE_NULL == m_gl_TransformFeedbackBufferBase) || (DE_NULL == m_gl_TransformFeedbackBufferRange)) 642 { 643 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values." 644 << tcu::TestLog::EndMessage; 645 646 throw 0; 647 } 648 649 /** @brief XFB object creation */ 650 gl.createTransformFeedbacks(1, &m_xfb_dsa); 651 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed"); 652 653 /* Buffer Objects creation. */ 654 gl.genBuffers(1, &m_bo_a); 655 gl.genBuffers(1, &m_bo_b); 656 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed"); 657 658 if ((0 == m_bo_a) || (0 == m_bo_b)) 659 { 660 m_context.getTestContext().getLog() << tcu::TestLog::Message 661 << "Buffer object has not been generated and no error has been triggered." 662 << tcu::TestLog::EndMessage; 663 664 throw 0; 665 } 666 667 /* First buffer memory allocation. */ 668 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_a); 669 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed"); 670 671 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY); 672 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed"); 673 674 /* Sainty check of buffer size */ 675 glw::GLint allocated_size = -1; 676 677 gl.getBufferParameteriv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_BUFFER_SIZE, &allocated_size); 678 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv have failed"); 679 680 if (allocated_size != (glw::GLint)s_bo_size) 681 { 682 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Buffer allocation failed." 683 << tcu::TestLog::EndMessage; 684 685 throw 0; 686 } 687 688 /* Second buffer memory allocation. */ 689 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_b); 690 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed"); 691 692 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY); 693 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed"); 694 695 /* Sainty check of buffer size */ 696 allocated_size = -1; 697 698 gl.getBufferParameteriv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_BUFFER_SIZE, &allocated_size); 699 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv have failed"); 700 701 if (allocated_size != (glw::GLint)s_bo_size) 702 { 703 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Buffer allocation failed." 704 << tcu::TestLog::EndMessage; 705 706 throw 0; 707 } 708 709 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); 710 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed"); 711 } 712 713 /** @brief Setup indexed buffer binding points in the xfb object using 714 * glTransformFeedbackBufferBase and glTransformFeedbackBufferRange 715 * functions. 716 * 717 * @return True if setup succeeded, false otherwise (functions triggered errors). 718 */ 719 bool BuffersTest::prepareTestSetup() 720 { 721 /* Shortcut for GL functionality */ 722 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 723 724 /* Bind Buffer Object to first indexed binding point. */ 725 m_gl_TransformFeedbackBufferBase(m_xfb_dsa, 0, m_bo_a); 726 727 /* Check errors. */ 728 glw::GLenum error_value = gl.getError(); 729 730 if (GL_NONE != error_value) 731 { 732 m_context.getTestContext().getLog() 733 << tcu::TestLog::Message << "glTransformFeedbackBufferBase has generated unexpected error (" 734 << glu::getErrorStr(error_value) << "). Test Failed." << tcu::TestLog::EndMessage; 735 736 return false; 737 } 738 739 /* Bind Buffer Object to second and third indexed binding point. */ 740 m_gl_TransformFeedbackBufferRange(m_xfb_dsa, 1, m_bo_b, 0, s_bo_size / 2); 741 m_gl_TransformFeedbackBufferRange(m_xfb_dsa, 2, m_bo_b, s_bo_size / 2, s_bo_size / 2); 742 743 /* Check errors. */ 744 error_value = gl.getError(); 745 746 if (GL_NONE != error_value) 747 { 748 m_context.getTestContext().getLog() 749 << tcu::TestLog::Message << "glTransformFeedbackBufferRange has generated unexpected error (" 750 << glu::getErrorStr(error_value) << "). Test Failed." << tcu::TestLog::EndMessage; 751 752 return false; 753 } 754 755 return true; 756 } 757 758 /** @brief Test that xfb object's binding point #<index> has <expected_value>. 759 * 760 * @param [in] index Tested index point. 761 * @param [in] expected_value Value to be expected (buffer name). 762 * @param [in] tested_function_name Name of function which this function is going to test 763 * (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange) 764 * for logging purposes. 765 * 766 * @note The function may throw if unexpected error has occured. 767 * 768 * @return True if test succeeded, false otherwise. 769 */ 770 bool BuffersTest::testBindingPoint(glw::GLuint const index, glw::GLint const expected_value, 771 glw::GLchar const* const tested_function_name) 772 { 773 /* Shortcut for GL functionality */ 774 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 775 776 /* Check default binding points value. */ 777 glw::GLint buffer_binding = -1; 778 779 m_gl_getTransformFeedbacki_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, index, &buffer_binding); 780 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed"); 781 782 if (-1 == buffer_binding) 783 { 784 m_context.getTestContext().getLog() 785 << tcu::TestLog::Message << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING " 786 "has not returned anything and error has not been generated." 787 << tcu::TestLog::EndMessage; 788 789 return false; 790 } 791 else 792 { 793 if (expected_value != buffer_binding) 794 { 795 m_context.getTestContext().getLog() 796 << tcu::TestLog::Message 797 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING has returned " 798 << buffer_binding << ", however " << expected_value << " is expected. As a consequence function " 799 << tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage; 800 801 return false; 802 } 803 } 804 805 return true; 806 } 807 808 /** @brief Test that buffer object at xfb object's binding point #<index> has starting offset set to the <expected_value>. 809 * 810 * @param [in] index Tested index point. 811 * @param [in] expected_value Value to be expected (starting offset). 812 * @param [in] tested_function_name Name of function which this function is going to test 813 * (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange) 814 * for logging purposes. 815 * 816 * @note The function may throw if unexpected error has occured. 817 * 818 * @return True if test succeeded, false otherwise. 819 */ 820 bool BuffersTest::testStart(glw::GLuint const index, glw::GLint const expected_value, 821 glw::GLchar const* const tested_function_name) 822 { 823 /* Shortcut for GL functionality */ 824 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 825 826 /* Check default buffers' start value. */ 827 glw::GLint64 buffer_start = -1; 828 829 m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_START, index, &buffer_start); 830 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed"); 831 832 /* Checking results and errors. */ 833 if (-1 == buffer_start) 834 { 835 m_context.getTestContext().getLog() 836 << tcu::TestLog::Message << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START " 837 "has not returned anything and error has not been generated." 838 << tcu::TestLog::EndMessage; 839 840 return false; 841 } 842 else 843 { 844 if (expected_value != buffer_start) 845 { 846 m_context.getTestContext().getLog() 847 << tcu::TestLog::Message 848 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START has returned " 849 << buffer_start << ", however " << expected_value << " is expected. As a consequence function " 850 << tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage; 851 852 return false; 853 } 854 } 855 856 return true; 857 } 858 859 /** @brief Test that buffer object at xfb object's binding point #<index> has size set to the <expected_value>. 860 * 861 * @param [in] index Tested index point. 862 * @param [in] expected_value Value to be expected (buffer's size). 863 * @param [in] tested_function_name Name of function which this function is going to test 864 * (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange) 865 * for logging purposes. 866 * 867 * @note The function may throw if unexpected error has occured. 868 * 869 * @return True if test succeeded, false otherwise. 870 */ 871 bool BuffersTest::testSize(glw::GLuint const index, glw::GLint const expected_value, 872 glw::GLchar const* const tested_function_name) 873 { 874 /* Shortcut for GL functionality */ 875 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 876 877 /* Check default buffer's size value. */ 878 glw::GLint64 buffer_size = -1; 879 880 m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, index, &buffer_size); 881 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed"); 882 883 /* Checking results and errors. */ 884 if (-1 == buffer_size) 885 { 886 m_context.getTestContext().getLog() 887 << tcu::TestLog::Message << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE " 888 "has not returned anything and error has not been generated." 889 << tcu::TestLog::EndMessage; 890 891 return false; 892 } 893 else 894 { 895 if (expected_value != buffer_size) 896 { 897 m_context.getTestContext().getLog() 898 << tcu::TestLog::Message 899 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE has returned " 900 << buffer_size << ", however " << expected_value << " is expected. As a consequence function " 901 << tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage; 902 903 return false; 904 } 905 } 906 907 return true; 908 } 909 910 /** @brief Clean al GL objects 911 */ 912 void BuffersTest::clean() 913 { 914 /* Shortcut for GL functionality */ 915 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 916 917 /* Release transform feedback object. */ 918 if (m_xfb_dsa) 919 { 920 gl.deleteTransformFeedbacks(1, &m_xfb_dsa); 921 922 m_xfb_dsa = 0; 923 } 924 925 /* Release buffer objects. */ 926 if (m_bo_a) 927 { 928 gl.deleteBuffers(1, &m_bo_a); 929 930 m_bo_a = 0; 931 } 932 933 if (m_bo_b) 934 { 935 gl.deleteBuffers(1, &m_bo_b); 936 937 m_bo_b = 0; 938 } 939 } 940 941 /** @brief Buffer Object Size */ 942 const glw::GLuint BuffersTest::s_bo_size = 512; 943 944 /******************************** Errors Test Implementation ********************************/ 945 946 /** @brief Errors Test constructor. 947 * 948 * @param [in] context OpenGL context. 949 */ 950 ErrorsTest::ErrorsTest(deqp::Context& context) 951 : deqp::TestCase(context, "xfb_errors", "Transform Feedback Errors Test") 952 , m_gl_getTransformFeedbackiv(DE_NULL) 953 , m_gl_getTransformFeedbacki_v(DE_NULL) 954 , m_gl_getTransformFeedbacki64_v(DE_NULL) 955 { 956 /* Intentionally left blank. */ 957 } 958 959 /** @brief Iterate Errors Test cases. 960 * 961 * @return Iteration result. 962 */ 963 tcu::TestNode::IterateResult ErrorsTest::iterate() 964 { 965 /* Get context setup. */ 966 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 967 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 968 969 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 970 { 971 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 972 973 return STOP; 974 } 975 976 /* Running tests. */ 977 bool is_ok = true; 978 bool is_error = false; 979 980 try 981 { 982 prepareFunctionPointers(); 983 984 is_ok &= testCreateTransformFeedbacksForInvalidNumberOfObjects(); 985 cleanErrors(); 986 987 is_ok &= testQueriesForInvalidNameOfObject(); 988 cleanErrors(); 989 990 is_ok &= testGetTransformFeedbackivQueryForInvalidParameterName(); 991 cleanErrors(); 992 993 is_ok &= testGetTransformFeedbacki_vQueryForInvalidParameterName(); 994 cleanErrors(); 995 996 is_ok &= testGetTransformFeedbacki64_vQueryForInvalidParameterName(); 997 cleanErrors(); 998 999 is_ok &= testIndexedQueriesForInvalidBindingPoint(); 1000 cleanErrors(); 1001 } 1002 catch (...) 1003 { 1004 is_ok = false; 1005 is_error = true; 1006 } 1007 1008 /* Result's setup. */ 1009 if (is_ok) 1010 { 1011 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1012 } 1013 else 1014 { 1015 if (is_error) 1016 { 1017 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 1018 } 1019 else 1020 { 1021 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1022 } 1023 } 1024 1025 return STOP; 1026 } 1027 1028 /** @brief Fetch GL function pointers. 1029 * 1030 * @note The function may throw if unexpected error has occured. 1031 */ 1032 void ErrorsTest::prepareFunctionPointers() 1033 { 1034 /* Shortcut for GL functionality */ 1035 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1036 1037 /* Fetching function pointers. */ 1038 m_gl_getTransformFeedbackiv = (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv; 1039 m_gl_getTransformFeedbacki_v = (GetTransformFeedbacki_v_ProcAddress)gl.getTransformFeedbacki_v; 1040 m_gl_getTransformFeedbacki64_v = (GetTransformFeedbacki64_v_ProcAddress)gl.getTransformFeedbacki64_v; 1041 1042 if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_getTransformFeedbacki_v) || 1043 (DE_NULL == m_gl_getTransformFeedbacki64_v)) 1044 { 1045 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values." 1046 << tcu::TestLog::EndMessage; 1047 1048 throw 0; 1049 } 1050 } 1051 1052 /** @brief Sanity clean-up of GL errors. 1053 * 1054 * @note This function is to only make sure that failing test will not affect other tests. 1055 */ 1056 void ErrorsTest::cleanErrors() 1057 { 1058 /* Shortcut for GL functionality */ 1059 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1060 1061 /* Cleaning errors. */ 1062 while (GL_NO_ERROR != gl.getError()) 1063 ; 1064 } 1065 1066 /** @brief Test Creation of Transform Feedbacks using Invalid Number Of Objects 1067 * 1068 * @note Test checks that CreateTransformFeedbacks generates INVALID_VALUE error if 1069 * number of transform feedback objects to create is negative. 1070 * 1071 * @return true if test succeded, false otherwise. 1072 */ 1073 bool ErrorsTest::testCreateTransformFeedbacksForInvalidNumberOfObjects() 1074 { 1075 /* Shortcut for GL functionality */ 1076 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1077 1078 glw::GLuint xfbs = 314159; 1079 1080 gl.createTransformFeedbacks(-1 /* invalid count */, &xfbs); 1081 1082 glw::GLenum error = gl.getError(); 1083 1084 if (GL_INVALID_VALUE != error) 1085 { 1086 m_context.getTestContext().getLog() << tcu::TestLog::Message 1087 << "glCreateTransformFeedbacks called with negative number of objects had " 1088 "been expected to generate GL_INVALID_VALUE. However, " 1089 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage; 1090 1091 return false; 1092 } 1093 1094 if (314159 != xfbs) 1095 { 1096 m_context.getTestContext().getLog() << tcu::TestLog::Message 1097 << "glCreateTransformFeedbacks called with negative number of objects had " 1098 "been expected not to change the given buffer." 1099 << tcu::TestLog::EndMessage; 1100 1101 return false; 1102 } 1103 1104 return true; 1105 } 1106 1107 /** @brief Test Direct State Access queries with invalid object name 1108 * 1109 * @note Test checks that GetTransformFeedbackiv, GetTransformFeedbacki_v and 1110 * GetTransformFeedbacki64_v generate INVALID_OPERATION error if xfb is not 1111 * zero or the name of an existing transform feedback object. 1112 * 1113 * @return true if test succeded, false otherwise. 1114 */ 1115 bool ErrorsTest::testQueriesForInvalidNameOfObject() 1116 { 1117 /* Shortcut for GL functionality */ 1118 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1119 1120 /* Generating not a-TransformFeedback name. */ 1121 glw::GLuint invalid_name = 0; 1122 1123 while (GL_TRUE == gl.isTransformFeedback(++invalid_name)) 1124 ; 1125 1126 /* Dummy storage. */ 1127 glw::GLint buffer = 314159; 1128 glw::GLint64 buffer64 = 314159; 1129 1130 /* Error variable. */ 1131 glw::GLenum error = 0; 1132 1133 /* Test of GetTransformFeedbackiv. */ 1134 m_gl_getTransformFeedbackiv(invalid_name, GL_TRANSFORM_FEEDBACK_PAUSED, &buffer); 1135 1136 if (GL_INVALID_OPERATION != (error = gl.getError())) 1137 { 1138 m_context.getTestContext().getLog() << tcu::TestLog::Message 1139 << "glGetTransformFeedbackiv called with invalid object name had been " 1140 "expected to generate GL_INVALID_OPERATION. However, " 1141 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage; 1142 1143 return false; 1144 } 1145 1146 if (314159 != buffer) 1147 { 1148 m_context.getTestContext().getLog() << tcu::TestLog::Message 1149 << "glGetTransformFeedbackiv called with invalid object name had been " 1150 "expected not to change the given buffer." 1151 << tcu::TestLog::EndMessage; 1152 1153 return false; 1154 } 1155 1156 while (GL_NO_ERROR != (error = gl.getError())) 1157 { 1158 m_context.getTestContext().getLog() << tcu::TestLog::Message 1159 << "Warning! glGetTransformFeedbackiv called with invalid object name has " 1160 "generated more than one error, The next error was " 1161 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage; 1162 } 1163 1164 /* Test of GetTransformFeedbacki_v. */ 1165 m_gl_getTransformFeedbacki_v(invalid_name, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &buffer); 1166 1167 if (GL_INVALID_OPERATION != (error = gl.getError())) 1168 { 1169 m_context.getTestContext().getLog() << tcu::TestLog::Message 1170 << "glGetTransformFeedbacki_v called with invalid object name had been " 1171 "expected to generate GL_INVALID_OPERATION. However, " 1172 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage; 1173 1174 return false; 1175 } 1176 1177 if (314159 != buffer) 1178 { 1179 m_context.getTestContext().getLog() << tcu::TestLog::Message 1180 << "glGetTransformFeedbacki_v called with invalid object name had been " 1181 "expected not to change the given buffer." 1182 << tcu::TestLog::EndMessage; 1183 1184 return false; 1185 } 1186 1187 while (GL_NO_ERROR != (error = gl.getError())) 1188 { 1189 m_context.getTestContext().getLog() << tcu::TestLog::Message 1190 << "Warning! glGetTransformFeedbacki_v called with invalid object name has " 1191 "unexpectedly generated more than one error, The next error was " 1192 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage; 1193 } 1194 1195 /* Test of GetTransformFeedbacki64_v. */ 1196 m_gl_getTransformFeedbacki64_v(invalid_name, GL_TRANSFORM_FEEDBACK_BUFFER_START, 0, &buffer64); 1197 1198 if (GL_INVALID_OPERATION != (error = gl.getError())) 1199 { 1200 m_context.getTestContext().getLog() << tcu::TestLog::Message 1201 << "glGetTransformFeedbacki64_v called with invalid object name had been " 1202 "expected to generate GL_INVALID_OPERATION. However, " 1203 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage; 1204 1205 return false; 1206 } 1207 1208 if (314159 != buffer64) 1209 { 1210 m_context.getTestContext().getLog() << tcu::TestLog::Message 1211 << "glGetTransformFeedbacki64_v called with invalid object name had been " 1212 "expected not to change the given buffer." 1213 << tcu::TestLog::EndMessage; 1214 1215 return false; 1216 } 1217 1218 while (GL_NO_ERROR != (error = gl.getError())) 1219 { 1220 m_context.getTestContext().getLog() << tcu::TestLog::Message 1221 << "Warning! glGetTransformFeedbacki64_v called with invalid object name " 1222 "has unexpectedly generated more than one error, The next error was " 1223 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage; 1224 } 1225 1226 return true; 1227 } 1228 1229 /** @brief Test Direct State Access queries with invalid parameter name 1230 * 1231 * @note Test checks that GetTransformFeedbackiv generates INVALID_ENUM error if pname 1232 * is not TRANSFORM_FEEDBACK_PAUSED or TRANSFORM_FEEDBACK_ACTIVE. 1233 * 1234 * @note The function may throw if unexpected error has occured. 1235 * 1236 * @return true if test succeded, false otherwise. 1237 */ 1238 bool ErrorsTest::testGetTransformFeedbackivQueryForInvalidParameterName() 1239 { 1240 /* Shortcut for GL functionality */ 1241 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1242 1243 /* Creating XFB object. */ 1244 glw::GLuint xfb = 0; 1245 1246 gl.createTransformFeedbacks(1, &xfb); 1247 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed"); 1248 1249 /* Generating invalid parameter name. */ 1250 glw::GLuint invalid_parameter_name = 0; 1251 1252 /* Dummy storage. */ 1253 glw::GLint buffer = 314159; 1254 1255 /* Error variable. */ 1256 glw::GLenum error = 0; 1257 1258 /* Default result. */ 1259 bool is_ok = true; 1260 1261 /* Test of GetTransformFeedbackiv. */ 1262 m_gl_getTransformFeedbackiv(xfb, invalid_parameter_name, &buffer); 1263 1264 if (GL_INVALID_ENUM != (error = gl.getError())) 1265 { 1266 m_context.getTestContext().getLog() << tcu::TestLog::Message 1267 << "glGetTransformFeedbackiv called with invalid parameter name had been " 1268 "expected to generate GL_INVALID_ENUM. However, " 1269 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage; 1270 1271 is_ok = false; 1272 } 1273 1274 if (314159 != buffer) 1275 { 1276 m_context.getTestContext().getLog() << tcu::TestLog::Message 1277 << "glGetTransformFeedbackiv called with invalid parameter name had been " 1278 "expected not to change the given buffer." 1279 << tcu::TestLog::EndMessage; 1280 1281 is_ok = false; 1282 } 1283 1284 while (GL_NO_ERROR != (error = gl.getError())) 1285 { 1286 m_context.getTestContext().getLog() << tcu::TestLog::Message 1287 << "Warning! glGetTransformFeedbackiv called with invalid parameter name " 1288 "has generated more than one error, The next error was " 1289 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage; 1290 } 1291 1292 /* Clean-up. */ 1293 gl.deleteTransformFeedbacks(1, &xfb); 1294 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed"); 1295 1296 return is_ok; 1297 } 1298 1299 /** @brief Test Direct State Access indexed integer query with invalid parameter name 1300 * 1301 * @note Test checks that GetTransformFeedbacki_v generates INVALID_ENUM error if pname 1302 * is not TRANSFORM_FEEDBACK_BUFFER_BINDING. 1303 * 1304 * @note The function may throw if unexpected error has occured. 1305 * 1306 * @return true if test succeded, false otherwise. 1307 */ 1308 bool ErrorsTest::testGetTransformFeedbacki_vQueryForInvalidParameterName() 1309 { 1310 /* Shortcut for GL functionality */ 1311 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1312 1313 /* Creating XFB object. */ 1314 glw::GLuint xfb = 0; 1315 1316 gl.createTransformFeedbacks(1, &xfb); 1317 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed"); 1318 1319 /* Generating invalid parameter name. */ 1320 glw::GLuint invalid_parameter_name = 0; 1321 1322 /* Dummy storage. */ 1323 glw::GLint buffer = 314159; 1324 1325 /* Error variable. */ 1326 glw::GLenum error = 0; 1327 1328 /* Default result. */ 1329 bool is_ok = true; 1330 1331 /* Test of GetTransformFeedbackiv. */ 1332 m_gl_getTransformFeedbacki_v(xfb, invalid_parameter_name, 0, &buffer); 1333 1334 if (GL_INVALID_ENUM != (error = gl.getError())) 1335 { 1336 m_context.getTestContext().getLog() << tcu::TestLog::Message 1337 << "glGetTransformFeedbacki_v called with invalid parameter name had been " 1338 "expected to generate GL_INVALID_ENUM. However, " 1339 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage; 1340 1341 is_ok = false; 1342 } 1343 1344 if (314159 != buffer) 1345 { 1346 m_context.getTestContext().getLog() << tcu::TestLog::Message 1347 << "glGetTransformFeedbacki_v called with invalid parameter name had been " 1348 "expected not to change the given buffer." 1349 << tcu::TestLog::EndMessage; 1350 1351 is_ok = false; 1352 } 1353 1354 while (GL_NO_ERROR != (error = gl.getError())) 1355 { 1356 m_context.getTestContext().getLog() << tcu::TestLog::Message 1357 << "Warning! glGetTransformFeedbacki_v called with invalid parameter name " 1358 "has generated more than one error, The next error was " 1359 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage; 1360 } 1361 1362 /* Clean-up. */ 1363 gl.deleteTransformFeedbacks(1, &xfb); 1364 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed"); 1365 1366 return is_ok; 1367 } 1368 1369 /** @brief Test Direct State Access indexed 64 bit integer query with invalid parameter name 1370 * 1371 * @note Test checks that GetTransformFeedbacki64_v generates INVALID_ENUM error if 1372 * pname is not TRANSFORM_FEEDBACK_BUFFER_START or 1373 * TRANSFORM_FEEDBACK_BUFFER_SIZE. 1374 * 1375 * @note The function may throw if unexpected error has occured. 1376 * 1377 * @return true if test succeded, false otherwise. 1378 */ 1379 bool ErrorsTest::testGetTransformFeedbacki64_vQueryForInvalidParameterName() 1380 { 1381 /* Shortcut for GL functionality */ 1382 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1383 1384 /* Creating XFB object. */ 1385 glw::GLuint xfb = 0; 1386 1387 gl.createTransformFeedbacks(1, &xfb); 1388 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed"); 1389 1390 /* Generating invalid parameter name. */ 1391 glw::GLuint invalid_parameter_name = 0; 1392 1393 /* Dummy storage. */ 1394 glw::GLint64 buffer = 314159; 1395 1396 /* Error variable. */ 1397 glw::GLenum error = 0; 1398 1399 /* Default result. */ 1400 bool is_ok = true; 1401 1402 /* Test of GetTransformFeedbackiv. */ 1403 m_gl_getTransformFeedbacki64_v(xfb, invalid_parameter_name, 0, &buffer); 1404 1405 if (GL_INVALID_ENUM != (error = gl.getError())) 1406 { 1407 m_context.getTestContext().getLog() << tcu::TestLog::Message 1408 << "glGetTransformFeedbacki64_v called with invalid parameter name had " 1409 "been expected to generate GL_INVALID_ENUM. However, " 1410 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage; 1411 1412 is_ok = false; 1413 } 1414 1415 if (314159 != buffer) 1416 { 1417 m_context.getTestContext().getLog() << tcu::TestLog::Message 1418 << "glGetTransformFeedbacki64_v called with invalid parameter name had " 1419 "been expected not to change the given buffer." 1420 << tcu::TestLog::EndMessage; 1421 1422 is_ok = false; 1423 } 1424 1425 while (GL_NO_ERROR != (error = gl.getError())) 1426 { 1427 m_context.getTestContext().getLog() << tcu::TestLog::Message 1428 << "Warning! glGetTransformFeedbacki64_v called with invalid parameter " 1429 "name has generated more than one error, The next error was " 1430 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage; 1431 } 1432 1433 /* Clean-up. */ 1434 gl.deleteTransformFeedbacks(1, &xfb); 1435 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed"); 1436 1437 return is_ok; 1438 } 1439 1440 /** @brief Test Direct State Access indexed queries with invalid index 1441 * 1442 * @note Test checks that GetTransformFeedbacki_v and GetTransformFeedbacki64_v 1443 * generate INVALID_VALUE error by GetTransformFeedbacki_v and 1444 * GetTransformFeedbacki64_v if index is greater than or equal to the 1445 * number of binding points for transform feedback (the value of 1446 * MAX_TRANSFORM_FEEDBACK_BUFFERS). 1447 * 1448 * @note The function may throw if unexpected error has occured. 1449 * 1450 * @return true if test succeded, false otherwise. 1451 */ 1452 bool ErrorsTest::testIndexedQueriesForInvalidBindingPoint() 1453 { 1454 /* Shortcut for GL functionality */ 1455 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1456 1457 /* Generating invalid index. */ 1458 glw::GLint max_transform_feedback_buffers = 1459 4; /* Default limit is 4 - OpenGL 4.5 Core Specification, Table 23.72: Implementation Dependent Transform Feedback Limits. */ 1460 1461 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers); 1462 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv have failed"); 1463 1464 /* Creating XFB object. */ 1465 glw::GLuint xfb = 0; 1466 1467 gl.createTransformFeedbacks(1, &xfb); 1468 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed"); 1469 1470 /* Dummy storage. */ 1471 glw::GLint buffer = 314159; 1472 glw::GLint64 buffer64 = 314159; 1473 1474 /* Error variable. */ 1475 glw::GLenum error = 0; 1476 1477 /* Default result. */ 1478 bool is_ok = true; 1479 1480 /* Test of GetTransformFeedbacki_v. */ 1481 m_gl_getTransformFeedbacki_v(xfb, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, max_transform_feedback_buffers, &buffer); 1482 1483 if (GL_INVALID_VALUE != (error = gl.getError())) 1484 { 1485 m_context.getTestContext().getLog() << tcu::TestLog::Message 1486 << "glGetTransformFeedbacki_v called with invalid index had been expected " 1487 "to generate GL_INVALID_VALUE. However, " 1488 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage; 1489 1490 is_ok = false; 1491 } 1492 1493 if (314159 != buffer) 1494 { 1495 m_context.getTestContext().getLog() 1496 << tcu::TestLog::Message 1497 << "glGetTransformFeedbacki_v called with invalid index had been expected not to change the given buffer." 1498 << tcu::TestLog::EndMessage; 1499 1500 is_ok = false; 1501 } 1502 1503 while (GL_NO_ERROR != (error = gl.getError())) 1504 { 1505 m_context.getTestContext().getLog() << tcu::TestLog::Message 1506 << "Warning! glGetTransformFeedbacki_v called with invalid index has " 1507 "unexpectedly generated more than one error, The next error was " 1508 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage; 1509 } 1510 1511 /* Test of GetTransformFeedbacki64_v. */ 1512 m_gl_getTransformFeedbacki64_v(xfb, GL_TRANSFORM_FEEDBACK_BUFFER_START, max_transform_feedback_buffers, &buffer64); 1513 1514 if (GL_INVALID_VALUE != (error = gl.getError())) 1515 { 1516 m_context.getTestContext().getLog() << tcu::TestLog::Message 1517 << "glGetTransformFeedbacki64_v called with invalid index had been " 1518 "expected to generate GL_INVALID_VALUE. However, " 1519 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage; 1520 1521 is_ok = false; 1522 } 1523 1524 if (314159 != buffer64) 1525 { 1526 m_context.getTestContext().getLog() 1527 << tcu::TestLog::Message 1528 << "glGetTransformFeedbacki64_v called with invalid index had been expected not to change the given buffer." 1529 << tcu::TestLog::EndMessage; 1530 1531 is_ok = false; 1532 } 1533 1534 while (GL_NO_ERROR != (error = gl.getError())) 1535 { 1536 m_context.getTestContext().getLog() << tcu::TestLog::Message 1537 << "Warning! glGetTransformFeedbacki64_v called with invalid index has " 1538 "unexpectedly generated more than one error, The next error was " 1539 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage; 1540 } 1541 1542 /* Clean-up. */ 1543 gl.deleteTransformFeedbacks(1, &xfb); 1544 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed"); 1545 1546 return is_ok; 1547 } 1548 1549 /******************************** Functional Test Implementation ********************************/ 1550 1551 /** @brief Functional Test constructor. 1552 * 1553 * @param [in] context OpenGL context. 1554 */ 1555 FunctionalTest::FunctionalTest(deqp::Context& context) 1556 : deqp::TestCase(context, "xfb_functional", "Transform Feedback Functional Test") 1557 , m_gl_getTransformFeedbackiv(DE_NULL) 1558 , m_gl_TransformFeedbackBufferBase(DE_NULL) 1559 , m_xfb_dsa(0) 1560 , m_bo(0) 1561 , m_po(0) 1562 , m_vao(0) 1563 { 1564 /* Intentionally left blank. */ 1565 } 1566 1567 /** @brief Iterate Functional Test cases. 1568 * 1569 * @return Iteration result. 1570 */ 1571 tcu::TestNode::IterateResult FunctionalTest::iterate() 1572 { 1573 /* Get context setup. */ 1574 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 1575 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 1576 1577 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 1578 { 1579 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 1580 1581 return STOP; 1582 } 1583 1584 /* Running tests. */ 1585 bool is_ok = true; 1586 bool is_error = false; 1587 1588 try 1589 { 1590 prepareFunctionPointers(); 1591 prepareTransformFeedback(); 1592 prepareBuffer(); 1593 prepareProgram(); 1594 prepareVertexArrayObject(); 1595 1596 is_ok &= draw(); 1597 is_ok &= verifyBufferContent(); 1598 } 1599 catch (...) 1600 { 1601 is_ok = false; 1602 is_error = true; 1603 } 1604 1605 /* Releasing GL objects. */ 1606 clean(); 1607 1608 /* Result's setup. */ 1609 if (is_ok) 1610 { 1611 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1612 } 1613 else 1614 { 1615 if (is_error) 1616 { 1617 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 1618 } 1619 else 1620 { 1621 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1622 } 1623 } 1624 1625 return STOP; 1626 } 1627 1628 /** @brief Get access pointers to GL functions. 1629 * 1630 * @note The function may throw if unexpected error has occured. 1631 */ 1632 void FunctionalTest::prepareFunctionPointers() 1633 { 1634 /* Shortcut for GL functionality */ 1635 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1636 1637 /* Fetching function pointers. */ 1638 m_gl_getTransformFeedbackiv = (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv; 1639 m_gl_TransformFeedbackBufferBase = (TransformFeedbackBufferBase_ProcAddress)gl.transformFeedbackBufferBase; 1640 1641 if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_TransformFeedbackBufferBase)) 1642 { 1643 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values." 1644 << tcu::TestLog::EndMessage; 1645 1646 throw 0; 1647 } 1648 } 1649 1650 /** @brief Create transform feedback object using direct access function. 1651 * 1652 * @note The function may throw if unexpected error has occured. 1653 */ 1654 void FunctionalTest::prepareTransformFeedback() 1655 { 1656 /* Shortcut for GL functionality */ 1657 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1658 1659 /* XFB object creation. */ 1660 gl.createTransformFeedbacks(1, &m_xfb_dsa); 1661 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed"); 1662 } 1663 1664 /** @brief Create buffer object and bind it to transform feedback object using direct access function. 1665 * 1666 * @note The function may throw if unexpected error has occured. 1667 */ 1668 void FunctionalTest::prepareBuffer() 1669 { 1670 /* Shortcut for GL functionality */ 1671 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1672 1673 /* Buffer creation and memory allocation. */ 1674 gl.genBuffers(1, &m_bo); 1675 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed"); 1676 1677 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo); 1678 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed"); 1679 1680 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, DE_NULL, GL_DYNAMIC_COPY); 1681 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed"); 1682 1683 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); 1684 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed"); 1685 1686 /* Bind buffer to xfb object (using direct state access function). */ 1687 m_gl_TransformFeedbackBufferBase(m_xfb_dsa, 0, m_bo); 1688 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackBufferBase have failed"); 1689 } 1690 1691 /** @brief Build test's GLSL program. 1692 * 1693 * @note The function may throw if unexpected error has occured. 1694 */ 1695 void FunctionalTest::prepareProgram() 1696 { 1697 /* Shortcut for GL functionality */ 1698 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1699 1700 struct Shader 1701 { 1702 glw::GLchar const* const source; 1703 glw::GLenum const type; 1704 glw::GLuint id; 1705 } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } }; 1706 1707 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]); 1708 1709 try 1710 { 1711 /* Create program. */ 1712 m_po = gl.createProgram(); 1713 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed."); 1714 1715 /* Shader compilation. */ 1716 1717 for (glw::GLuint i = 0; i < shader_count; ++i) 1718 { 1719 if (DE_NULL != shader[i].source) 1720 { 1721 shader[i].id = gl.createShader(shader[i].type); 1722 1723 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed."); 1724 1725 gl.attachShader(m_po, shader[i].id); 1726 1727 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed."); 1728 1729 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL); 1730 1731 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed."); 1732 1733 gl.compileShader(shader[i].id); 1734 1735 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed."); 1736 1737 glw::GLint status = GL_FALSE; 1738 1739 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status); 1740 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 1741 1742 if (GL_FALSE == status) 1743 { 1744 glw::GLint log_size = 0; 1745 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size); 1746 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 1747 1748 glw::GLchar* log_text = new glw::GLchar[log_size]; 1749 1750 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]); 1751 1752 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n" 1753 << "Shader type: " << glu::getShaderTypeStr(shader[i].type) 1754 << "\n" 1755 << "Shader compilation error log:\n" 1756 << log_text << "\n" 1757 << "Shader source code:\n" 1758 << shader[i].source << "\n" 1759 << tcu::TestLog::EndMessage; 1760 1761 delete[] log_text; 1762 1763 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed."); 1764 1765 throw 0; 1766 } 1767 } 1768 } 1769 1770 /* Transform Feedback setup. */ 1771 gl.transformFeedbackVaryings(m_po, 1, &s_xfb_varying, GL_INTERLEAVED_ATTRIBS); 1772 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 1773 1774 /* Link. */ 1775 gl.linkProgram(m_po); 1776 1777 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 1778 1779 glw::GLint status = GL_FALSE; 1780 1781 gl.getProgramiv(m_po, GL_LINK_STATUS, &status); 1782 1783 if (GL_TRUE == status) 1784 { 1785 for (glw::GLuint i = 0; i < shader_count; ++i) 1786 { 1787 if (shader[i].id) 1788 { 1789 gl.detachShader(m_po, shader[i].id); 1790 1791 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed."); 1792 } 1793 } 1794 } 1795 else 1796 { 1797 glw::GLint log_size = 0; 1798 1799 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size); 1800 1801 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed."); 1802 1803 glw::GLchar* log_text = new glw::GLchar[log_size]; 1804 1805 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]); 1806 1807 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n" 1808 << log_text << "\n" 1809 << tcu::TestLog::EndMessage; 1810 1811 delete[] log_text; 1812 1813 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed."); 1814 1815 throw 0; 1816 } 1817 } 1818 catch (...) 1819 { 1820 if (m_po) 1821 { 1822 gl.deleteProgram(m_po); 1823 1824 m_po = 0; 1825 } 1826 } 1827 1828 for (glw::GLuint i = 0; i < shader_count; ++i) 1829 { 1830 if (0 != shader[i].id) 1831 { 1832 gl.deleteShader(shader[i].id); 1833 1834 shader[i].id = 0; 1835 } 1836 } 1837 1838 if (m_po) 1839 { 1840 gl.useProgram(m_po); 1841 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed."); 1842 } 1843 1844 if (0 == m_po) 1845 { 1846 throw 0; 1847 } 1848 } 1849 1850 /** @brief Create and bind empty vertex array object. 1851 * 1852 * @note The function may throw if unexpected error has occured. 1853 */ 1854 void FunctionalTest::prepareVertexArrayObject() 1855 { 1856 /* Shortcut for GL functionality */ 1857 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1858 1859 /* Creating and binding empty vertex array object. */ 1860 gl.genVertexArrays(1, &m_vao); 1861 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed."); 1862 1863 gl.bindVertexArray(m_vao); 1864 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 1865 } 1866 1867 /** @brief Draw with XFB. 1868 * 1869 * @note Function follows steps: 1870 * Begin transform feedback environment. 1871 * 1872 * Using the program with discarded rasterizer, draw array of 4 indices 1873 * using POINTS. 1874 * 1875 * Pause transform feedback environment. 1876 * 1877 * Query parameter TRANSFORM_FEEDBACK_PAUSED using GetTransformFeedbackiv. 1878 * Expect value equal to TRUE. 1879 * 1880 * Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv. 1881 * Expect value equal to TRUE. 1882 * 1883 * Resume transform feedback environment. 1884 * 1885 * Query parameter TRANSFORM_FEEDBACK_PAUSED using GetTransformFeedbackiv. 1886 * Expect value equal to FALSE. 1887 * 1888 * Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv. 1889 * Expect value equal to TRUE. 1890 * 1891 * End Transform feedback environment. 1892 * 1893 * Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv. 1894 * Expect value equal to FALSE. 1895 * 1896 * @note The function may throw if unexpected error has occured. 1897 * 1898 * @return True if included tests succeded, false otherwise. 1899 */ 1900 bool FunctionalTest::draw() 1901 { 1902 /* Shortcut for GL functionality */ 1903 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1904 1905 /* Default result. */ 1906 bool is_ok = true; 1907 1908 /* Start transform feedback environment. */ 1909 gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_dsa); 1910 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed."); 1911 1912 gl.beginTransformFeedback(GL_POINTS); 1913 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed."); 1914 1915 /* Use only xfb. No rendering. */ 1916 gl.enable(GL_RASTERIZER_DISCARD); 1917 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed."); 1918 1919 /* Draw. */ 1920 gl.drawArrays(GL_POINTS, 0, 4); 1921 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed."); 1922 1923 /* Pause Transform Feedback and tests direct state queries related to paused state. */ 1924 gl.pauseTransformFeedback(); 1925 GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed."); 1926 1927 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_PAUSED, GL_TRUE); 1928 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_TRUE); 1929 1930 /* Activate Transform Feedback and tests direct state queries related to paused state. */ 1931 gl.resumeTransformFeedback(); 1932 GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed."); 1933 1934 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_PAUSED, GL_FALSE); 1935 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_TRUE); 1936 1937 /* Finish transform feedback. */ 1938 gl.endTransformFeedback(); 1939 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed."); 1940 1941 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_FALSE); 1942 1943 return is_ok; 1944 } 1945 1946 /** @brief Check that selected Transform Feedback state has an expected value. 1947 * 1948 * @param [in] parameter_name Name of the parameter to be queried. 1949 * It must be GL_TRANSFORM_FEEDBACK_PAUSED or 1950 * GL_TRANSFORM_FEEDBACK_ACTIVE 1951 * @param [in] expected_value The expected value of the query. 1952 * 1953 * @note The function may throw if unexpected error has occured. 1954 * 1955 * @return True if the queried value is equal to expected value, false otherwise. 1956 */ 1957 bool FunctionalTest::testTransformFeedbackStatus(glw::GLenum parameter_name, glw::GLint expected_value) 1958 { 1959 /* Shortcut for GL functionality */ 1960 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1961 1962 /* Dummy storage. */ 1963 glw::GLint value = 314159; 1964 1965 /* Test of GetTransformFeedbackiv. */ 1966 m_gl_getTransformFeedbackiv(m_xfb_dsa, parameter_name, &value); 1967 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbackiv call failed."); 1968 1969 if (expected_value != value) 1970 { 1971 m_context.getTestContext().getLog() 1972 << tcu::TestLog::Message << "It was expected that glGetTransformFeedbackiv query of parameter " 1973 << ((parameter_name == GL_TRANSFORM_FEEDBACK_PAUSED) ? "GL_TRANSFORM_FEEDBACK_PAUSED" : 1974 "GL_TRANSFORM_FEEDBACK_ACTIVE") 1975 << " shall return " << ((expected_value == GL_TRUE) ? "GL_TRUE" : "GL_FALSE") << "however, " 1976 << ((value == GL_TRUE) ? "GL_TRUE" : "GL_FALSE") << " was returned." << tcu::TestLog::EndMessage; 1977 1978 return false; 1979 } 1980 1981 return true; 1982 } 1983 1984 /** @brief Check that transform feedback buffer contains 1985 * consecutive integer numbers from 0 to 3 (included). 1986 * 1987 * @note The function may throw if unexpected error has occured. 1988 * 1989 * @return True if buffer conatins consecutive integer 1990 * numbers from 0 to 3 (included), false otherwise. 1991 */ 1992 bool FunctionalTest::verifyBufferContent() 1993 { 1994 /* Shortcut for GL functionality */ 1995 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1996 1997 /* Default result. */ 1998 bool is_ok = true; 1999 2000 /* Mapping buffer object to the user-space. */ 2001 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo); 2002 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 2003 2004 glw::GLint* buffer = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 2005 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed."); 2006 2007 for (glw::GLint i = 0; i < 4 /* Number of emitted vertices. */; ++i) 2008 { 2009 if (buffer[i] != i) 2010 { 2011 is_ok = false; 2012 2013 break; 2014 } 2015 } 2016 2017 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 2018 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed."); 2019 2020 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); 2021 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 2022 2023 return is_ok; 2024 } 2025 2026 /** Release GL objects, return to the default state 2027 */ 2028 void FunctionalTest::clean() 2029 { 2030 /* Shortcut for GL functionality */ 2031 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2032 2033 /* Release transform feedback object. */ 2034 if (m_xfb_dsa) 2035 { 2036 gl.deleteTransformFeedbacks(1, &m_xfb_dsa); 2037 2038 m_xfb_dsa = 0; 2039 } 2040 2041 /* Release buffer object. */ 2042 if (m_bo) 2043 { 2044 gl.deleteBuffers(1, &m_bo); 2045 2046 m_bo = 0; 2047 } 2048 2049 /* Release GLSL program. */ 2050 if (m_po) 2051 { 2052 gl.useProgram(0); 2053 2054 gl.deleteProgram(m_po); 2055 2056 m_po = 0; 2057 } 2058 2059 /* Release vertex array object. */ 2060 if (m_vao) 2061 { 2062 gl.bindVertexArray(0); 2063 2064 gl.deleteVertexArrays(1, &m_vao); 2065 2066 m_vao = 0; 2067 } 2068 2069 /* Returning to default rasterizer state. */ 2070 gl.disable(GL_RASTERIZER_DISCARD); 2071 } 2072 2073 const glw::GLuint FunctionalTest::s_bo_size = 4 * sizeof(glw::GLint); 2074 2075 const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 130\n" 2076 "\n" 2077 "out int result;\n" 2078 "\n" 2079 "void main()\n" 2080 "{\n" 2081 "\n" 2082 " result = gl_VertexID;\n" 2083 " gl_Position = vec4(1.0);\n" 2084 "}\n"; 2085 2086 const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 130\n" 2087 "\n" 2088 "out vec4 color;\n" 2089 "\n" 2090 "void main()\n" 2091 "{\n" 2092 " color = vec4(0.0, 0.0, 0.0, 1.0);\n" 2093 "}\n"; 2094 2095 const glw::GLchar* const FunctionalTest::s_xfb_varying = "result"; 2096 2097 } /* TransformFeedback namespace */ 2098 } /* DirectStateAccess namespace */ 2099 } /* gl4cts namespace */ 2100