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 gl4cDirectStateAccessVertexArraysTests.cpp 27 * \brief Conformance tests for the Direct State Access feature functionality (Vertex Array Objects 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 #include <algorithm> 50 #include <climits> 51 #include <cmath> 52 #include <set> 53 #include <sstream> 54 #include <stack> 55 56 namespace gl4cts 57 { 58 namespace DirectStateAccess 59 { 60 namespace VertexArrays 61 { 62 /******************************** Creation Test Implementation ********************************/ 63 64 /** @brief Creation Test constructor. 65 * 66 * @param [in] context OpenGL context. 67 */ 68 CreationTest::CreationTest(deqp::Context& context) 69 : deqp::TestCase(context, "vertex_arrays_creation", "Vertex Array Objects Creation Test") 70 { 71 /* Intentionally left blank. */ 72 } 73 74 /** @brief Iterate Creation Test cases. 75 * 76 * @return Iteration result. 77 */ 78 tcu::TestNode::IterateResult CreationTest::iterate() 79 { 80 /* Shortcut for GL functionality. */ 81 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 82 83 /* Get context setup. */ 84 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 85 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 86 87 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 88 { 89 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 90 91 return STOP; 92 } 93 94 /* Running tests. */ 95 bool is_ok = true; 96 bool is_error = false; 97 98 /* VertexArrays' objects */ 99 static const glw::GLuint vertex_arrays_count = 2; 100 101 glw::GLuint vertex_arrays_legacy[vertex_arrays_count] = {}; 102 glw::GLuint vertex_arrays_dsa[vertex_arrays_count] = {}; 103 104 try 105 { 106 /* Check legacy state creation. */ 107 gl.genVertexArrays(vertex_arrays_count, vertex_arrays_legacy); 108 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays have failed"); 109 110 for (glw::GLuint i = 0; i < vertex_arrays_count; ++i) 111 { 112 if (gl.isVertexArray(vertex_arrays_legacy[i])) 113 { 114 is_ok = false; 115 116 /* Log. */ 117 m_context.getTestContext().getLog() 118 << tcu::TestLog::Message 119 << "GenVertexArrays has created default objects, but it should create only a names." 120 << tcu::TestLog::EndMessage; 121 } 122 } 123 124 /* Check direct state creation. */ 125 gl.createVertexArrays(vertex_arrays_count, vertex_arrays_dsa); 126 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays have failed"); 127 128 for (glw::GLuint i = 0; i < vertex_arrays_count; ++i) 129 { 130 if (!gl.isVertexArray(vertex_arrays_dsa[i])) 131 { 132 is_ok = false; 133 134 /* Log. */ 135 m_context.getTestContext().getLog() << tcu::TestLog::Message 136 << "CreateVertexArrays has not created default objects." 137 << tcu::TestLog::EndMessage; 138 } 139 } 140 } 141 catch (...) 142 { 143 is_ok = false; 144 is_error = true; 145 } 146 147 /* Cleanup. */ 148 for (glw::GLuint i = 0; i < vertex_arrays_count; ++i) 149 { 150 if (vertex_arrays_legacy[i]) 151 { 152 gl.deleteVertexArrays(1, &vertex_arrays_legacy[i]); 153 154 vertex_arrays_legacy[i] = 0; 155 } 156 157 if (vertex_arrays_dsa[i]) 158 { 159 gl.deleteVertexArrays(1, &vertex_arrays_dsa[i]); 160 161 vertex_arrays_dsa[i] = 0; 162 } 163 } 164 165 /* Errors clean up. */ 166 while (gl.getError()) 167 ; 168 169 /* Result's setup. */ 170 if (is_ok) 171 { 172 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 173 } 174 else 175 { 176 if (is_error) 177 { 178 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 179 } 180 else 181 { 182 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 183 } 184 } 185 186 return STOP; 187 } 188 189 /******************************** Vertex Array Object Enable Disable Attributes Test Implementation ********************************/ 190 191 /** @brief Vertex Array Object Enable Disable Attributes Test constructor. 192 * 193 * @param [in] context OpenGL context. 194 */ 195 EnableDisableAttributesTest::EnableDisableAttributesTest(deqp::Context& context) 196 : deqp::TestCase(context, "vertex_arrays_enable_disable_attributes", 197 "Vertex Array Objects Enable Disable Attributes Test") 198 , m_po_even(0) 199 , m_po_odd(0) 200 , m_vao(0) 201 , m_bo(0) 202 , m_bo_xfb(0) 203 , m_max_attributes(16) /* Required Minimum: OpenGL 4.5 Table 23.57: Implementation Dependent Vertex Shader Limits */ 204 { 205 /* Intentionally left blank. */ 206 } 207 208 /** @brief Iterate Vertex Array Object Enable Disable Attributes Test cases. 209 * 210 * @return Iteration result. 211 */ 212 tcu::TestNode::IterateResult EnableDisableAttributesTest::iterate() 213 { 214 /* Shortcut for GL functionality. */ 215 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 216 217 /* Get context setup. */ 218 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 219 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 220 221 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 222 { 223 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 224 225 return STOP; 226 } 227 228 /* Running tests. */ 229 bool is_ok = true; 230 bool is_error = false; 231 232 try 233 { 234 gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &m_max_attributes); 235 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, ...) have failed"); 236 237 m_po_even = PrepareProgram(false); 238 m_po_odd = PrepareProgram(true); 239 240 PrepareVAO(); 241 PrepareXFB(); 242 243 is_ok &= TurnOnAttributes(true, false); 244 is_ok &= DrawAndCheck(false); 245 246 is_ok &= TurnOnAttributes(false, true); 247 is_ok &= DrawAndCheck(true); 248 } 249 catch (...) 250 { 251 is_ok = false; 252 is_error = true; 253 } 254 255 /* Cleanup. */ 256 Clean(); 257 258 /* Errors clean up. */ 259 while (gl.getError()) 260 ; 261 262 /* Result's setup. */ 263 if (is_ok) 264 { 265 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 266 } 267 else 268 { 269 if (is_error) 270 { 271 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 272 } 273 else 274 { 275 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 276 } 277 } 278 279 return STOP; 280 } 281 282 glw::GLuint EnableDisableAttributesTest::PrepareProgram(const bool bind_even_or_odd) 283 { 284 /* Preprocess vertex shader sources. */ 285 std::string declarations = ""; 286 std::string copies = " sum = 0;\n"; 287 288 for (glw::GLint i = (glw::GLint)(bind_even_or_odd); i < m_max_attributes; i += 2) 289 { 290 declarations.append((std::string("in int a_").append(Utilities::itoa(i))).append(";\n")); 291 copies.append((std::string(" sum += a_").append(Utilities::itoa(i))).append(";\n")); 292 } 293 294 std::string vs_template(s_vertex_shader_template); 295 296 std::string vs_source = Utilities::replace(vs_template, "DECLARATION_TEMPLATE", declarations); 297 vs_source = Utilities::replace(vs_source, "COPY_TEMPLATE", copies); 298 299 /* Build and compile. */ 300 return BuildProgram(vs_source.c_str(), bind_even_or_odd); 301 } 302 303 /** @brief Build test's GLSL program. 304 * 305 * @note The function may throw if unexpected error has occured. 306 */ 307 glw::GLuint EnableDisableAttributesTest::BuildProgram(const char* vertex_shader, const bool bind_even_or_odd) 308 { 309 /* Shortcut for GL functionality */ 310 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 311 312 struct Shader 313 { 314 glw::GLchar const* const source; 315 glw::GLenum const type; 316 glw::GLuint id; 317 } shader[] = { { vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } }; 318 319 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]); 320 321 glw::GLuint po = 0; 322 323 try 324 { 325 /* Create program. */ 326 po = gl.createProgram(); 327 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed."); 328 329 /* Shader compilation. */ 330 331 for (glw::GLuint i = 0; i < shader_count; ++i) 332 { 333 if (DE_NULL != shader[i].source) 334 { 335 shader[i].id = gl.createShader(shader[i].type); 336 337 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed."); 338 339 gl.attachShader(po, shader[i].id); 340 341 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed."); 342 343 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL); 344 345 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed."); 346 347 gl.compileShader(shader[i].id); 348 349 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed."); 350 351 glw::GLint status = GL_FALSE; 352 353 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status); 354 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 355 356 if (GL_FALSE == status) 357 { 358 glw::GLint log_size = 0; 359 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size); 360 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 361 362 glw::GLchar* log_text = new glw::GLchar[log_size]; 363 364 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]); 365 366 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n" 367 << "Shader type: " << glu::getShaderTypeStr(shader[i].type) 368 << "\n" 369 << "Shader compilation error log:\n" 370 << log_text << "\n" 371 << "Shader source code:\n" 372 << shader[i].source << "\n" 373 << tcu::TestLog::EndMessage; 374 375 delete[] log_text; 376 377 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed."); 378 379 throw 0; 380 } 381 } 382 } 383 384 /* Transform Feedback setup. */ 385 static const glw::GLchar* xfb_varying = "sum"; 386 387 gl.transformFeedbackVaryings(po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS); 388 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 389 390 for (glw::GLint i = (glw::GLint)(bind_even_or_odd); i < m_max_attributes; i += 2) 391 { 392 std::string attribute = std::string("a_").append(Utilities::itoa(i)); 393 394 gl.bindAttribLocation(po, i, attribute.c_str()); 395 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindAttribLocation call failed."); 396 } 397 398 /* Link. */ 399 gl.linkProgram(po); 400 401 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 402 403 glw::GLint status = GL_FALSE; 404 405 gl.getProgramiv(po, GL_LINK_STATUS, &status); 406 407 if (GL_TRUE == status) 408 { 409 for (glw::GLuint i = 0; i < shader_count; ++i) 410 { 411 if (shader[i].id) 412 { 413 gl.detachShader(po, shader[i].id); 414 415 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed."); 416 } 417 } 418 } 419 else 420 { 421 glw::GLint log_size = 0; 422 423 gl.getProgramiv(po, GL_INFO_LOG_LENGTH, &log_size); 424 425 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed."); 426 427 glw::GLchar* log_text = new glw::GLchar[log_size]; 428 429 gl.getProgramInfoLog(po, log_size, NULL, &log_text[0]); 430 431 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n" 432 << log_text << "\n" 433 << tcu::TestLog::EndMessage; 434 435 delete[] log_text; 436 437 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed."); 438 439 throw 0; 440 } 441 } 442 catch (...) 443 { 444 if (po) 445 { 446 gl.deleteProgram(po); 447 448 po = 0; 449 } 450 } 451 452 for (glw::GLuint i = 0; i < shader_count; ++i) 453 { 454 if (0 != shader[i].id) 455 { 456 gl.deleteShader(shader[i].id); 457 458 shader[i].id = 0; 459 } 460 } 461 462 if (0 == po) 463 { 464 throw 0; 465 } 466 467 return po; 468 } 469 470 /** @brief Prepare vertex array object for the test. 471 */ 472 void EnableDisableAttributesTest::PrepareVAO() 473 { 474 /* Shortcut for GL functionality */ 475 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 476 477 /* VAO creation. */ 478 gl.genVertexArrays(1, &m_vao); 479 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed."); 480 481 gl.bindVertexArray(m_vao); 482 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 483 484 /* Buffer creation. */ 485 gl.genBuffers(1, &m_bo); 486 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 487 488 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo); 489 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 490 491 glw::GLint* reference_data = new glw::GLint[m_max_attributes]; 492 493 if (DE_NULL == reference_data) 494 { 495 throw 0; 496 } 497 498 for (glw::GLint i = 0; i < m_max_attributes; ++i) 499 { 500 reference_data[i] = i; 501 } 502 503 gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLint) * m_max_attributes, reference_data, GL_STATIC_DRAW); 504 505 delete[] reference_data; 506 507 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed."); 508 509 /* VAO setup. */ 510 for (glw::GLint i = 0; i < m_max_attributes; ++i) 511 { 512 gl.vertexAttribIPointer(i, 1, GL_INT, static_cast<glw::GLsizei>(sizeof(glw::GLint) * m_max_attributes), 513 (glw::GLvoid*)((glw::GLint*)NULL + i)); 514 515 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed."); 516 } 517 } 518 519 /** @brief Prepare buffer object for test GLSL program transform feedback results. 520 */ 521 void EnableDisableAttributesTest::PrepareXFB() 522 { 523 /* Shortcut for GL functionality */ 524 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 525 526 /* Buffer creation. */ 527 gl.genBuffers(1, &m_bo_xfb); 528 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 529 530 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb); 531 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 532 533 /* Preparing storage. */ 534 gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint), NULL, GL_MAP_READ_BIT); 535 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed."); 536 537 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb); 538 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed."); 539 } 540 541 /** @brief Draw test program, fetch transform feedback results and compare them with expected values. 542 * 543 * @param [in] bind_even_or_odd Even or odd attribute are enabled. 544 * 545 * @return True if expected results are equal to returned by XFB, false otherwise. 546 */ 547 bool EnableDisableAttributesTest::DrawAndCheck(bool bind_even_or_odd) 548 { 549 /* Shortcut for GL functionality */ 550 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 551 552 /* Setup state. */ 553 gl.useProgram(bind_even_or_odd ? m_po_odd : m_po_even); 554 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed."); 555 556 gl.bindVertexArray(m_vao); 557 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 558 559 gl.beginTransformFeedback(GL_POINTS); 560 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed."); 561 562 /* Draw. */ 563 gl.drawArrays(GL_POINTS, 0, 1); 564 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed."); 565 566 /* State reset. */ 567 gl.endTransformFeedback(); 568 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed."); 569 570 /* Result query. */ 571 glw::GLint* result_ptr = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 572 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed."); 573 574 glw::GLint result = *result_ptr; 575 576 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 577 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed."); 578 579 /* Check result and return. */ 580 if (bind_even_or_odd) 581 { 582 glw::GLint reference_sum = 0; 583 584 for (glw::GLint i = 1; i < m_max_attributes; i += 2) 585 { 586 reference_sum += i; 587 } 588 589 if (reference_sum == result) 590 { 591 return true; 592 } 593 } 594 else 595 { 596 glw::GLint reference_sum = 0; 597 598 for (glw::GLint i = 0; i < m_max_attributes; i += 2) 599 { 600 reference_sum += i; 601 } 602 603 if (reference_sum == result) 604 { 605 return true; 606 } 607 } 608 609 return false; 610 } 611 612 /** @brief Turn on even or odd attributes (up to m_max_attributes) using EnableVertexArrayAttrib function. 613 * 614 * @param [in] enable_even Turn on even attribute indexes. 615 * @param [in] enable_odd Turn on odd attribute indexes. 616 * 617 * @return True if EnableVertexArrayAttrib does not generate any error, false otherwise. 618 */ 619 bool EnableDisableAttributesTest::TurnOnAttributes(bool enable_even, bool enable_odd) 620 { 621 /* Shortcut for GL functionality */ 622 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 623 624 gl.bindVertexArray(0); 625 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 626 627 for (glw::GLint i = 0; i < m_max_attributes; ++i) 628 { 629 bool disable = true; 630 631 if (i % 2) /* if odd */ 632 { 633 if (enable_odd) 634 { 635 gl.enableVertexArrayAttrib(m_vao, i); 636 637 if (glw::GLenum error = gl.getError()) 638 { 639 m_context.getTestContext().getLog() 640 << tcu::TestLog::Message << "glEnableVertexArrayAttrib generated error " 641 << glu::getErrorStr(error) << " when called with VAO " << m_vao << " and index " << i << "." 642 << tcu::TestLog::EndMessage; 643 644 return false; 645 } 646 647 disable = false; 648 } 649 } 650 else 651 { 652 if (enable_even) 653 { 654 gl.enableVertexArrayAttrib(m_vao, i); 655 656 if (glw::GLenum error = gl.getError()) 657 { 658 m_context.getTestContext().getLog() 659 << tcu::TestLog::Message << "glEnableVertexArrayAttrib generated error " 660 << glu::getErrorStr(error) << " when called with VAO " << m_vao << " and index " << i << "." 661 << tcu::TestLog::EndMessage; 662 663 return false; 664 } 665 666 disable = false; 667 } 668 } 669 670 if (disable) 671 { 672 gl.disableVertexArrayAttrib(m_vao, i); 673 674 if (glw::GLenum error = gl.getError()) 675 { 676 m_context.getTestContext().getLog() 677 << tcu::TestLog::Message << "glDisableVertexArrayAttrib generated error " << glu::getErrorStr(error) 678 << " when called with VAO " << m_vao << " and index " << i << "." << tcu::TestLog::EndMessage; 679 680 return false; 681 } 682 } 683 } 684 685 gl.bindVertexArray(m_vao); 686 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 687 688 return true; 689 } 690 691 /** @brief Clean GL objects. */ 692 void EnableDisableAttributesTest::Clean() 693 { 694 /* Shortcut for GL functionality */ 695 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 696 697 gl.useProgram(0); 698 699 if (m_po_even) 700 { 701 gl.deleteProgram(m_po_even); 702 703 m_po_even = 0; 704 } 705 706 if (m_po_odd) 707 { 708 gl.deleteProgram(m_po_odd); 709 710 m_po_odd = 0; 711 } 712 713 if (m_vao) 714 { 715 gl.deleteVertexArrays(1, &m_vao); 716 717 m_vao = 0; 718 } 719 720 if (m_bo) 721 { 722 gl.deleteBuffers(1, &m_bo); 723 724 m_bo = 0; 725 } 726 727 if (m_bo_xfb) 728 { 729 gl.deleteBuffers(1, &m_bo_xfb); 730 731 m_bo_xfb = 0; 732 } 733 734 if (m_max_attributes) 735 { 736 m_max_attributes = 737 16; /* OpenGL 4.5 Required Minimum Table 23.57: Implementation Dependent Vertex Shader Limits */ 738 } 739 740 while (gl.getError()) 741 ; 742 } 743 744 std::string Utilities::itoa(glw::GLuint i) 745 { 746 std::string s = ""; 747 748 std::stringstream ss; 749 750 ss << i; 751 752 s = ss.str(); 753 754 return s; 755 } 756 757 std::string Utilities::replace(const std::string& src, const std::string& key, const std::string& value) 758 { 759 size_t pos = 0; 760 std::string dst = src; 761 762 while (std::string::npos != (pos = dst.find(key, pos))) 763 { 764 dst.replace(pos, key.length(), value); 765 pos += key.length(); 766 } 767 768 return dst; 769 } 770 771 const glw::GLchar EnableDisableAttributesTest::s_vertex_shader_template[] = "#version 450\n" 772 "\n" 773 "DECLARATION_TEMPLATE" 774 "out int sum;\n" 775 "\n" 776 "void main()\n" 777 "{\n" 778 "COPY_TEMPLATE" 779 "}\n"; 780 781 const glw::GLchar EnableDisableAttributesTest::s_fragment_shader[] = "#version 450\n" 782 "\n" 783 "out vec4 color;\n" 784 "\n" 785 "void main()\n" 786 "{\n" 787 " color = vec4(1.0);" 788 "}\n"; 789 790 /******************************** Vertex Array Object Element Buffer Test Implementation ********************************/ 791 792 /** @brief Vertex Array Object Element Buffer Test constructor. 793 * 794 * @param [in] context OpenGL context. 795 */ 796 ElementBufferTest::ElementBufferTest(deqp::Context& context) 797 : deqp::TestCase(context, "vertex_arrays_element_buffer", "Vertex Array Objects Element Buffer Test") 798 , m_po(0) 799 , m_vao(0) 800 , m_bo_array(0) 801 , m_bo_elements(0) 802 , m_bo_xfb(0) 803 { 804 /* Intentionally left blank. */ 805 } 806 807 /** @brief Iterate Vertex Array Object Enable Disable Attributes Test cases. 808 * 809 * @return Iteration result. 810 */ 811 tcu::TestNode::IterateResult ElementBufferTest::iterate() 812 { 813 /* Shortcut for GL functionality. */ 814 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 815 816 /* Get context setup. */ 817 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 818 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 819 820 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 821 { 822 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 823 824 return STOP; 825 } 826 827 /* Running tests. */ 828 bool is_ok = true; 829 bool is_error = false; 830 831 try 832 { 833 PrepareProgram(); 834 is_ok &= PrepareVAO(); 835 PrepareXFB(); 836 is_ok &= DrawAndCheck(); 837 } 838 catch (...) 839 { 840 is_ok = false; 841 is_error = true; 842 } 843 844 /* Cleanup. */ 845 Clean(); 846 847 /* Errors clean up. */ 848 while (gl.getError()) 849 ; 850 851 /* Result's setup. */ 852 if (is_ok) 853 { 854 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 855 } 856 else 857 { 858 if (is_error) 859 { 860 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 861 } 862 else 863 { 864 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 865 } 866 } 867 868 return STOP; 869 } 870 871 /** @brief Build test's GLSL program. 872 * 873 * @note The function may throw if unexpected error has occured. 874 */ 875 void ElementBufferTest::PrepareProgram() 876 { 877 /* Shortcut for GL functionality */ 878 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 879 880 struct Shader 881 { 882 glw::GLchar const* const source; 883 glw::GLenum const type; 884 glw::GLuint id; 885 } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } }; 886 887 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]); 888 889 try 890 { 891 /* Create program. */ 892 m_po = gl.createProgram(); 893 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed."); 894 895 /* Shader compilation. */ 896 897 for (glw::GLuint i = 0; i < shader_count; ++i) 898 { 899 if (DE_NULL != shader[i].source) 900 { 901 shader[i].id = gl.createShader(shader[i].type); 902 903 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed."); 904 905 gl.attachShader(m_po, shader[i].id); 906 907 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed."); 908 909 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL); 910 911 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed."); 912 913 gl.compileShader(shader[i].id); 914 915 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed."); 916 917 glw::GLint status = GL_FALSE; 918 919 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status); 920 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 921 922 if (GL_FALSE == status) 923 { 924 glw::GLint log_size = 0; 925 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size); 926 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 927 928 glw::GLchar* log_text = new glw::GLchar[log_size]; 929 930 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]); 931 932 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n" 933 << "Shader type: " << glu::getShaderTypeStr(shader[i].type) 934 << "\n" 935 << "Shader compilation error log:\n" 936 << log_text << "\n" 937 << "Shader source code:\n" 938 << shader[i].source << "\n" 939 << tcu::TestLog::EndMessage; 940 941 delete[] log_text; 942 943 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed."); 944 945 throw 0; 946 } 947 } 948 } 949 950 /* Transform Feedback setup. */ 951 static const glw::GLchar* xfb_varying = "result"; 952 953 gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS); 954 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 955 956 /* Link. */ 957 gl.linkProgram(m_po); 958 959 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 960 961 glw::GLint status = GL_FALSE; 962 963 gl.getProgramiv(m_po, GL_LINK_STATUS, &status); 964 965 if (GL_TRUE == status) 966 { 967 for (glw::GLuint i = 0; i < shader_count; ++i) 968 { 969 if (shader[i].id) 970 { 971 gl.detachShader(m_po, shader[i].id); 972 973 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed."); 974 } 975 } 976 } 977 else 978 { 979 glw::GLint log_size = 0; 980 981 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size); 982 983 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed."); 984 985 glw::GLchar* log_text = new glw::GLchar[log_size]; 986 987 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]); 988 989 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n" 990 << log_text << "\n" 991 << tcu::TestLog::EndMessage; 992 993 delete[] log_text; 994 995 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed."); 996 997 throw 0; 998 } 999 } 1000 catch (...) 1001 { 1002 if (m_po) 1003 { 1004 gl.deleteProgram(m_po); 1005 1006 m_po = 0; 1007 } 1008 } 1009 1010 for (glw::GLuint i = 0; i < shader_count; ++i) 1011 { 1012 if (0 != shader[i].id) 1013 { 1014 gl.deleteShader(shader[i].id); 1015 1016 shader[i].id = 0; 1017 } 1018 } 1019 1020 if (0 == m_po) 1021 { 1022 throw 0; 1023 } 1024 } 1025 1026 /** @brief Prepare vertex array object for the test of VertexArrayElementBuffer function. 1027 * 1028 * @return True if function VertexArrayElementBuffer* does not generate any error. 1029 */ 1030 bool ElementBufferTest::PrepareVAO() 1031 { 1032 /* Shortcut for GL functionality */ 1033 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1034 1035 /* VAO creation. */ 1036 gl.genVertexArrays(1, &m_vao); 1037 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed."); 1038 1039 gl.bindVertexArray(m_vao); 1040 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 1041 1042 /* Array buffer creation. */ 1043 glw::GLint array_data[3] = { 2, 1, 0 }; 1044 1045 gl.genBuffers(1, &m_bo_array); 1046 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 1047 1048 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array); 1049 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 1050 1051 gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW); 1052 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed."); 1053 1054 gl.vertexAttribIPointer(gl.getAttribLocation(m_po, "a"), 1, GL_INT, 0, NULL); 1055 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed."); 1056 1057 gl.enableVertexAttribArray(0); 1058 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed."); 1059 1060 gl.bindVertexArray(0); 1061 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 1062 1063 /* Element buffer creation. */ 1064 glw::GLuint elements_data[3] = { 2, 1, 0 }; 1065 1066 gl.genBuffers(1, &m_bo_elements); 1067 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 1068 1069 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bo_elements); 1070 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 1071 1072 gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements_data), elements_data, GL_STATIC_DRAW); 1073 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed."); 1074 1075 gl.vertexArrayElementBuffer(m_vao, m_bo_elements); 1076 1077 if (glw::GLenum error = gl.getError()) 1078 { 1079 m_context.getTestContext().getLog() << tcu::TestLog::Message 1080 << "VertexArrayElementBuffer has unexpectedly generated " 1081 << glu::getErrorStr(error) << "error. Test fails.\n" 1082 << tcu::TestLog::EndMessage; 1083 1084 return false; 1085 } 1086 1087 return true; 1088 } 1089 1090 /** @brief Prepare buffer object for test GLSL program transform feedback results. 1091 */ 1092 void ElementBufferTest::PrepareXFB() 1093 { 1094 /* Shortcut for GL functionality */ 1095 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1096 1097 /* Buffer creation. */ 1098 gl.genBuffers(1, &m_bo_xfb); 1099 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 1100 1101 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb); 1102 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 1103 1104 /* Preparing storage. */ 1105 gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 3 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT); 1106 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed."); 1107 1108 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb); 1109 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed."); 1110 } 1111 1112 /** @brief Draw test program, fetch transform feedback results and compare them with expected values. 1113 * 1114 * @return True if expected results are equal to returned by XFB, false otherwise. 1115 */ 1116 bool ElementBufferTest::DrawAndCheck() 1117 { 1118 /* Shortcut for GL functionality */ 1119 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1120 1121 /* Setup state. */ 1122 gl.useProgram(m_po); 1123 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed."); 1124 1125 gl.bindVertexArray(m_vao); 1126 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 1127 1128 gl.beginTransformFeedback(GL_POINTS); 1129 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed."); 1130 1131 /* Draw. */ 1132 gl.drawElements(GL_POINTS, 3, GL_UNSIGNED_INT, NULL); 1133 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed."); 1134 1135 /* State reset. */ 1136 gl.endTransformFeedback(); 1137 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed."); 1138 1139 /* Result query. */ 1140 glw::GLint* result_ptr = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 1141 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed."); 1142 1143 glw::GLint result[3] = { result_ptr[0], result_ptr[1], result_ptr[2] }; 1144 1145 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 1146 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed."); 1147 1148 /* Check result and return. */ 1149 for (glw::GLint i = 0; i < 3; ++i) 1150 { 1151 if (i != result[i]) 1152 { 1153 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Result vector is equal to [" << result[0] 1154 << ", " << result[1] << ", " << result[2] 1155 << "], but [0, 1, 2] was expected." << tcu::TestLog::EndMessage; 1156 1157 return false; 1158 } 1159 } 1160 1161 return true; 1162 } 1163 1164 /** @brief Clean GL objects. */ 1165 void ElementBufferTest::Clean() 1166 { 1167 /* Shortcut for GL functionality */ 1168 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1169 1170 gl.useProgram(0); 1171 1172 if (m_po) 1173 { 1174 gl.deleteProgram(m_po); 1175 1176 m_po = 0; 1177 } 1178 1179 if (m_vao) 1180 { 1181 gl.deleteVertexArrays(1, &m_vao); 1182 1183 m_vao = 0; 1184 } 1185 1186 if (m_bo_array) 1187 { 1188 gl.deleteBuffers(1, &m_bo_array); 1189 1190 m_bo_array = 0; 1191 } 1192 1193 if (m_bo_elements) 1194 { 1195 gl.deleteBuffers(1, &m_bo_elements); 1196 1197 m_bo_elements = 0; 1198 } 1199 1200 if (m_bo_xfb) 1201 { 1202 gl.deleteBuffers(1, &m_bo_xfb); 1203 1204 m_bo_xfb = 0; 1205 } 1206 1207 while (gl.getError()) 1208 ; 1209 } 1210 1211 const glw::GLchar ElementBufferTest::s_vertex_shader[] = "#version 450\n" 1212 "\n" 1213 "in int a;" 1214 "out int result;\n" 1215 "\n" 1216 "void main()\n" 1217 "{\n" 1218 " gl_Position = vec4(1.0);\n" 1219 " result = a;" 1220 "}\n"; 1221 1222 const glw::GLchar ElementBufferTest::s_fragment_shader[] = "#version 450\n" 1223 "\n" 1224 "out vec4 color;\n" 1225 "\n" 1226 "void main()\n" 1227 "{\n" 1228 " color = vec4(1.0);" 1229 "}\n"; 1230 1231 /******************************** Vertex Array Object Vertex Buffer and Buffers Test Implementation ********************************/ 1232 1233 /** @brief Vertex Array Object Element Buffer Test constructor. 1234 * 1235 * @param [in] context OpenGL context. 1236 */ 1237 VertexBuffersTest::VertexBuffersTest(deqp::Context& context) 1238 : deqp::TestCase(context, "vertex_arrays_vertex_buffers", "Vertex Array Object Vertex Buffer and Buffers Test") 1239 , m_po(0) 1240 , m_vao(0) 1241 , m_bo_array_0(0) 1242 , m_bo_array_1(0) 1243 , m_bo_xfb(0) 1244 { 1245 /* Intentionally left blank. */ 1246 } 1247 1248 /** @brief Iterate Vertex Array Object Enable Disable Attributes Test cases. 1249 * 1250 * @return Iteration result. 1251 */ 1252 tcu::TestNode::IterateResult VertexBuffersTest::iterate() 1253 { 1254 /* Shortcut for GL functionality. */ 1255 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1256 1257 /* Get context setup. */ 1258 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 1259 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 1260 1261 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 1262 { 1263 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 1264 1265 return STOP; 1266 } 1267 1268 /* Running tests. */ 1269 bool is_ok = true; 1270 bool is_error = false; 1271 1272 try 1273 { 1274 PrepareProgram(); 1275 is_ok &= PrepareVAO(false); 1276 PrepareXFB(); 1277 is_ok &= DrawAndCheck(); 1278 Clean(); 1279 1280 PrepareProgram(); 1281 is_ok &= PrepareVAO(true); 1282 PrepareXFB(); 1283 is_ok &= DrawAndCheck(); 1284 } 1285 catch (...) 1286 { 1287 is_ok = false; 1288 is_error = true; 1289 } 1290 1291 /* Cleanup. */ 1292 Clean(); 1293 1294 /* Errors clean up. */ 1295 while (gl.getError()) 1296 ; 1297 1298 /* Result's setup. */ 1299 if (is_ok) 1300 { 1301 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1302 } 1303 else 1304 { 1305 if (is_error) 1306 { 1307 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 1308 } 1309 else 1310 { 1311 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1312 } 1313 } 1314 1315 return STOP; 1316 } 1317 1318 /** @brief Build test's GLSL program. 1319 * 1320 * @note The function may throw if unexpected error has occured. 1321 */ 1322 void VertexBuffersTest::PrepareProgram() 1323 { 1324 /* Shortcut for GL functionality */ 1325 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1326 1327 struct Shader 1328 { 1329 glw::GLchar const* const source; 1330 glw::GLenum const type; 1331 glw::GLuint id; 1332 } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } }; 1333 1334 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]); 1335 1336 try 1337 { 1338 /* Create program. */ 1339 m_po = gl.createProgram(); 1340 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed."); 1341 1342 /* Shader compilation. */ 1343 1344 for (glw::GLuint i = 0; i < shader_count; ++i) 1345 { 1346 if (DE_NULL != shader[i].source) 1347 { 1348 shader[i].id = gl.createShader(shader[i].type); 1349 1350 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed."); 1351 1352 gl.attachShader(m_po, shader[i].id); 1353 1354 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed."); 1355 1356 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL); 1357 1358 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed."); 1359 1360 gl.compileShader(shader[i].id); 1361 1362 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed."); 1363 1364 glw::GLint status = GL_FALSE; 1365 1366 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status); 1367 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 1368 1369 if (GL_FALSE == status) 1370 { 1371 glw::GLint log_size = 0; 1372 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size); 1373 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 1374 1375 glw::GLchar* log_text = new glw::GLchar[log_size]; 1376 1377 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]); 1378 1379 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n" 1380 << "Shader type: " << glu::getShaderTypeStr(shader[i].type) 1381 << "\n" 1382 << "Shader compilation error log:\n" 1383 << log_text << "\n" 1384 << "Shader source code:\n" 1385 << shader[i].source << "\n" 1386 << tcu::TestLog::EndMessage; 1387 1388 delete[] log_text; 1389 1390 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed."); 1391 1392 throw 0; 1393 } 1394 } 1395 } 1396 1397 /* Transform Feedback setup. */ 1398 static const glw::GLchar* xfb_varying = "result"; 1399 1400 gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS); 1401 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 1402 1403 /* Link. */ 1404 gl.linkProgram(m_po); 1405 1406 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 1407 1408 glw::GLint status = GL_FALSE; 1409 1410 gl.getProgramiv(m_po, GL_LINK_STATUS, &status); 1411 1412 if (GL_TRUE == status) 1413 { 1414 for (glw::GLuint i = 0; i < shader_count; ++i) 1415 { 1416 if (shader[i].id) 1417 { 1418 gl.detachShader(m_po, shader[i].id); 1419 1420 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed."); 1421 } 1422 } 1423 } 1424 else 1425 { 1426 glw::GLint log_size = 0; 1427 1428 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size); 1429 1430 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed."); 1431 1432 glw::GLchar* log_text = new glw::GLchar[log_size]; 1433 1434 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]); 1435 1436 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n" 1437 << log_text << "\n" 1438 << tcu::TestLog::EndMessage; 1439 1440 delete[] log_text; 1441 1442 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed."); 1443 1444 throw 0; 1445 } 1446 } 1447 catch (...) 1448 { 1449 if (m_po) 1450 { 1451 gl.deleteProgram(m_po); 1452 1453 m_po = 0; 1454 } 1455 } 1456 1457 for (glw::GLuint i = 0; i < shader_count; ++i) 1458 { 1459 if (0 != shader[i].id) 1460 { 1461 gl.deleteShader(shader[i].id); 1462 1463 shader[i].id = 0; 1464 } 1465 } 1466 1467 if (0 == m_po) 1468 { 1469 throw 0; 1470 } 1471 } 1472 1473 /** @brief Prepare vertex array object for the test of gl.vertexArrayVertexBuffer* functions. 1474 * 1475 * @param [in] use_multiple_buffers_function Use gl.vertexArrayVertexBuffers instead of gl.vertexArrayVertexBuffer. 1476 * 1477 * @return True if functions gl.vertexArrayVertexBuffer* do not generate any error. 1478 */ 1479 bool VertexBuffersTest::PrepareVAO(bool use_multiple_buffers_function) 1480 { 1481 /* Shortcut for GL functionality */ 1482 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1483 1484 /* VAO creation. */ 1485 gl.genVertexArrays(1, &m_vao); 1486 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed."); 1487 1488 gl.bindVertexArray(m_vao); 1489 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 1490 1491 /* Array buffer 0 creation. */ 1492 glw::GLint array_data_0[4] = { 0, 2, 1, 3 }; 1493 1494 gl.genBuffers(1, &m_bo_array_0); 1495 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 1496 1497 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array_0); 1498 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 1499 1500 gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data_0), array_data_0, GL_STATIC_DRAW); 1501 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed."); 1502 1503 gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_0"), 0); 1504 1505 gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_1"), 1); 1506 1507 gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a_0"), 1, GL_INT, 0); 1508 1509 gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a_1"), 1, GL_INT, 0); 1510 1511 if (use_multiple_buffers_function) 1512 { 1513 const glw::GLuint buffers[2] = { m_bo_array_0, m_bo_array_0 }; 1514 static const glw::GLintptr offsets[2] = { (glw::GLintptr)NULL, (glw::GLintptr)((glw::GLint*)NULL + 1) }; 1515 static const glw::GLsizei strides[2] = { sizeof(glw::GLint) * 2, sizeof(glw::GLint) * 2 }; 1516 1517 gl.vertexArrayVertexBuffers(m_vao, 0, 2, buffers, offsets, strides); 1518 1519 if (glw::GLenum error = gl.getError()) 1520 { 1521 m_context.getTestContext().getLog() << tcu::TestLog::Message 1522 << "VertexArrayVertexBuffers has unexpectedly generated " 1523 << glu::getErrorStr(error) << "error. Test fails.\n" 1524 << tcu::TestLog::EndMessage; 1525 1526 return false; 1527 } 1528 } 1529 else 1530 { 1531 gl.vertexArrayVertexBuffer(m_vao, 0, m_bo_array_0, (glw::GLintptr)NULL, sizeof(glw::GLint) * 2); 1532 1533 if (glw::GLenum error = gl.getError()) 1534 { 1535 m_context.getTestContext().getLog() << tcu::TestLog::Message 1536 << "VertexArrayVertexBuffer has unexpectedly generated " 1537 << glu::getErrorStr(error) << "error. Test fails.\n" 1538 << tcu::TestLog::EndMessage; 1539 1540 return false; 1541 } 1542 1543 gl.vertexArrayVertexBuffer(m_vao, 1, m_bo_array_0, (glw::GLintptr)((glw::GLint*)NULL + 1), 1544 sizeof(glw::GLint) * 2); 1545 1546 if (glw::GLenum error = gl.getError()) 1547 { 1548 m_context.getTestContext().getLog() << tcu::TestLog::Message 1549 << "VertexArrayVertexBuffer has unexpectedly generated " 1550 << glu::getErrorStr(error) << "error. Test fails.\n" 1551 << tcu::TestLog::EndMessage; 1552 1553 return false; 1554 } 1555 } 1556 1557 gl.enableVertexAttribArray(0); 1558 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed."); 1559 1560 gl.enableVertexAttribArray(1); 1561 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed."); 1562 1563 /* Array buffer 1 creation. */ 1564 glw::GLint array_data_1[2] = { 4, 5 }; 1565 1566 gl.genBuffers(1, &m_bo_array_1); 1567 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 1568 1569 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array_1); 1570 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 1571 1572 gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data_1), array_data_1, GL_STATIC_DRAW); 1573 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed."); 1574 1575 gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_2"), 2); 1576 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed."); 1577 1578 gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a_2"), 1, GL_INT, 0); 1579 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIFormat call failed."); 1580 1581 if (use_multiple_buffers_function) 1582 { 1583 glw::GLintptr offset = (glw::GLintptr)NULL; 1584 glw::GLsizei stride = sizeof(glw::GLint); 1585 1586 gl.vertexArrayVertexBuffers(m_vao, 2, 1, &m_bo_array_1, &offset, &stride); 1587 1588 if (glw::GLenum error = gl.getError()) 1589 { 1590 m_context.getTestContext().getLog() << tcu::TestLog::Message 1591 << "VertexArrayVertexBuffers has unexpectedly generated " 1592 << glu::getErrorStr(error) << "error. Test fails.\n" 1593 << tcu::TestLog::EndMessage; 1594 1595 return false; 1596 } 1597 } 1598 else 1599 { 1600 gl.vertexArrayVertexBuffer(m_vao, 2, m_bo_array_1, (glw::GLintptr)NULL, sizeof(glw::GLint)); 1601 1602 if (glw::GLenum error = gl.getError()) 1603 { 1604 m_context.getTestContext().getLog() << tcu::TestLog::Message 1605 << "VertexArrayVertexBuffer has unexpectedly generated " 1606 << glu::getErrorStr(error) << "error. Test fails.\n" 1607 << tcu::TestLog::EndMessage; 1608 1609 return false; 1610 } 1611 } 1612 1613 gl.enableVertexAttribArray(2); 1614 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed."); 1615 1616 gl.bindVertexArray(0); 1617 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 1618 1619 return true; 1620 } 1621 1622 /** @brief Prepare buffer object for test GLSL program transform feedback results. 1623 */ 1624 void VertexBuffersTest::PrepareXFB() 1625 { 1626 /* Shortcut for GL functionality */ 1627 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1628 1629 /* Buffer creation. */ 1630 gl.genBuffers(1, &m_bo_xfb); 1631 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 1632 1633 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb); 1634 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 1635 1636 /* Preparing storage. */ 1637 gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 2 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT); 1638 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed."); 1639 1640 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb); 1641 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed."); 1642 } 1643 1644 /** @brief Draw test program, fetch transform feedback results and compare them with expected values. 1645 * 1646 * @return True if expected results are equal to returned by XFB, false otherwise. 1647 */ 1648 bool VertexBuffersTest::DrawAndCheck() 1649 { 1650 /* Shortcut for GL functionality */ 1651 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1652 1653 /* Setup state. */ 1654 gl.useProgram(m_po); 1655 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed."); 1656 1657 gl.bindVertexArray(m_vao); 1658 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 1659 1660 gl.beginTransformFeedback(GL_POINTS); 1661 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed."); 1662 1663 /* Draw. */ 1664 gl.drawArrays(GL_POINTS, 0, 2); 1665 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed."); 1666 1667 /* State reset. */ 1668 gl.endTransformFeedback(); 1669 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed."); 1670 1671 /* Result query. */ 1672 glw::GLint* result_ptr = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 1673 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed."); 1674 1675 glw::GLint result[2] = { result_ptr[0], result_ptr[1] }; 1676 1677 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 1678 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed."); 1679 1680 static const glw::GLint reference[2] = { 0 + 2 + 4, 1 + 3 + 5 }; 1681 1682 /* Check result and return. */ 1683 for (glw::GLint i = 0; i < 2; ++i) 1684 { 1685 if (reference[i] != result[i]) 1686 { 1687 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Result vector is equal to [" << result[0] 1688 << ", " << result[1] << "], but [" << reference[0] << ", " 1689 << reference[1] << "] was expected." << tcu::TestLog::EndMessage; 1690 1691 return false; 1692 } 1693 } 1694 1695 return true; 1696 } 1697 1698 /** @brief Clean GL objects. */ 1699 void VertexBuffersTest::Clean() 1700 { 1701 /* Shortcut for GL functionality */ 1702 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1703 1704 gl.useProgram(0); 1705 1706 if (m_po) 1707 { 1708 gl.deleteProgram(m_po); 1709 1710 m_po = 0; 1711 } 1712 1713 if (m_vao) 1714 { 1715 gl.deleteVertexArrays(1, &m_vao); 1716 1717 m_vao = 0; 1718 } 1719 1720 if (m_bo_array_0) 1721 { 1722 gl.deleteBuffers(1, &m_bo_array_0); 1723 1724 m_bo_array_0 = 0; 1725 } 1726 1727 if (m_bo_array_1) 1728 { 1729 gl.deleteBuffers(1, &m_bo_array_1); 1730 1731 m_bo_array_1 = 0; 1732 } 1733 1734 if (m_bo_xfb) 1735 { 1736 gl.deleteBuffers(1, &m_bo_xfb); 1737 1738 m_bo_xfb = 0; 1739 } 1740 1741 while (gl.getError()) 1742 ; 1743 } 1744 1745 const glw::GLchar VertexBuffersTest::s_vertex_shader[] = "#version 450\n" 1746 "\n" 1747 "in int a_0;" 1748 "in int a_1;" 1749 "in int a_2;" 1750 "\n" 1751 "out int result;\n" 1752 "\n" 1753 "void main()\n" 1754 "{\n" 1755 " gl_Position = vec4(1.0);\n" 1756 " result = a_0 + a_1 + a_2;" 1757 "}\n"; 1758 1759 const glw::GLchar VertexBuffersTest::s_fragment_shader[] = "#version 450\n" 1760 "\n" 1761 "out vec4 color;\n" 1762 "\n" 1763 "void main()\n" 1764 "{\n" 1765 " color = vec4(1.0);" 1766 "}\n"; 1767 1768 /******************************** Vertex Array Object Attribute Format Test Implementation ********************************/ 1769 1770 /** @brief Vertex Array Object Element Buffer Test constructor. 1771 * 1772 * @param [in] context OpenGL context. 1773 */ 1774 AttributeFormatTest::AttributeFormatTest(deqp::Context& context) 1775 : deqp::TestCase(context, "vertex_arrays_attribute_format", "Vertex Array Object Attribute Format Test") 1776 , m_po(0) 1777 , m_vao(0) 1778 , m_bo_array(0) 1779 , m_bo_xfb(0) 1780 { 1781 /* Intentionally left blank. */ 1782 } 1783 1784 /** @brief Iterate Vertex Array Object Enable Disable Attributes Test cases. 1785 * 1786 * @return Iteration result. 1787 */ 1788 tcu::TestNode::IterateResult AttributeFormatTest::iterate() 1789 { 1790 /* Shortcut for GL functionality. */ 1791 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1792 1793 /* Get context setup. */ 1794 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 1795 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 1796 1797 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 1798 { 1799 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 1800 1801 return STOP; 1802 } 1803 1804 /* Running tests. */ 1805 bool is_ok = true; 1806 bool is_error = false; 1807 1808 try 1809 { 1810 PrepareXFB(); 1811 1812 /* Test floating function. */ 1813 for (glw::GLuint i = 1; i <= 4 /* max size */; ++i) 1814 { 1815 PrepareProgram(i, ATTRIBUTE_FORMAT_FUNCTION_FLOAT); 1816 1817 is_ok &= PrepareVAO<glw::GLfloat>(i, GL_FLOAT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT); 1818 is_ok &= DrawAndCheck<glw::GLfloat>(i, false); 1819 1820 CleanVAO(); 1821 1822 is_ok &= PrepareVAO<glw::GLbyte>(i, GL_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT); 1823 is_ok &= DrawAndCheck<glw::GLfloat>(i, false); 1824 1825 CleanVAO(); 1826 1827 is_ok &= PrepareVAO<glw::GLbyte>(i, GL_BYTE, true, ATTRIBUTE_FORMAT_FUNCTION_FLOAT); 1828 is_ok &= DrawAndCheck<glw::GLfloat>(i, true); 1829 1830 CleanVAO(); 1831 1832 is_ok &= PrepareVAO<glw::GLubyte>(i, GL_UNSIGNED_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT); 1833 is_ok &= DrawAndCheck<glw::GLfloat>(i, false); 1834 1835 CleanVAO(); 1836 1837 is_ok &= PrepareVAO<glw::GLshort>(i, GL_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT); 1838 is_ok &= DrawAndCheck<glw::GLfloat>(i, false); 1839 1840 CleanVAO(); 1841 1842 is_ok &= PrepareVAO<glw::GLushort>(i, GL_UNSIGNED_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT); 1843 is_ok &= DrawAndCheck<glw::GLfloat>(i, false); 1844 1845 CleanVAO(); 1846 1847 is_ok &= PrepareVAO<glw::GLint>(i, GL_INT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT); 1848 is_ok &= DrawAndCheck<glw::GLfloat>(i, false); 1849 1850 CleanVAO(); 1851 1852 is_ok &= PrepareVAO<glw::GLuint>(i, GL_UNSIGNED_INT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT); 1853 is_ok &= DrawAndCheck<glw::GLfloat>(i, false); 1854 1855 CleanVAO(); 1856 1857 CleanProgram(); 1858 } 1859 1860 for (glw::GLuint i = 1; i <= 2 /* max size */; ++i) 1861 { 1862 PrepareProgram(i, ATTRIBUTE_FORMAT_FUNCTION_DOUBLE); 1863 1864 is_ok &= PrepareVAO<glw::GLdouble>(i, GL_DOUBLE, false, ATTRIBUTE_FORMAT_FUNCTION_DOUBLE); 1865 is_ok &= DrawAndCheck<glw::GLdouble>(i, false); 1866 1867 CleanProgram(); 1868 CleanVAO(); 1869 } 1870 1871 for (glw::GLuint i = 1; i <= 4 /* max size */; ++i) 1872 { 1873 PrepareProgram(i, ATTRIBUTE_FORMAT_FUNCTION_INTEGER); 1874 1875 is_ok &= PrepareVAO<glw::GLbyte>(i, GL_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER); 1876 is_ok &= DrawAndCheck<glw::GLint>(i, false); 1877 1878 CleanVAO(); 1879 1880 is_ok &= PrepareVAO<glw::GLubyte>(i, GL_UNSIGNED_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER); 1881 is_ok &= DrawAndCheck<glw::GLint>(i, false); 1882 1883 CleanVAO(); 1884 1885 is_ok &= PrepareVAO<glw::GLshort>(i, GL_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER); 1886 is_ok &= DrawAndCheck<glw::GLint>(i, false); 1887 1888 CleanVAO(); 1889 1890 is_ok &= PrepareVAO<glw::GLushort>(i, GL_UNSIGNED_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER); 1891 is_ok &= DrawAndCheck<glw::GLint>(i, false); 1892 1893 CleanVAO(); 1894 1895 is_ok &= PrepareVAO<glw::GLint>(i, GL_INT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER); 1896 is_ok &= DrawAndCheck<glw::GLint>(i, false); 1897 1898 CleanVAO(); 1899 1900 is_ok &= PrepareVAO<glw::GLuint>(i, GL_UNSIGNED_INT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER); 1901 is_ok &= DrawAndCheck<glw::GLint>(i, false); 1902 1903 CleanVAO(); 1904 1905 CleanProgram(); 1906 } 1907 } 1908 catch (...) 1909 { 1910 is_ok = false; 1911 is_error = true; 1912 } 1913 1914 /* Cleanup. */ 1915 CleanProgram(); 1916 CleanVAO(); 1917 CleanXFB(); 1918 1919 /* Errors clean up. */ 1920 while (gl.getError()) 1921 ; 1922 1923 /* Result's setup. */ 1924 if (is_ok) 1925 { 1926 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1927 } 1928 else 1929 { 1930 if (is_error) 1931 { 1932 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 1933 } 1934 else 1935 { 1936 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1937 } 1938 } 1939 1940 return STOP; 1941 } 1942 1943 /** @brief Build test's GLSL program. 1944 * 1945 * @note The function may throw if unexpected error has occured. 1946 */ 1947 void AttributeFormatTest::PrepareProgram(glw::GLint size, AtributeFormatFunctionType function_selector) 1948 { 1949 /* Shortcut for GL functionality */ 1950 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1951 1952 struct Shader 1953 { 1954 glw::GLchar const* source[3]; 1955 glw::GLuint const count; 1956 glw::GLenum const type; 1957 glw::GLuint id; 1958 } shader[] = { { { s_vertex_shader_head, s_vertex_shader_declaration[function_selector][size - 1], 1959 s_vertex_shader_body }, 1960 3, 1961 GL_VERTEX_SHADER, 1962 0 }, 1963 { { s_fragment_shader, DE_NULL, DE_NULL }, 1, GL_FRAGMENT_SHADER, 0 } }; 1964 1965 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]); 1966 1967 try 1968 { 1969 /* Create program. */ 1970 m_po = gl.createProgram(); 1971 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed."); 1972 1973 /* Shader compilation. */ 1974 1975 for (glw::GLuint i = 0; i < shader_count; ++i) 1976 { 1977 { 1978 shader[i].id = gl.createShader(shader[i].type); 1979 1980 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed."); 1981 1982 gl.attachShader(m_po, shader[i].id); 1983 1984 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed."); 1985 1986 gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL); 1987 1988 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed."); 1989 1990 gl.compileShader(shader[i].id); 1991 1992 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed."); 1993 1994 glw::GLint status = GL_FALSE; 1995 1996 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status); 1997 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 1998 1999 if (GL_FALSE == status) 2000 { 2001 glw::GLint log_size = 0; 2002 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size); 2003 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 2004 2005 glw::GLchar* log_text = new glw::GLchar[log_size]; 2006 2007 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]); 2008 2009 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n" 2010 << "Shader type: " << glu::getShaderTypeStr(shader[i].type) 2011 << "\n" 2012 << "Shader compilation error log:\n" 2013 << log_text << "\n" 2014 << "Shader source code:\n" 2015 << shader[i].source << "\n" 2016 << tcu::TestLog::EndMessage; 2017 2018 delete[] log_text; 2019 2020 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed."); 2021 2022 throw 0; 2023 } 2024 } 2025 } 2026 2027 /* Transform Feedback setup. */ 2028 static const glw::GLchar* xfb_varying = "result"; 2029 2030 gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS); 2031 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 2032 2033 /* Link. */ 2034 gl.linkProgram(m_po); 2035 2036 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 2037 2038 glw::GLint status = GL_FALSE; 2039 2040 gl.getProgramiv(m_po, GL_LINK_STATUS, &status); 2041 2042 if (GL_TRUE == status) 2043 { 2044 for (glw::GLuint i = 0; i < shader_count; ++i) 2045 { 2046 if (shader[i].id) 2047 { 2048 gl.detachShader(m_po, shader[i].id); 2049 2050 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed."); 2051 } 2052 } 2053 } 2054 else 2055 { 2056 glw::GLint log_size = 0; 2057 2058 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size); 2059 2060 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed."); 2061 2062 glw::GLchar* log_text = new glw::GLchar[log_size]; 2063 2064 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]); 2065 2066 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n" 2067 << log_text << "\n" 2068 << tcu::TestLog::EndMessage; 2069 2070 delete[] log_text; 2071 2072 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed."); 2073 2074 throw 0; 2075 } 2076 } 2077 catch (...) 2078 { 2079 if (m_po) 2080 { 2081 gl.deleteProgram(m_po); 2082 2083 m_po = 0; 2084 } 2085 } 2086 2087 for (glw::GLuint i = 0; i < shader_count; ++i) 2088 { 2089 if (0 != shader[i].id) 2090 { 2091 gl.deleteShader(shader[i].id); 2092 2093 shader[i].id = 0; 2094 } 2095 } 2096 2097 if (0 == m_po) 2098 { 2099 throw 0; 2100 } 2101 } 2102 2103 template <> 2104 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLuint>() 2105 { 2106 return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLuint) - 4 /* 1.0 / 16.0 */)); 2107 } 2108 2109 template <> 2110 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLushort>() 2111 { 2112 return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLushort) - 4 /* 1.0 / 16.0 */)); 2113 } 2114 2115 template <> 2116 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLubyte>() 2117 { 2118 return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLubyte) - 4 /* 1.0 / 16.0 */)); 2119 } 2120 2121 template <> 2122 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLint>() 2123 { 2124 return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLint) - 4 /* 1.0 / 16.0 */ - 1 /* sign bit */)); 2125 } 2126 2127 template <> 2128 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLshort>() 2129 { 2130 return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLshort) - 4 /* 1.0 / 16.0 */ - 1 /* sign bit */)); 2131 } 2132 2133 template <> 2134 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLbyte>() 2135 { 2136 return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLbyte) - 4 /* 1.0 / 16.0 */ - 1 /* sign bit */)); 2137 } 2138 2139 template <typename T> 2140 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor() 2141 { 2142 return 1.0; /* Rest of the types cannot be normalized. */ 2143 } 2144 2145 /** @brief Prepare vertex array object for the test of VertexArrayAttrib*Format function. 2146 * 2147 * @param [in] size Size passed to VertexArrayAttrib*Format. 2148 * @param [in] type_gl_name Type passed to VertexArrayAttrib*Format. 2149 * @param [in] function_selector Selects one of VertexArrayAttrib*Format functions. 2150 * 2151 * @return True if function VertexArrayAttrib*Format does not generate any error. 2152 */ 2153 template <typename T> 2154 bool AttributeFormatTest::PrepareVAO(glw::GLint size, glw::GLenum type_gl_name, bool normalized, 2155 AtributeFormatFunctionType function_selector) 2156 { 2157 /* Shortcut for GL functionality */ 2158 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2159 2160 /* VAO creation. */ 2161 gl.genVertexArrays(1, &m_vao); 2162 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed."); 2163 2164 gl.bindVertexArray(m_vao); 2165 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 2166 2167 /* Array buffer 0 creation. */ 2168 2169 const glw::GLdouble scale = normalized ? NormalizationScaleFactor<T>() : 1.0; 2170 2171 const T array_data[16] = { (T)(0.0 * scale), (T)(1.0 * scale), (T)(2.0 * scale), (T)(3.0 * scale), 2172 (T)(4.0 * scale), (T)(5.0 * scale), (T)(6.0 * scale), (T)(7.0 * scale), 2173 (T)(8.0 * scale), (T)(9.0 * scale), (T)(10.0 * scale), (T)(11.0 * scale), 2174 (T)(12.0 * scale), (T)(13.0 * scale), (T)(14.0 * scale), (T)(15.0 * scale) }; 2175 2176 gl.genBuffers(1, &m_bo_array); 2177 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 2178 2179 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array); 2180 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 2181 2182 gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW); 2183 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed."); 2184 2185 /* Attribute setup. */ 2186 gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_0"), 0); 2187 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed."); 2188 2189 gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_1"), 1); 2190 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed."); 2191 2192 /* Tested attribute format setup. */ 2193 switch (function_selector) 2194 { 2195 case ATTRIBUTE_FORMAT_FUNCTION_FLOAT: 2196 gl.vertexArrayAttribFormat(m_vao, gl.getAttribLocation(m_po, "a_0"), size, type_gl_name, normalized, 0); 2197 gl.vertexArrayAttribFormat(m_vao, gl.getAttribLocation(m_po, "a_1"), size, type_gl_name, normalized, 0); 2198 break; 2199 2200 case ATTRIBUTE_FORMAT_FUNCTION_DOUBLE: 2201 gl.vertexArrayAttribLFormat(m_vao, gl.getAttribLocation(m_po, "a_0"), size, type_gl_name, 0); 2202 gl.vertexArrayAttribLFormat(m_vao, gl.getAttribLocation(m_po, "a_1"), size, type_gl_name, 0); 2203 break; 2204 2205 case ATTRIBUTE_FORMAT_FUNCTION_INTEGER: 2206 gl.vertexArrayAttribIFormat(m_vao, gl.getAttribLocation(m_po, "a_0"), size, type_gl_name, 0); 2207 gl.vertexArrayAttribIFormat(m_vao, gl.getAttribLocation(m_po, "a_1"), size, type_gl_name, 0); 2208 break; 2209 default: 2210 throw 0; 2211 } 2212 2213 if (glw::GLenum error = gl.getError()) 2214 { 2215 m_context.getTestContext().getLog() 2216 << tcu::TestLog::Message 2217 << ((ATTRIBUTE_FORMAT_FUNCTION_FLOAT == function_selector) ? 2218 "VertexArrayAttribFormat" : 2219 ((ATTRIBUTE_FORMAT_FUNCTION_DOUBLE == function_selector) ? 2220 "VertexArrayAttribLFormat" : 2221 ((ATTRIBUTE_FORMAT_FUNCTION_INTEGER == function_selector) ? "VertexArrayAttribIFormat" : 2222 "VertexArrayAttrib?Format"))) 2223 << " has unexpectedly generated " << glu::getErrorStr(error) << "error for test with size = " << size 2224 << ", type = " << glu::getTypeStr(type_gl_name) 2225 << ((ATTRIBUTE_FORMAT_FUNCTION_FLOAT == function_selector) ? 2226 (normalized ? ", which was normalized." : ", which was not normalized.") : 2227 ".") 2228 << " Test fails.\n" 2229 << tcu::TestLog::EndMessage; 2230 2231 return false; 2232 } 2233 2234 gl.bindVertexBuffer(0, m_bo_array, 0, static_cast<glw::GLsizei>(sizeof(T) * size * 2)); 2235 gl.bindVertexBuffer(1, m_bo_array, (glw::GLintptr)((T*)NULL + size), 2236 static_cast<glw::GLsizei>(sizeof(T) * size * 2)); 2237 2238 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed."); 2239 2240 gl.enableVertexAttribArray(0); 2241 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed."); 2242 2243 gl.enableVertexAttribArray(1); 2244 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed."); 2245 2246 gl.bindVertexArray(0); 2247 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 2248 2249 return true; 2250 } 2251 2252 /** @brief Prepare buffer object for test GLSL program transform feedback results. 2253 */ 2254 void AttributeFormatTest::PrepareXFB() 2255 { 2256 /* Shortcut for GL functionality */ 2257 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2258 2259 /* Buffer creation. */ 2260 gl.genBuffers(1, &m_bo_xfb); 2261 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 2262 2263 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb); 2264 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 2265 2266 /* Calculating maximum size. */ 2267 glw::GLsizei size = static_cast<glw::GLsizei>( 2268 de::max(sizeof(glw::GLubyte), 2269 de::max(sizeof(glw::GLbyte), 2270 de::max(sizeof(glw::GLushort), 2271 de::max(sizeof(glw::GLshort), 2272 de::max(sizeof(glw::GLhalf), 2273 de::max(sizeof(glw::GLint), 2274 de::max(sizeof(glw::GLuint), 2275 de::max(sizeof(glw::GLfixed), 2276 de::max(sizeof(glw::GLfloat), 2277 sizeof(glw::GLdouble)))))))))) * 2278 4 /* maximum number of components */); 2279 2280 /* Preparing storage. */ 2281 gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, size, NULL, GL_MAP_READ_BIT); 2282 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed."); 2283 2284 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb); 2285 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed."); 2286 } 2287 2288 template <> 2289 bool AttributeFormatTest::compare<glw::GLfloat>(glw::GLfloat a, glw::GLfloat b) 2290 { 2291 if (de::abs(a - b) < 0.03125) 2292 { 2293 return true; 2294 } 2295 2296 return false; 2297 } 2298 2299 template <> 2300 bool AttributeFormatTest::compare<glw::GLdouble>(glw::GLdouble a, glw::GLdouble b) 2301 { 2302 if (de::abs(a - b) < 0.03125) 2303 { 2304 return true; 2305 } 2306 2307 return false; 2308 } 2309 2310 template <typename T> 2311 bool AttributeFormatTest::compare(T a, T b) 2312 { 2313 return (a == b); 2314 } 2315 2316 /** @brief Draw test program, fetch transform feedback results and compare them with expected values. 2317 * 2318 * @param [in] size Count of elements of the XFB vector is expected. 2319 * @param [in] normalized Normalized values are expected. 2320 * 2321 * @return True if expected results are equal to returned by XFB, false otherwise. 2322 */ 2323 template <typename T> 2324 bool AttributeFormatTest::DrawAndCheck(glw::GLint size, bool normalized) 2325 { 2326 /* Shortcut for GL functionality */ 2327 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2328 2329 /* Setup state. */ 2330 gl.useProgram(m_po); 2331 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed."); 2332 2333 gl.bindVertexArray(m_vao); 2334 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 2335 2336 /* Draw. */ 2337 gl.beginTransformFeedback(GL_POINTS); 2338 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed."); 2339 2340 gl.drawArrays(GL_POINTS, 0, 2); 2341 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed."); 2342 2343 gl.endTransformFeedback(); 2344 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed."); 2345 2346 /* Result query. */ 2347 T* result_ptr = (T*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 2348 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed."); 2349 2350 T result[8] = { 0 }; 2351 2352 for (glw::GLint i = 0; i < size * 2 /* two points */; ++i) 2353 { 2354 result[i] = result_ptr[i]; 2355 } 2356 2357 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 2358 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed."); 2359 2360 const glw::GLdouble scale = normalized ? (1.0 / 16.0) /* Floating point scalling factor. */ : 1.0; 2361 2362 const T array_data[16] = { (T)(0.0 * scale), (T)(1.0 * scale), (T)(2.0 * scale), (T)(3.0 * scale), 2363 (T)(4.0 * scale), (T)(5.0 * scale), (T)(6.0 * scale), (T)(7.0 * scale), 2364 (T)(8.0 * scale), (T)(9.0 * scale), (T)(10.0 * scale), (T)(11.0 * scale), 2365 (T)(12.0 * scale), (T)(13.0 * scale), (T)(14.0 * scale), (T)(15.0 * scale) }; 2366 2367 T reference[8] = { 0 }; 2368 2369 for (glw::GLint i = 0; i < 2 /* two points */; ++i) 2370 { 2371 for (glw::GLint j = 0; j < size /* size components */; ++j) 2372 { 2373 reference[i * size + j] = array_data[i * size * 2 + j] + array_data[i * size * 2 + j + size]; 2374 } 2375 } 2376 2377 /* Check result and return. */ 2378 for (glw::GLint i = 0; i < size * 2 /* two points */; ++i) 2379 { 2380 if (!AttributeFormatTest::compare<T>(reference[i], result[i])) 2381 { 2382 std::string reference_str = "[ "; 2383 2384 for (glw::GLint j = 0; j < size * 2 /* two points */; ++j) 2385 { 2386 std::stringstream ss; 2387 2388 ss << reference[j]; 2389 2390 reference_str.append(ss.str()); 2391 2392 if (j < size * 2 - 1 /* if it is not the last value */) 2393 { 2394 reference_str.append(", "); 2395 } 2396 else 2397 { 2398 reference_str.append(" ]"); 2399 } 2400 } 2401 2402 std::string result_str = "[ "; 2403 2404 for (glw::GLint j = 0; j < size * 2 /* two points */; ++j) 2405 { 2406 std::stringstream ss; 2407 2408 ss << result[j]; 2409 2410 result_str.append(ss.str()); 2411 2412 if (j < size * 2 - 1 /* if it is not the last value */) 2413 { 2414 result_str.append(", "); 2415 } 2416 else 2417 { 2418 result_str.append(" ]"); 2419 } 2420 } 2421 2422 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Result vector is equal to " 2423 << result_str.c_str() << ", but " << reference_str.c_str() 2424 << " was expected." << tcu::TestLog::EndMessage; 2425 2426 return false; 2427 } 2428 } 2429 2430 return true; 2431 } 2432 2433 /** @brief Clean GLSL program object. */ 2434 void AttributeFormatTest::CleanProgram() 2435 { 2436 /* Shortcut for GL functionality */ 2437 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2438 2439 gl.useProgram(0); 2440 2441 if (m_po) 2442 { 2443 gl.deleteProgram(m_po); 2444 2445 m_po = 0; 2446 } 2447 } 2448 2449 /** @brief Clean Vertex Array Object and related buffer. */ 2450 void AttributeFormatTest::CleanVAO() 2451 { 2452 /* Shortcut for GL functionality */ 2453 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2454 2455 if (m_vao) 2456 { 2457 gl.deleteVertexArrays(1, &m_vao); 2458 2459 m_vao = 0; 2460 } 2461 2462 if (m_bo_array) 2463 { 2464 gl.deleteBuffers(1, &m_bo_array); 2465 2466 m_bo_array = 0; 2467 } 2468 } 2469 2470 /** @brief Clean GL objects related to transform feedback. */ 2471 void AttributeFormatTest::CleanXFB() 2472 { 2473 /* Shortcut for GL functionality */ 2474 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2475 2476 if (m_bo_xfb) 2477 { 2478 gl.deleteBuffers(1, &m_bo_xfb); 2479 2480 m_bo_xfb = 0; 2481 } 2482 2483 while (gl.getError()) 2484 ; 2485 } 2486 2487 const glw::GLchar* AttributeFormatTest::s_vertex_shader_head = "#version 450\n" 2488 "\n"; 2489 2490 const glw::GLchar* AttributeFormatTest::s_vertex_shader_body = "\n" 2491 "void main()\n" 2492 "{\n" 2493 " gl_Position = vec4(1.0);\n" 2494 " result = a_0 + a_1;" 2495 "}\n"; 2496 2497 const glw::GLchar* AttributeFormatTest::s_vertex_shader_declaration[ATTRIBUTE_FORMAT_FUNCTION_COUNT] 2498 [4 /* sizes count */] = { { 2499 "in float a_0;" 2500 "in float a_1;" 2501 "out float result;\n", 2502 2503 "in vec2 a_0;" 2504 "in vec2 a_1;" 2505 "out vec2 result;\n", 2506 2507 "in vec3 a_0;" 2508 "in vec3 a_1;" 2509 "out vec3 result;\n", 2510 2511 "in vec4 a_0;" 2512 "in vec4 a_1;" 2513 "out vec4 result;\n", 2514 }, 2515 { 2516 "in double a_0;" 2517 "in double a_1;" 2518 "out double result;\n", 2519 2520 "in dvec2 a_0;" 2521 "in dvec2 a_1;" 2522 "out dvec2 result;\n", 2523 2524 "in dvec3 a_0;" 2525 "in dvec3 a_1;" 2526 "out dvec3 result;\n", 2527 2528 "in dvec4 a_0;" 2529 "in dvec4 a_1;" 2530 "out dvec4 result;\n", 2531 }, 2532 { 2533 "in int a_0;" 2534 "in int a_1;" 2535 "out int result;\n", 2536 2537 "in ivec2 a_0;" 2538 "in ivec2 a_1;" 2539 "out ivec2 result;\n", 2540 2541 "in ivec3 a_0;" 2542 "in ivec3 a_1;" 2543 "out ivec3 result;\n", 2544 2545 "in ivec4 a_0;" 2546 "in ivec4 a_1;" 2547 "out ivec4 result;\n", 2548 } }; 2549 2550 const glw::GLchar* AttributeFormatTest::s_fragment_shader = "#version 450\n" 2551 "\n" 2552 "out vec4 color;\n" 2553 "\n" 2554 "void main()\n" 2555 "{\n" 2556 " color = vec4(1.0);" 2557 "}\n"; 2558 2559 /******************************** Vertex Array Object Attribute Binding Test Implementation ********************************/ 2560 2561 /** @brief Attribute Binding Test constructor. 2562 * 2563 * @param [in] context OpenGL context. 2564 */ 2565 AttributeBindingTest::AttributeBindingTest(deqp::Context& context) 2566 : deqp::TestCase(context, "vertex_arrays_attribute_binding", "Vertex Array Objects Attribute Binding Test") 2567 , m_po(0) 2568 , m_vao(0) 2569 , m_bo_array(0) 2570 , m_bo_xfb(0) 2571 { 2572 /* Intentionally left blank. */ 2573 } 2574 2575 /** @brief Iterate Attribute Binding Test cases. 2576 * 2577 * @return Iteration result. 2578 */ 2579 tcu::TestNode::IterateResult AttributeBindingTest::iterate() 2580 { 2581 /* Shortcut for GL functionality. */ 2582 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2583 2584 /* Get context setup. */ 2585 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 2586 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 2587 2588 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 2589 { 2590 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 2591 2592 return STOP; 2593 } 2594 2595 /* Running tests. */ 2596 bool is_ok = true; 2597 bool is_error = false; 2598 2599 try 2600 { 2601 PrepareProgram(); 2602 is_ok &= PrepareVAO(); 2603 PrepareXFB(); 2604 is_ok &= DrawAndCheck(); 2605 } 2606 catch (...) 2607 { 2608 is_ok = false; 2609 is_error = true; 2610 } 2611 2612 /* Cleanup. */ 2613 Clean(); 2614 2615 /* Errors clean up. */ 2616 while (gl.getError()) 2617 ; 2618 2619 /* Result's setup. */ 2620 if (is_ok) 2621 { 2622 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2623 } 2624 else 2625 { 2626 if (is_error) 2627 { 2628 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 2629 } 2630 else 2631 { 2632 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2633 } 2634 } 2635 2636 return STOP; 2637 } 2638 2639 /** @brief Build test's GLSL program. 2640 * 2641 * @note The function may throw if unexpected error has occured. 2642 */ 2643 void AttributeBindingTest::PrepareProgram() 2644 { 2645 /* Shortcut for GL functionality */ 2646 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2647 2648 struct Shader 2649 { 2650 glw::GLchar const* const source; 2651 glw::GLenum const type; 2652 glw::GLuint id; 2653 } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } }; 2654 2655 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]); 2656 2657 try 2658 { 2659 /* Create program. */ 2660 m_po = gl.createProgram(); 2661 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed."); 2662 2663 /* Shader compilation. */ 2664 2665 for (glw::GLuint i = 0; i < shader_count; ++i) 2666 { 2667 if (DE_NULL != shader[i].source) 2668 { 2669 shader[i].id = gl.createShader(shader[i].type); 2670 2671 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed."); 2672 2673 gl.attachShader(m_po, shader[i].id); 2674 2675 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed."); 2676 2677 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL); 2678 2679 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed."); 2680 2681 gl.compileShader(shader[i].id); 2682 2683 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed."); 2684 2685 glw::GLint status = GL_FALSE; 2686 2687 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status); 2688 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 2689 2690 if (GL_FALSE == status) 2691 { 2692 glw::GLint log_size = 0; 2693 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size); 2694 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 2695 2696 glw::GLchar* log_text = new glw::GLchar[log_size]; 2697 2698 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]); 2699 2700 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n" 2701 << "Shader type: " << glu::getShaderTypeStr(shader[i].type) 2702 << "\n" 2703 << "Shader compilation error log:\n" 2704 << log_text << "\n" 2705 << "Shader source code:\n" 2706 << shader[i].source << "\n" 2707 << tcu::TestLog::EndMessage; 2708 2709 delete[] log_text; 2710 2711 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed."); 2712 2713 throw 0; 2714 } 2715 } 2716 } 2717 2718 /* Binding attributes. */ 2719 gl.bindAttribLocation(m_po, 0, "a_0"); 2720 gl.bindAttribLocation(m_po, 1, "a_1"); 2721 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindAttribLocation call failed."); 2722 2723 /* Transform Feedback setup. */ 2724 static const glw::GLchar* xfb_varying = "result"; 2725 gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS); 2726 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 2727 2728 /* Link. */ 2729 gl.linkProgram(m_po); 2730 2731 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 2732 2733 glw::GLint status = GL_FALSE; 2734 2735 gl.getProgramiv(m_po, GL_LINK_STATUS, &status); 2736 2737 if (GL_TRUE == status) 2738 { 2739 for (glw::GLuint i = 0; i < shader_count; ++i) 2740 { 2741 if (shader[i].id) 2742 { 2743 gl.detachShader(m_po, shader[i].id); 2744 2745 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed."); 2746 } 2747 } 2748 } 2749 else 2750 { 2751 glw::GLint log_size = 0; 2752 2753 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size); 2754 2755 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed."); 2756 2757 glw::GLchar* log_text = new glw::GLchar[log_size]; 2758 2759 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]); 2760 2761 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n" 2762 << log_text << "\n" 2763 << tcu::TestLog::EndMessage; 2764 2765 delete[] log_text; 2766 2767 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed."); 2768 2769 throw 0; 2770 } 2771 } 2772 catch (...) 2773 { 2774 if (m_po) 2775 { 2776 gl.deleteProgram(m_po); 2777 2778 m_po = 0; 2779 } 2780 } 2781 2782 for (glw::GLuint i = 0; i < shader_count; ++i) 2783 { 2784 if (0 != shader[i].id) 2785 { 2786 gl.deleteShader(shader[i].id); 2787 2788 shader[i].id = 0; 2789 } 2790 } 2791 2792 if (0 == m_po) 2793 { 2794 throw 0; 2795 } 2796 } 2797 2798 /** @brief Prepare vertex array object for the test. 2799 * 2800 * @return True if function VertexArrayAttribBinding does not generate any error. 2801 */ 2802 bool AttributeBindingTest::PrepareVAO() 2803 { 2804 /* Shortcut for GL functionality */ 2805 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2806 2807 /* VAO creation. */ 2808 gl.genVertexArrays(1, &m_vao); 2809 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed."); 2810 2811 gl.bindVertexArray(m_vao); 2812 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 2813 2814 /* Array buffer creation. */ 2815 glw::GLint array_data[2] = { 1, 0 }; 2816 2817 gl.genBuffers(1, &m_bo_array); 2818 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 2819 2820 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array); 2821 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 2822 2823 gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW); 2824 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed."); 2825 2826 gl.vertexAttribIPointer(0, 1, GL_INT, sizeof(glw::GLint) * 2, NULL); 2827 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed."); 2828 2829 gl.vertexAttribIPointer(1, 1, GL_INT, sizeof(glw::GLint) * 2, (glw::GLvoid*)((glw::GLint*)NULL + 1)); 2830 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed."); 2831 2832 gl.enableVertexAttribArray(0); 2833 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed."); 2834 2835 gl.enableVertexAttribArray(1); 2836 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed."); 2837 2838 gl.vertexArrayAttribBinding(m_vao, 0, 1); 2839 gl.vertexArrayAttribBinding(m_vao, 1, 0); 2840 2841 if (glw::GLenum error = gl.getError()) 2842 { 2843 m_context.getTestContext().getLog() << tcu::TestLog::Message 2844 << "VertexArrayAttribBinding has unexpectedly generated " 2845 << glu::getErrorStr(error) << "error. Test fails.\n" 2846 << tcu::TestLog::EndMessage; 2847 2848 return false; 2849 } 2850 2851 return true; 2852 } 2853 2854 /** @brief Prepare buffer object for test GLSL program transform feedback results. 2855 */ 2856 void AttributeBindingTest::PrepareXFB() 2857 { 2858 /* Shortcut for GL functionality */ 2859 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2860 2861 /* Buffer creation. */ 2862 gl.genBuffers(1, &m_bo_xfb); 2863 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 2864 2865 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb); 2866 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 2867 2868 /* Preparing storage. */ 2869 gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 2 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT); 2870 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed."); 2871 2872 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb); 2873 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed."); 2874 } 2875 2876 /** @brief Draw test program, fetch transform feedback results and compare them with expected values. 2877 * 2878 * @return True if expected results are equal to returned by XFB, false otherwise. 2879 */ 2880 bool AttributeBindingTest::DrawAndCheck() 2881 { 2882 /* Shortcut for GL functionality */ 2883 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2884 2885 /* Setup state. */ 2886 gl.useProgram(m_po); 2887 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed."); 2888 2889 gl.bindVertexArray(m_vao); 2890 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 2891 2892 gl.beginTransformFeedback(GL_POINTS); 2893 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed."); 2894 2895 /* Draw. */ 2896 gl.drawArrays(GL_POINTS, 0, 1); 2897 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed."); 2898 2899 /* State reset. */ 2900 gl.endTransformFeedback(); 2901 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed."); 2902 2903 /* Result query. */ 2904 glw::GLint* result_ptr = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 2905 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed."); 2906 2907 glw::GLint result[2] = { result_ptr[0], result_ptr[1] }; 2908 2909 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 2910 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed."); 2911 2912 /* Check result and return. */ 2913 if ((0 == result[0]) || (1 == result[1])) 2914 { 2915 return true; 2916 } 2917 2918 return false; 2919 } 2920 2921 /** @brief Clean GL objects. */ 2922 void AttributeBindingTest::Clean() 2923 { 2924 /* Shortcut for GL functionality */ 2925 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2926 2927 gl.useProgram(0); 2928 2929 if (m_po) 2930 { 2931 gl.deleteProgram(m_po); 2932 2933 m_po = 0; 2934 } 2935 2936 if (m_vao) 2937 { 2938 gl.deleteVertexArrays(1, &m_vao); 2939 2940 m_vao = 0; 2941 } 2942 2943 if (m_bo_array) 2944 { 2945 gl.deleteBuffers(1, &m_bo_array); 2946 2947 m_bo_array = 0; 2948 } 2949 2950 if (m_bo_xfb) 2951 { 2952 gl.deleteBuffers(1, &m_bo_xfb); 2953 2954 m_bo_xfb = 0; 2955 } 2956 2957 while (gl.getError()) 2958 ; 2959 } 2960 2961 const glw::GLchar AttributeBindingTest::s_vertex_shader[] = "#version 450\n" 2962 "\n" 2963 "in int a_0;\n" 2964 "in int a_1;\n" 2965 "out ivec2 result;\n" 2966 "\n" 2967 "void main()\n" 2968 "{\n" 2969 " gl_Position = vec4(1.0);\n" 2970 " result[0] = a_0;\n" 2971 " result[1] = a_1;\n" 2972 "}\n"; 2973 2974 const glw::GLchar AttributeBindingTest::s_fragment_shader[] = "#version 450\n" 2975 "\n" 2976 "out vec4 color;\n" 2977 "\n" 2978 "void main()\n" 2979 "{\n" 2980 " color = vec4(1.0);" 2981 "}\n"; 2982 2983 /******************************** Vertex Array Attribute Binding Divisor Test Implementation ********************************/ 2984 2985 /** @brief Vertex Array Attribute Binding Divisor Test constructor. 2986 * 2987 * @param [in] context OpenGL context. 2988 */ 2989 AttributeBindingDivisorTest::AttributeBindingDivisorTest(deqp::Context& context) 2990 : deqp::TestCase(context, "vertex_arrays_attribute_binding_divisor", "Vertex Array Attribute Binding Divisor Test") 2991 , m_po(0) 2992 , m_vao(0) 2993 , m_bo_array(0) 2994 , m_bo_xfb(0) 2995 { 2996 /* Intentionally left blank. */ 2997 } 2998 2999 /** @brief Iterate Vertex Array Attribute Binding Divisor Test cases. 3000 * 3001 * @return Iteration result. 3002 */ 3003 tcu::TestNode::IterateResult AttributeBindingDivisorTest::iterate() 3004 { 3005 /* Shortcut for GL functionality. */ 3006 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3007 3008 /* Get context setup. */ 3009 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 3010 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 3011 3012 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 3013 { 3014 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 3015 3016 return STOP; 3017 } 3018 3019 /* Running tests. */ 3020 bool is_ok = true; 3021 bool is_error = false; 3022 3023 try 3024 { 3025 PrepareProgram(); 3026 PrepareVAO(); 3027 PrepareXFB(); 3028 3029 { 3030 glw::GLint reference[] = { 0, 2 }; 3031 is_ok = SetDivisor(2); 3032 Draw(1, 2); 3033 is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference, 3034 "Draw of 1 point with 2 instances with 2 divisor has failed."); 3035 } 3036 3037 { 3038 glw::GLint reference[] = { 0, 0, 1, 1 }; 3039 is_ok = SetDivisor(1); 3040 Draw(2, 2); 3041 is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference, 3042 "Draw of 2 points with 2 instances with 1 divisor has failed."); 3043 } 3044 3045 { 3046 glw::GLint reference[] = { 0, 1, 2, 3 }; 3047 is_ok = SetDivisor(1); 3048 Draw(1, 4); 3049 is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference, 3050 "Draw of 1 point with 4 instances with 1 divisor has failed."); 3051 } 3052 3053 { 3054 glw::GLint reference[] = { 0, 1, 0, 1 }; 3055 is_ok = SetDivisor(0); 3056 Draw(2, 2); 3057 is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference, 3058 "Draw of 2 points with 2 instances with 0 divisor has failed."); 3059 } 3060 3061 { 3062 glw::GLint reference[] = { 0, 1, 2, 3 }; 3063 is_ok = SetDivisor(0); 3064 Draw(4, 1); 3065 is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference, 3066 "Draw of 4 points with 1 instance with 0 divisor has failed."); 3067 } 3068 } 3069 catch (...) 3070 { 3071 is_ok = false; 3072 is_error = true; 3073 } 3074 3075 /* Cleanup. */ 3076 Clean(); 3077 3078 /* Errors clean up. */ 3079 while (gl.getError()) 3080 ; 3081 3082 /* Result's setup. */ 3083 if (is_ok) 3084 { 3085 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3086 } 3087 else 3088 { 3089 if (is_error) 3090 { 3091 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 3092 } 3093 else 3094 { 3095 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3096 } 3097 } 3098 3099 return STOP; 3100 } 3101 3102 /** @brief Build test's GLSL program. 3103 * 3104 * @note The function may throw if unexpected error has occured. 3105 */ 3106 void AttributeBindingDivisorTest::PrepareProgram() 3107 { 3108 /* Shortcut for GL functionality */ 3109 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3110 3111 struct Shader 3112 { 3113 glw::GLchar const* const source; 3114 glw::GLenum const type; 3115 glw::GLuint id; 3116 } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } }; 3117 3118 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]); 3119 3120 try 3121 { 3122 /* Create program. */ 3123 m_po = gl.createProgram(); 3124 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed."); 3125 3126 /* Shader compilation. */ 3127 3128 for (glw::GLuint i = 0; i < shader_count; ++i) 3129 { 3130 if (DE_NULL != shader[i].source) 3131 { 3132 shader[i].id = gl.createShader(shader[i].type); 3133 3134 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed."); 3135 3136 gl.attachShader(m_po, shader[i].id); 3137 3138 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed."); 3139 3140 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL); 3141 3142 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed."); 3143 3144 gl.compileShader(shader[i].id); 3145 3146 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed."); 3147 3148 glw::GLint status = GL_FALSE; 3149 3150 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status); 3151 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 3152 3153 if (GL_FALSE == status) 3154 { 3155 glw::GLint log_size = 0; 3156 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size); 3157 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); 3158 3159 glw::GLchar* log_text = new glw::GLchar[log_size]; 3160 3161 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]); 3162 3163 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n" 3164 << "Shader type: " << glu::getShaderTypeStr(shader[i].type) 3165 << "\n" 3166 << "Shader compilation error log:\n" 3167 << log_text << "\n" 3168 << "Shader source code:\n" 3169 << shader[i].source << "\n" 3170 << tcu::TestLog::EndMessage; 3171 3172 delete[] log_text; 3173 3174 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed."); 3175 3176 throw 0; 3177 } 3178 } 3179 } 3180 3181 /* Transform Feedback setup. */ 3182 static const glw::GLchar* xfb_varying = "result"; 3183 3184 gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS); 3185 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 3186 3187 /* Link. */ 3188 gl.linkProgram(m_po); 3189 3190 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); 3191 3192 glw::GLint status = GL_FALSE; 3193 3194 gl.getProgramiv(m_po, GL_LINK_STATUS, &status); 3195 3196 if (GL_TRUE == status) 3197 { 3198 for (glw::GLuint i = 0; i < shader_count; ++i) 3199 { 3200 if (shader[i].id) 3201 { 3202 gl.detachShader(m_po, shader[i].id); 3203 3204 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed."); 3205 } 3206 } 3207 } 3208 else 3209 { 3210 glw::GLint log_size = 0; 3211 3212 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size); 3213 3214 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed."); 3215 3216 glw::GLchar* log_text = new glw::GLchar[log_size]; 3217 3218 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]); 3219 3220 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n" 3221 << log_text << "\n" 3222 << tcu::TestLog::EndMessage; 3223 3224 delete[] log_text; 3225 3226 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed."); 3227 3228 throw 0; 3229 } 3230 } 3231 catch (...) 3232 { 3233 if (m_po) 3234 { 3235 gl.deleteProgram(m_po); 3236 3237 m_po = 0; 3238 } 3239 } 3240 3241 for (glw::GLuint i = 0; i < shader_count; ++i) 3242 { 3243 if (0 != shader[i].id) 3244 { 3245 gl.deleteShader(shader[i].id); 3246 3247 shader[i].id = 0; 3248 } 3249 } 3250 3251 if (m_po) 3252 { 3253 gl.useProgram(m_po); 3254 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed."); 3255 } 3256 3257 if (0 == m_po) 3258 { 3259 throw 0; 3260 } 3261 } 3262 3263 /** @brief Prepare vertex array object for the test. 3264 */ 3265 void AttributeBindingDivisorTest::PrepareVAO() 3266 { 3267 /* Shortcut for GL functionality */ 3268 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3269 3270 /* VAO creation. */ 3271 gl.genVertexArrays(1, &m_vao); 3272 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed."); 3273 3274 gl.bindVertexArray(m_vao); 3275 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 3276 3277 /* Array buffer 0 creation. */ 3278 glw::GLint array_data[4] = { 0, 1, 2, 3 }; 3279 3280 gl.genBuffers(1, &m_bo_array); 3281 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 3282 3283 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array); 3284 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 3285 3286 gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW); 3287 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed."); 3288 3289 gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a"), 0); 3290 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed."); 3291 3292 gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a"), 1, GL_INT, 0); 3293 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIFormat call failed."); 3294 3295 gl.bindVertexBuffer(0, m_bo_array, 0, sizeof(glw::GLint)); 3296 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexBuffer call failed."); 3297 3298 gl.enableVertexAttribArray(gl.getAttribLocation(m_po, "a")); 3299 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed."); 3300 } 3301 3302 /** @brief Prepare buffer object for test GLSL program transform feedback results. 3303 */ 3304 void AttributeBindingDivisorTest::PrepareXFB() 3305 { 3306 /* Shortcut for GL functionality */ 3307 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3308 3309 /* Buffer creation. */ 3310 gl.genBuffers(1, &m_bo_xfb); 3311 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed."); 3312 3313 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb); 3314 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 3315 3316 /* Preparing storage. */ 3317 gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 4 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT); 3318 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed."); 3319 3320 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb); 3321 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed."); 3322 } 3323 3324 /** @brief Draw number of points and number of instances with XFB environment. 3325 * 3326 * @param [in] number_of_points Number of points to be drawn. 3327 * @param [in] number_of_instances Number of instances to be drawn. 3328 */ 3329 void AttributeBindingDivisorTest::Draw(glw::GLuint number_of_points, glw::GLuint number_of_instances) 3330 { 3331 /* Shortcut for GL functionality */ 3332 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3333 3334 /* Setup state. */ 3335 gl.beginTransformFeedback(GL_POINTS); 3336 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed."); 3337 3338 /* Draw. */ 3339 gl.drawArraysInstanced(GL_POINTS, 0, number_of_points, number_of_instances); 3340 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArraysInstanced call failed."); 3341 3342 /* State reset. */ 3343 gl.endTransformFeedback(); 3344 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed."); 3345 } 3346 3347 /** @brief Call VertexArrayBindingDivisor on m_vao object and check errors. 3348 * 3349 * @param [in] divisor Divisor to be passed. 3350 * 3351 * @return True if VertexArrayBindingDivisor doe not generate any error, false otherwise. 3352 */ 3353 bool AttributeBindingDivisorTest::SetDivisor(glw::GLuint divisor) 3354 { 3355 /* Shortcut for GL functionality */ 3356 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3357 3358 /* Setup. */ 3359 gl.vertexArrayBindingDivisor(m_vao, 0, divisor); 3360 3361 /* Checking for errors (this is tested function so it fail the test if there is error). */ 3362 if (glw::GLenum error = gl.getError()) 3363 { 3364 m_context.getTestContext().getLog() 3365 << tcu::TestLog::Message << "VertexArrayBindingDivisor unexpectedl generated " << glu::getErrorStr(error) 3366 << " error when called with divisor" << divisor << ". " << tcu::TestLog::EndMessage; 3367 3368 return false; 3369 } 3370 3371 return true; 3372 } 3373 3374 /** @brief Check transform feedback results and log. 3375 * 3376 * @param [in] count Number of results to be checked. 3377 * @param [in] expected Expected results. 3378 * @param [in] log_message Message to be logged if expected values are not equal to queried. 3379 * 3380 * @return True if expected values are equal to queried, false otherwise. 3381 */ 3382 bool AttributeBindingDivisorTest::CheckXFB(const glw::GLuint count, const glw::GLint expected[], 3383 const glw::GLchar* log_message) 3384 { 3385 /* Shortcut for GL functionality */ 3386 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3387 3388 /* Result setup */ 3389 bool is_ok = true; 3390 3391 /* Result query. */ 3392 glw::GLint* result = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 3393 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed."); 3394 3395 /* Check result and return. */ 3396 for (glw::GLuint i = 0; i < count; ++i) 3397 { 3398 if (expected[i] != result[i]) 3399 { 3400 std::string expected_str = "["; 3401 std::string result_str = "["; 3402 3403 for (glw::GLuint j = 0; j < count; ++j) 3404 { 3405 expected_str.append(Utilities::itoa((glw::GLuint)expected[j])); 3406 result_str.append(Utilities::itoa((glw::GLuint)result[j])); 3407 3408 if (j < count - 1) 3409 { 3410 expected_str.append(", "); 3411 result_str.append(", "); 3412 } 3413 else 3414 { 3415 expected_str.append("]"); 3416 result_str.append("]"); 3417 } 3418 } 3419 3420 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Result is " << result_str << ", but " 3421 << expected_str << " was expected. " << log_message 3422 << tcu::TestLog::EndMessage; 3423 3424 is_ok = false; 3425 break; 3426 } 3427 } 3428 3429 /* Unmaping GL buffer. */ 3430 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 3431 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed."); 3432 3433 return is_ok; 3434 } 3435 3436 /** @brief Clean GL objects. */ 3437 void AttributeBindingDivisorTest::Clean() 3438 { 3439 /* Shortcut for GL functionality */ 3440 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3441 3442 gl.useProgram(0); 3443 3444 if (m_po) 3445 { 3446 gl.deleteProgram(m_po); 3447 3448 m_po = 0; 3449 } 3450 3451 if (m_vao) 3452 { 3453 gl.deleteVertexArrays(1, &m_vao); 3454 3455 m_vao = 0; 3456 } 3457 3458 if (m_bo_array) 3459 { 3460 gl.deleteBuffers(1, &m_bo_array); 3461 3462 m_bo_array = 0; 3463 } 3464 3465 if (m_bo_xfb) 3466 { 3467 gl.deleteBuffers(1, &m_bo_xfb); 3468 3469 m_bo_xfb = 0; 3470 } 3471 3472 while (gl.getError()) 3473 ; 3474 } 3475 3476 const glw::GLchar AttributeBindingDivisorTest::s_vertex_shader[] = "#version 450\n" 3477 "\n" 3478 "in int a;\n" 3479 "out int result;\n" 3480 "\n" 3481 "void main()\n" 3482 "{\n" 3483 " gl_Position = vec4(1.0);\n" 3484 " result = a;" 3485 "}\n"; 3486 3487 const glw::GLchar AttributeBindingDivisorTest::s_fragment_shader[] = "#version 450\n" 3488 "\n" 3489 "out vec4 color;\n" 3490 "\n" 3491 "void main()\n" 3492 "{\n" 3493 " color = vec4(1.0);" 3494 "}\n"; 3495 3496 /******************************** Get Vertex Array Test Implementation ********************************/ 3497 3498 /** @brief Get Vertex Array Test constructor. 3499 * 3500 * @param [in] context OpenGL context. 3501 */ 3502 GetVertexArrayTest::GetVertexArrayTest(deqp::Context& context) 3503 : deqp::TestCase(context, "vertex_arrays_get_vertex_array", "Get Vertex Array Test") 3504 { 3505 /* Intentionally left blank. */ 3506 } 3507 3508 /** @brief Iterate Vertex Array Attribute Binding Divisor Test cases. 3509 * 3510 * @return Iteration result. 3511 */ 3512 tcu::TestNode::IterateResult GetVertexArrayTest::iterate() 3513 { 3514 /* Shortcut for GL functionality. */ 3515 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3516 3517 /* Get context setup. */ 3518 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 3519 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 3520 3521 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 3522 { 3523 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 3524 3525 return STOP; 3526 } 3527 3528 /* Running tests. */ 3529 bool is_ok = true; 3530 bool is_error = false; 3531 3532 /* Test objects. */ 3533 glw::GLuint vao = 0; 3534 glw::GLuint bo = 0; 3535 3536 try 3537 { 3538 gl.genVertexArrays(1, &vao); 3539 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed."); 3540 3541 gl.bindVertexArray(vao); 3542 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 3543 3544 gl.genBuffers(1, &bo); 3545 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed."); 3546 3547 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo); 3548 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 3549 3550 glw::GLint result = 0; 3551 gl.getVertexArrayiv(vao, GL_ELEMENT_ARRAY_BUFFER_BINDING, &result); 3552 3553 if (glw::GLenum error = gl.getError()) 3554 { 3555 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayiv unexpectedly generated " 3556 << glu::getErrorStr(error) << "error. Test fails." 3557 << tcu::TestLog::EndMessage; 3558 3559 is_ok = false; 3560 } 3561 3562 if ((glw::GLuint)result != bo) 3563 { 3564 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayiv was expected to return " 3565 << bo << ", but " << result << " was observed. Test fails." 3566 << tcu::TestLog::EndMessage; 3567 3568 is_ok = false; 3569 } 3570 } 3571 catch (...) 3572 { 3573 is_ok = false; 3574 is_error = true; 3575 } 3576 3577 /* Cleanup. */ 3578 if (vao) 3579 { 3580 gl.deleteVertexArrays(1, &vao); 3581 } 3582 3583 if (bo) 3584 { 3585 gl.deleteBuffers(1, &bo); 3586 } 3587 3588 /* Errors clean up. */ 3589 while (gl.getError()) 3590 ; 3591 3592 /* Result's setup. */ 3593 if (is_ok) 3594 { 3595 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3596 } 3597 else 3598 { 3599 if (is_error) 3600 { 3601 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 3602 } 3603 else 3604 { 3605 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3606 } 3607 } 3608 3609 return STOP; 3610 } 3611 3612 /******************************** Get Vertex Array Test Indexed Implementation ********************************/ 3613 3614 /** @brief Get Vertex Array Indexed Test constructor. 3615 * 3616 * @param [in] context OpenGL context. 3617 */ 3618 GetVertexArrayIndexedTest::GetVertexArrayIndexedTest(deqp::Context& context) 3619 : deqp::TestCase(context, "vertex_arrays_get_vertex_array_indexed", "Get Vertex Array Indexed Test"), m_vao(0) 3620 { 3621 m_bo[0] = 0; 3622 m_bo[1] = 0; 3623 m_bo[2] = 0; 3624 m_bo[3] = 0; 3625 } 3626 3627 /** @brief Iterate Vertex Array Attribute Binding Divisor Test cases. 3628 * 3629 * @return Iteration result. 3630 */ 3631 tcu::TestNode::IterateResult GetVertexArrayIndexedTest::iterate() 3632 { 3633 /* Shortcut for GL functionality. */ 3634 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3635 3636 /* Get context setup. */ 3637 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 3638 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 3639 3640 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 3641 { 3642 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 3643 3644 return STOP; 3645 } 3646 3647 /* Running tests. */ 3648 bool is_ok = true; 3649 bool is_error = false; 3650 3651 try 3652 { 3653 PrepareVAO(); 3654 3655 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 0, GL_TRUE); 3656 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 1, GL_TRUE); 3657 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 2, GL_TRUE); 3658 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 3, GL_TRUE); 3659 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 5, GL_FALSE); 3660 3661 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 0, 0); 3662 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 1, 2); 3663 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 2, 0); 3664 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 3, 8); 3665 3666 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 0, GL_BYTE); 3667 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 1, GL_SHORT); 3668 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 2, GL_FLOAT); 3669 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 3, GL_UNSIGNED_INT_2_10_10_10_REV); 3670 3671 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 0, GL_TRUE); 3672 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 1, GL_FALSE); 3673 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 2, GL_FALSE); 3674 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 3, GL_FALSE); 3675 3676 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 0, GL_FALSE); 3677 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 1, GL_TRUE); 3678 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 2, GL_FALSE); 3679 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 3, GL_FALSE); 3680 3681 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 0, 3); 3682 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 1, 2); 3683 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 2, 1); 3684 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 3, 0); 3685 3686 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 0, GL_FALSE); 3687 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 1, GL_FALSE); 3688 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 2, GL_FALSE); 3689 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 3, GL_FALSE); 3690 3691 is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 0, 0); 3692 is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 1, 0); 3693 is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 2, 4); 3694 is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 3, 0); 3695 3696 is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 0, 0); 3697 is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 1, 2); 3698 is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 2, 8); 3699 is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 3, 4); 3700 } 3701 catch (...) 3702 { 3703 is_ok = false; 3704 is_error = true; 3705 } 3706 3707 /* Cleanup. */ 3708 if (m_vao) 3709 { 3710 gl.deleteVertexArrays(1, &m_vao); 3711 3712 m_vao = 0; 3713 } 3714 3715 if (m_bo[0] || m_bo[1] || m_bo[2] || m_bo[3]) 3716 { 3717 gl.deleteBuffers(4, m_bo); 3718 3719 m_bo[0] = 0; 3720 m_bo[1] = 0; 3721 m_bo[2] = 0; 3722 m_bo[3] = 0; 3723 } 3724 3725 /* Errors clean up. */ 3726 while (gl.getError()) 3727 ; 3728 3729 /* Result's setup. */ 3730 if (is_ok) 3731 { 3732 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3733 } 3734 else 3735 { 3736 if (is_error) 3737 { 3738 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 3739 } 3740 else 3741 { 3742 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3743 } 3744 } 3745 3746 return STOP; 3747 } 3748 3749 /** @brief Prepare vertex array object for the test. 3750 */ 3751 void GetVertexArrayIndexedTest::PrepareVAO() 3752 { 3753 /* Shortcut for GL functionality. */ 3754 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3755 3756 gl.genVertexArrays(1, &m_vao); 3757 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed."); 3758 3759 gl.bindVertexArray(m_vao); 3760 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed."); 3761 3762 gl.genBuffers(4, m_bo); 3763 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed."); 3764 3765 /* Attribute 0. */ 3766 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[0]); 3767 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 3768 3769 gl.vertexAttribPointer(0, 1, GL_BYTE, GL_TRUE, 0, NULL); 3770 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed."); 3771 3772 gl.enableVertexAttribArray(0); 3773 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed."); 3774 3775 gl.vertexAttribDivisor(0, 3); 3776 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed."); 3777 3778 /* Attribute 1. */ 3779 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[1]); 3780 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 3781 3782 gl.vertexAttribIPointer(1, 2, GL_SHORT, 2, ((glw::GLchar*)NULL + 2)); 3783 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed."); 3784 3785 gl.enableVertexAttribArray(1); 3786 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed."); 3787 3788 gl.vertexAttribDivisor(1, 2); 3789 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed."); 3790 3791 /* Attribute 2. */ 3792 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[2]); 3793 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 3794 3795 gl.vertexAttribBinding(2, 2); 3796 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed."); 3797 3798 gl.vertexAttribFormat(2, 3, GL_FLOAT, GL_FALSE, 4); 3799 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIFormat call failed."); 3800 3801 gl.bindVertexBuffer(2, m_bo[2], 8, 0); 3802 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexBuffer call failed."); 3803 3804 gl.enableVertexAttribArray(2); 3805 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed."); 3806 3807 gl.vertexAttribDivisor(2, 1); 3808 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed."); 3809 3810 /* Attribute 3. */ 3811 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[3]); 3812 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed."); 3813 3814 gl.vertexAttribPointer(3, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 8, ((glw::GLchar*)NULL + 4)); 3815 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed."); 3816 3817 gl.enableVertexAttribArray(3); 3818 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed."); 3819 3820 gl.vertexAttribDivisor(3, 0); 3821 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed."); 3822 } 3823 3824 /** @brief Compare value queried using GetVertexArrayIndexediv with expected value and log. 3825 * 3826 * @param [in] pname Parameter to be queried. 3827 * @param [in] index Index to be queried. 3828 * @param [in] expected Expected error. 3829 * 3830 * @return True if value is equal to expected, false otherwise. 3831 */ 3832 bool GetVertexArrayIndexedTest::Check(const glw::GLenum pname, const glw::GLuint index, const glw::GLint expected) 3833 { 3834 /* Shortcut for GL functionality. */ 3835 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3836 3837 glw::GLint result = 0; 3838 3839 gl.getVertexArrayIndexediv(m_vao, index, pname, &result); 3840 3841 if (glw::GLenum error = gl.getError()) 3842 { 3843 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayIndexediv called with index " 3844 << index << ", with pname" << glu::getVertexAttribParameterNameStr(pname) 3845 << " unexpectedly generated " << glu::getErrorStr(error) 3846 << "error. Test fails." << tcu::TestLog::EndMessage; 3847 3848 return false; 3849 } 3850 3851 if (result != expected) 3852 { 3853 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayIndexediv called with index " 3854 << index << " and with pname" << glu::getVertexAttribParameterNameStr(pname) 3855 << " returned " << result << ", but " << expected 3856 << " was expected. Test fails." << tcu::TestLog::EndMessage; 3857 3858 return false; 3859 } 3860 3861 return true; 3862 } 3863 3864 /** @brief Compare value queried using GetVertexArrayIndexed64iv with expected value and log. 3865 * 3866 * @param [in] pname Parameter to be queried. 3867 * @param [in] index Index to be queried. 3868 * @param [in] expected Expected error. 3869 * 3870 * @return True if value is equal to expected, false otherwise. 3871 */ 3872 bool GetVertexArrayIndexedTest::Check64(const glw::GLenum pname, const glw::GLuint index, const glw::GLint64 expected) 3873 { 3874 /* Shortcut for GL functionality. */ 3875 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3876 3877 glw::GLint64 result = 0; 3878 3879 gl.getVertexArrayIndexed64iv(m_vao, index, pname, &result); 3880 3881 if (glw::GLenum error = gl.getError()) 3882 { 3883 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayIndexed64iv called with index " 3884 << index << ", with pname" << glu::getVertexAttribParameterNameStr(pname) 3885 << " unexpectedly generated " << glu::getErrorStr(error) 3886 << "error. Test fails." << tcu::TestLog::EndMessage; 3887 3888 return false; 3889 } 3890 3891 if (result != expected) 3892 { 3893 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayIndexed64iv called with index " 3894 << index << " and with pname" << glu::getVertexAttribParameterNameStr(pname) 3895 << " returned " << result << ", but " << expected 3896 << " was expected. Test fails." << tcu::TestLog::EndMessage; 3897 3898 return false; 3899 } 3900 3901 return true; 3902 } 3903 3904 /******************************** Defaults Test Implementation ********************************/ 3905 3906 /** @brief Defaults Test constructor. 3907 * 3908 * @param [in] context OpenGL context. 3909 */ 3910 DefaultsTest::DefaultsTest(deqp::Context& context) 3911 : deqp::TestCase(context, "vertex_arrays_defaults", "Defaults Test"), m_vao(0) 3912 { 3913 } 3914 3915 /** @brief Iterate Defaults Test cases. 3916 * 3917 * @return Iteration result. 3918 */ 3919 tcu::TestNode::IterateResult DefaultsTest::iterate() 3920 { 3921 /* Shortcut for GL functionality. */ 3922 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3923 3924 /* Get context setup. */ 3925 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 3926 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 3927 3928 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 3929 { 3930 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 3931 3932 return STOP; 3933 } 3934 3935 /* Running tests. */ 3936 bool is_ok = true; 3937 bool is_error = false; 3938 3939 /* Test objects. */ 3940 glw::GLint max_attributes = 8; 3941 3942 try 3943 { 3944 /* Query limits. */ 3945 gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_attributes); 3946 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed."); 3947 3948 /* Prepare default Vertex Array Object. */ 3949 PrepareVAO(); 3950 3951 /* Check default values per attribute index. */ 3952 for (glw::GLint i = 0; i < max_attributes; ++i) 3953 { 3954 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_ENABLED, i, GL_FALSE); 3955 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_SIZE, i, 4); 3956 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_STRIDE, i, 0); 3957 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_TYPE, i, GL_FLOAT); 3958 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, i, GL_FALSE); 3959 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_INTEGER, i, GL_FALSE); 3960 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, i, 0); 3961 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_LONG, i, GL_FALSE); 3962 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, i, 0); 3963 is_ok &= CheckIndexed64(GL_VERTEX_BINDING_OFFSET, i, 0); 3964 } 3965 3966 /* Check default values per vertex array object. */ 3967 is_ok &= Check(GL_ELEMENT_ARRAY_BUFFER_BINDING, 0); 3968 } 3969 catch (...) 3970 { 3971 is_ok = false; 3972 is_error = true; 3973 } 3974 3975 /* Cleanup. */ 3976 if (m_vao) 3977 { 3978 gl.deleteVertexArrays(1, &m_vao); 3979 3980 m_vao = 0; 3981 } 3982 3983 /* Errors clean up. */ 3984 while (gl.getError()) 3985 ; 3986 3987 /* Result's setup. */ 3988 if (is_ok) 3989 { 3990 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3991 } 3992 else 3993 { 3994 if (is_error) 3995 { 3996 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 3997 } 3998 else 3999 { 4000 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 4001 } 4002 } 4003 4004 return STOP; 4005 } 4006 4007 /** @brief Prepare vertex array object for the test. 4008 */ 4009 void DefaultsTest::PrepareVAO() 4010 { 4011 /* Shortcut for GL functionality. */ 4012 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4013 4014 gl.createVertexArrays(1, &m_vao); 4015 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed."); 4016 } 4017 4018 /** @brief Compare value queried using GetVertexArrayiv with expected value and log. 4019 * 4020 * @param [in] pname Parameter to be queried. 4021 * @param [in] expected Expected error. 4022 * 4023 * @return True if value is equal to expected, false otherwise. 4024 */ 4025 bool DefaultsTest::Check(const glw::GLenum pname, const glw::GLint expected) 4026 { 4027 /* Shortcut for GL functionality. */ 4028 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4029 4030 glw::GLint result = 0; 4031 4032 gl.getVertexArrayiv(m_vao, pname, &result); 4033 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetVertexArrayiv call failed."); 4034 4035 if (result != expected) 4036 { 4037 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Default Vertex Array Object has parameter " 4038 << glu::getVertexAttribParameterNameStr(pname) << " equal to " << result 4039 << ", but " << expected << " was expected. Test fails." 4040 << tcu::TestLog::EndMessage; 4041 4042 return false; 4043 } 4044 4045 return true; 4046 } 4047 4048 /** @brief Compare value queried using GetVertexArrayIndexediv with expected value and log. 4049 * 4050 * @param [in] pname Parameter to be queried. 4051 * @param [in] index Index to be queried. 4052 * @param [in] expected Expected error. 4053 * 4054 * @return True if value is equal to expected, false otherwise. 4055 */ 4056 bool DefaultsTest::CheckIndexed(const glw::GLenum pname, const glw::GLuint index, const glw::GLint expected) 4057 { 4058 /* Shortcut for GL functionality. */ 4059 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4060 4061 glw::GLint result = 0; 4062 4063 gl.getVertexArrayIndexediv(m_vao, index, pname, &result); 4064 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetVertexArrayIndexediv call failed."); 4065 4066 if (result != expected) 4067 { 4068 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Default Vertex Array Object at index " << index 4069 << " has parameter " << glu::getVertexAttribParameterNameStr(pname) 4070 << " equal to " << result << ", but " << expected 4071 << " was expected. Test fails." << tcu::TestLog::EndMessage; 4072 4073 return false; 4074 } 4075 4076 return true; 4077 } 4078 4079 /** @brief Compare value queried using GetVertexArrayIndexed64iv with expected value and log. 4080 * 4081 * @param [in] pname Parameter to be queried. 4082 * @param [in] index Index to be queried. 4083 * @param [in] expected Expected error. 4084 * 4085 * @return True if value is equal to expected, false otherwise. 4086 */ 4087 bool DefaultsTest::CheckIndexed64(const glw::GLenum pname, const glw::GLuint index, const glw::GLint64 expected) 4088 { 4089 /* Shortcut for GL functionality. */ 4090 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4091 4092 glw::GLint64 result = 0; 4093 4094 gl.getVertexArrayIndexed64iv(m_vao, index, pname, &result); 4095 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetVertexArrayIndexed64iv call failed."); 4096 4097 if (result != expected) 4098 { 4099 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Default Vertex Array Object at index " << index 4100 << " has parameter " << glu::getVertexAttribParameterNameStr(pname) 4101 << " equal to " << result << ", but " << expected 4102 << " was expected. Test fails." << tcu::TestLog::EndMessage; 4103 4104 return false; 4105 } 4106 4107 return true; 4108 } 4109 4110 /******************************** Creation Error Test Implementation ********************************/ 4111 4112 /** @brief Creation Error Test constructor. 4113 * 4114 * @param [in] context OpenGL context. 4115 */ 4116 CreationErrorTest::CreationErrorTest(deqp::Context& context) 4117 : deqp::TestCase(context, "vertex_arrays_creation_error", "Creation Error Test") 4118 { 4119 } 4120 4121 /** @brief Iterate Creation Error Test cases. 4122 * 4123 * @return Iteration result. 4124 */ 4125 tcu::TestNode::IterateResult CreationErrorTest::iterate() 4126 { 4127 /* Shortcut for GL functionality. */ 4128 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4129 4130 /* Get context setup. */ 4131 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 4132 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 4133 4134 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 4135 { 4136 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 4137 4138 return STOP; 4139 } 4140 4141 /* Running tests. */ 4142 bool is_ok = true; 4143 bool is_error = false; 4144 4145 try 4146 { 4147 glw::GLuint negative_vao = 0; 4148 4149 gl.createVertexArrays(-1, &negative_vao); 4150 4151 is_ok = CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated if n is negative."); 4152 } 4153 catch (...) 4154 { 4155 is_ok = false; 4156 is_error = true; 4157 } 4158 4159 /* Errors clean up. */ 4160 while (gl.getError()) 4161 ; 4162 4163 /* Result's setup. */ 4164 if (is_ok) 4165 { 4166 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 4167 } 4168 else 4169 { 4170 if (is_error) 4171 { 4172 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 4173 } 4174 else 4175 { 4176 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 4177 } 4178 } 4179 4180 return STOP; 4181 } 4182 4183 /** @brief Compare error returned by GL with expected value and log. 4184 * 4185 * @param [in] expected Expected error. 4186 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one. 4187 * 4188 * @return True if GL error is equal to expected, false otherwise. 4189 */ 4190 bool CreationErrorTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message) 4191 { 4192 /* Shortcut for GL functionality. */ 4193 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4194 4195 glw::GLenum error = 0; 4196 4197 if (expected != (error = gl.getError())) 4198 { 4199 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error) 4200 << "was observed instead." << tcu::TestLog::EndMessage; 4201 4202 return false; 4203 } 4204 4205 return true; 4206 } 4207 4208 /******************************** Enable Disable Attribute Errors Test Implementation ********************************/ 4209 4210 /** @brief Enable Disable Attribute Errors Test constructor. 4211 * 4212 * @param [in] context OpenGL context. 4213 */ 4214 EnableDisableAttributeErrorsTest::EnableDisableAttributeErrorsTest(deqp::Context& context) 4215 : deqp::TestCase(context, "vertex_arrays_enable_disable_attribute_errors", "Enable Disable Attribute Errors Test") 4216 { 4217 } 4218 4219 /** @brief Enable Disable Attribute Errors Test cases. 4220 * 4221 * @return Iteration result. 4222 */ 4223 tcu::TestNode::IterateResult EnableDisableAttributeErrorsTest::iterate() 4224 { 4225 /* Shortcut for GL functionality. */ 4226 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4227 4228 /* Get context setup. */ 4229 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 4230 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 4231 4232 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 4233 { 4234 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 4235 4236 return STOP; 4237 } 4238 4239 /* Running tests. */ 4240 bool is_ok = true; 4241 bool is_error = false; 4242 4243 /* Test objects. */ 4244 glw::GLint max_attributes = 8; 4245 4246 /* Tested VAOs. */ 4247 glw::GLuint vao = 0; 4248 glw::GLuint not_a_vao = 0; 4249 try 4250 { 4251 /* Query limits. */ 4252 gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_attributes); 4253 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed."); 4254 4255 /* Prepare valid VAO. */ 4256 gl.createVertexArrays(1, &vao); 4257 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed."); 4258 4259 /* Prepare invalid VAO. */ 4260 while (gl.isVertexArray(++not_a_vao)) 4261 ; 4262 4263 /* Test not a VAO. */ 4264 gl.enableVertexArrayAttrib(0, not_a_vao); 4265 4266 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by EnableVertexArrayAttrib if " 4267 "vaobj is not the name of an existing vertex array object."); 4268 4269 gl.disableVertexArrayAttrib(0, not_a_vao); 4270 4271 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by DisableVertexArrayAttrib if " 4272 "vaobj is not the name of an existing vertex array object."); 4273 4274 /* Test to big attribute index. */ 4275 gl.enableVertexArrayAttrib(max_attributes, vao); 4276 4277 is_ok &= CheckError( 4278 GL_INVALID_OPERATION, 4279 "INVALID_VALUE was not generated by EnableVertexArrayAttrib if index is equal to MAX_VERTEX_ATTRIBS."); 4280 4281 gl.disableVertexArrayAttrib(max_attributes, vao); 4282 4283 is_ok &= CheckError( 4284 GL_INVALID_OPERATION, 4285 "INVALID_VALUE was not generated by DisableVertexArrayAttrib if index is equal to MAX_VERTEX_ATTRIBS."); 4286 4287 gl.enableVertexArrayAttrib(max_attributes + 1, vao); 4288 4289 is_ok &= CheckError( 4290 GL_INVALID_OPERATION, 4291 "INVALID_VALUE was not generated by EnableVertexArrayAttrib if index is greater than MAX_VERTEX_ATTRIBS."); 4292 4293 gl.disableVertexArrayAttrib(max_attributes + 1, vao); 4294 4295 is_ok &= CheckError( 4296 GL_INVALID_OPERATION, 4297 "INVALID_VALUE was not generated by DisableVertexArrayAttrib if index is greater than MAX_VERTEX_ATTRIBS."); 4298 } 4299 catch (...) 4300 { 4301 is_ok = false; 4302 is_error = true; 4303 } 4304 4305 /* Clean up. */ 4306 if (vao) 4307 { 4308 gl.deleteVertexArrays(1, &vao); 4309 } 4310 4311 /* Errors clean up. */ 4312 while (gl.getError()) 4313 ; 4314 4315 /* Result's setup. */ 4316 if (is_ok) 4317 { 4318 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 4319 } 4320 else 4321 { 4322 if (is_error) 4323 { 4324 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 4325 } 4326 else 4327 { 4328 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 4329 } 4330 } 4331 4332 return STOP; 4333 } 4334 4335 /** @brief Compare error returned by GL with expected value and log. 4336 * 4337 * @param [in] expected Expected error. 4338 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one. 4339 * 4340 * @return True if GL error is equal to expected, false otherwise. 4341 */ 4342 bool EnableDisableAttributeErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message) 4343 { 4344 /* Shortcut for GL functionality. */ 4345 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4346 4347 glw::GLenum error = 0; 4348 4349 if (expected != (error = gl.getError())) 4350 { 4351 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error) 4352 << "was observed instead." << tcu::TestLog::EndMessage; 4353 4354 return false; 4355 } 4356 4357 return true; 4358 } 4359 4360 /******************************** Element Buffer Errors Test Implementation ********************************/ 4361 4362 /** @brief Element Buffer Errors Test constructor. 4363 * 4364 * @param [in] context OpenGL context. 4365 */ 4366 ElementBufferErrorsTest::ElementBufferErrorsTest(deqp::Context& context) 4367 : deqp::TestCase(context, "vertex_arrays_element_buffer_errors", "Element Buffer Errors Test") 4368 { 4369 } 4370 4371 /** @brief Element Buffer Errors Test cases. 4372 * 4373 * @return Iteration result. 4374 */ 4375 tcu::TestNode::IterateResult ElementBufferErrorsTest::iterate() 4376 { 4377 /* Shortcut for GL functionality. */ 4378 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4379 4380 /* Get context setup. */ 4381 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 4382 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 4383 4384 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 4385 { 4386 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 4387 4388 return STOP; 4389 } 4390 4391 /* Running tests. */ 4392 bool is_ok = true; 4393 bool is_error = false; 4394 4395 /* Tested Objects. */ 4396 glw::GLuint vao = 0; 4397 glw::GLuint not_a_vao = 0; 4398 glw::GLuint bo = 0; 4399 glw::GLuint not_a_bo = 0; 4400 4401 try 4402 { 4403 /* Prepare valid Objects. */ 4404 gl.createVertexArrays(1, &vao); 4405 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed."); 4406 4407 gl.createBuffers(1, &bo); 4408 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed."); 4409 4410 /* Prepare invalid VAO. */ 4411 while (gl.isVertexArray(++not_a_vao)) 4412 ; 4413 while (gl.isBuffer(++not_a_bo)) 4414 ; 4415 4416 /* Test not a VAO. */ 4417 gl.vertexArrayElementBuffer(not_a_vao, bo); 4418 4419 is_ok &= 4420 CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by VertexArrayElementBuffer if " 4421 "vaobj is not the name of an existing vertex array object."); 4422 4423 /* Test not a BO. */ 4424 gl.vertexArrayElementBuffer(vao, not_a_bo); 4425 4426 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error is generated by VertexArrayElementBuffer if " 4427 "buffer is not zero or the name of an existing buffer object."); 4428 } 4429 catch (...) 4430 { 4431 is_ok = false; 4432 is_error = true; 4433 } 4434 4435 /* Clean up. */ 4436 if (vao) 4437 { 4438 gl.deleteVertexArrays(1, &vao); 4439 } 4440 4441 if (bo) 4442 { 4443 gl.deleteBuffers(1, &bo); 4444 } 4445 4446 /* Errors clean up. */ 4447 while (gl.getError()) 4448 ; 4449 4450 /* Result's setup. */ 4451 if (is_ok) 4452 { 4453 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 4454 } 4455 else 4456 { 4457 if (is_error) 4458 { 4459 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 4460 } 4461 else 4462 { 4463 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 4464 } 4465 } 4466 4467 return STOP; 4468 } 4469 4470 /** @brief Compare error returned by GL with expected value and log. 4471 * 4472 * @param [in] expected Expected error. 4473 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one. 4474 * 4475 * @return True if GL error is equal to expected, false otherwise. 4476 */ 4477 bool ElementBufferErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message) 4478 { 4479 /* Shortcut for GL functionality. */ 4480 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4481 4482 glw::GLenum error = 0; 4483 4484 if (expected != (error = gl.getError())) 4485 { 4486 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error) 4487 << " was observed instead." << tcu::TestLog::EndMessage; 4488 4489 return false; 4490 } 4491 4492 return true; 4493 } 4494 4495 /******************************** Vertex Buffers Errors Test Implementation ********************************/ 4496 4497 /** @brief Vertex Buffers Errors Test constructor. 4498 * 4499 * @param [in] context OpenGL context. 4500 */ 4501 VertexBuffersErrorsTest::VertexBuffersErrorsTest(deqp::Context& context) 4502 : deqp::TestCase(context, "vertex_arrays_vertex_buffers_errors", "Vertex Buffers Errors Test") 4503 { 4504 } 4505 4506 /** @brief Vertex Buffers Errors Test cases. 4507 * 4508 * @return Iteration result. 4509 */ 4510 tcu::TestNode::IterateResult VertexBuffersErrorsTest::iterate() 4511 { 4512 /* Shortcut for GL functionality. */ 4513 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4514 4515 /* Get context setup. */ 4516 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 4517 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 4518 4519 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 4520 { 4521 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 4522 4523 return STOP; 4524 } 4525 4526 /* Running tests. */ 4527 bool is_ok = true; 4528 bool is_error = false; 4529 4530 /* Tested Objects. */ 4531 glw::GLuint vao = 0; 4532 glw::GLuint not_a_vao = 0; 4533 glw::GLuint bo = 0; 4534 glw::GLuint not_a_bo = 0; 4535 4536 /* Valid setup. */ 4537 glw::GLintptr valid_offset = 0; 4538 glw::GLsizei valid_stride = 1; 4539 4540 /* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */ 4541 glw::GLint max_vertex_attrib_bindings = 16; 4542 glw::GLint max_vertex_attrib_stride = 2048; 4543 4544 try 4545 { 4546 /* Prepare valid Objects. */ 4547 gl.createVertexArrays(1, &vao); 4548 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed."); 4549 4550 gl.createBuffers(1, &bo); 4551 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed."); 4552 4553 /* Prepare invalid VAO. */ 4554 while (gl.isVertexArray(++not_a_vao)) 4555 ; 4556 while (gl.isBuffer(++not_a_bo)) 4557 ; 4558 4559 /* Prepare limits. */ 4560 gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings); 4561 gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &max_vertex_attrib_stride); 4562 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed."); 4563 4564 /* Invalid setup. */ 4565 glw::GLintptr invalid_offset = -1; 4566 glw::GLsizei invalid_stride_0 = -1; 4567 glw::GLsizei invalid_stride_1 = max_vertex_attrib_stride + 1; 4568 4569 /* Test not a VAO. */ 4570 gl.vertexArrayVertexBuffer(not_a_vao, 0, bo, valid_offset, valid_stride); 4571 4572 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffer if " 4573 "vaobj is not the name of an existing vertex array object."); 4574 4575 gl.vertexArrayVertexBuffers(not_a_vao, 0, 1, &bo, &valid_offset, &valid_stride); 4576 4577 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffers if " 4578 "vaobj is not the name of an existing vertex array object."); 4579 4580 /* Test not a BO. */ 4581 gl.vertexArrayVertexBuffer(vao, 0, not_a_bo, valid_offset, valid_stride); 4582 4583 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffer if " 4584 "vaobj is not the name of an existing vertex array object."); 4585 4586 gl.vertexArrayVertexBuffers(vao, 0, 1, ¬_a_bo, &valid_offset, &valid_stride); 4587 4588 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffers if " 4589 "vaobj is not the name of an existing vertex array object."); 4590 4591 /* Test too big binding index. */ 4592 gl.vertexArrayVertexBuffer(vao, max_vertex_attrib_bindings, bo, valid_offset, valid_stride); 4593 4594 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayVertexBuffer if " 4595 "bindingindex is equal to the value of MAX_VERTEX_ATTRIB_BINDINGS."); 4596 4597 gl.vertexArrayVertexBuffer(vao, max_vertex_attrib_bindings + 1, bo, valid_offset, valid_stride); 4598 4599 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayVertexBuffer if " 4600 "bindingindex is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS."); 4601 4602 gl.vertexArrayVertexBuffers(vao, max_vertex_attrib_bindings, 1, &bo, &valid_offset, &valid_stride); 4603 4604 is_ok &= 4605 CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffers if " 4606 "first+count is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS."); 4607 4608 /* Test too big stride. */ 4609 gl.vertexArrayVertexBuffer(vao, 0, bo, -1, valid_stride); 4610 4611 is_ok &= CheckError(GL_INVALID_VALUE, 4612 "INVALID_VALUE is generated by VertexArrayVertexBuffer if offset less than zero."); 4613 4614 gl.vertexArrayVertexBuffer(vao, 0, bo, valid_offset, -1); 4615 4616 is_ok &= CheckError(GL_INVALID_VALUE, 4617 "INVALID_VALUE is generated by VertexArrayVertexBuffer if stride is less than zero."); 4618 4619 gl.vertexArrayVertexBuffer(vao, 0, bo, valid_offset, max_vertex_attrib_stride + 1); 4620 4621 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE is generated by VertexArrayVertexBuffer if stride is " 4622 "greater than the value of MAX_VERTEX_ATTRIB_STRIDE."); 4623 4624 gl.vertexArrayVertexBuffers(vao, 0, 1, &bo, &invalid_offset, &valid_stride); 4625 4626 is_ok &= 4627 CheckError(GL_INVALID_VALUE, 4628 "INVALID_VALUE is generated by VertexArrayVertexBuffers if any value in offsets is negative."); 4629 4630 gl.vertexArrayVertexBuffers(vao, 0, 1, &bo, &valid_offset, &invalid_stride_0); 4631 4632 is_ok &= 4633 CheckError(GL_INVALID_VALUE, 4634 "INVALID_VALUE is generated by VertexArrayVertexBuffers if any value in strides is negative."); 4635 4636 gl.vertexArrayVertexBuffers(vao, 0, 1, &bo, &valid_offset, &invalid_stride_1); 4637 4638 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE is generated by VertexArrayVertexBuffers if a value in " 4639 "strides is greater than the value of MAX_VERTEX_ATTRIB_STRIDE."); 4640 } 4641 catch (...) 4642 { 4643 is_ok = false; 4644 is_error = true; 4645 } 4646 4647 /* Clean up. */ 4648 if (vao) 4649 { 4650 gl.deleteVertexArrays(1, &vao); 4651 } 4652 4653 if (bo) 4654 { 4655 gl.deleteBuffers(1, &bo); 4656 } 4657 4658 /* Errors clean up. */ 4659 while (gl.getError()) 4660 ; 4661 4662 /* Result's setup. */ 4663 if (is_ok) 4664 { 4665 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 4666 } 4667 else 4668 { 4669 if (is_error) 4670 { 4671 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 4672 } 4673 else 4674 { 4675 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 4676 } 4677 } 4678 4679 return STOP; 4680 } 4681 4682 /** @brief Compare error returned by GL with expected value and log. 4683 * 4684 * @param [in] expected Expected error. 4685 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one. 4686 * 4687 * @return True if GL error is equal to expected, false otherwise. 4688 */ 4689 bool VertexBuffersErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message) 4690 { 4691 /* Shortcut for GL functionality. */ 4692 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4693 4694 glw::GLenum error = 0; 4695 4696 if (expected != (error = gl.getError())) 4697 { 4698 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error) 4699 << " was observed instead." << tcu::TestLog::EndMessage; 4700 4701 return false; 4702 } 4703 4704 return true; 4705 } 4706 4707 /******************************** Attribute Format Errors Test Implementation ********************************/ 4708 4709 /** @brief Attribute Format Errors Test constructor. 4710 * 4711 * @param [in] context OpenGL context. 4712 */ 4713 AttributeFormatErrorsTest::AttributeFormatErrorsTest(deqp::Context& context) 4714 : deqp::TestCase(context, "vertex_arrays_attribute_format_errors", "Attribute Format Errors Test") 4715 { 4716 } 4717 4718 /** @brief Attribute Format Errors Test cases. 4719 * 4720 * @return Iteration result. 4721 */ 4722 tcu::TestNode::IterateResult AttributeFormatErrorsTest::iterate() 4723 { 4724 /* Shortcut for GL functionality. */ 4725 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4726 4727 /* Get context setup. */ 4728 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 4729 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 4730 4731 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 4732 { 4733 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 4734 4735 return STOP; 4736 } 4737 4738 /* Running tests. */ 4739 bool is_ok = true; 4740 bool is_error = false; 4741 4742 /* Tested Objects. */ 4743 glw::GLuint vao = 0; 4744 glw::GLuint not_a_vao = 0; 4745 4746 /* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */ 4747 glw::GLint max_vertex_attribs = 16; 4748 glw::GLint max_vertex_attrib_relative_offset = 2047; 4749 4750 /* Invalid values. */ 4751 glw::GLenum bad_type = 0; 4752 4753 static const glw::GLenum accepted_types[] = { GL_BYTE, 4754 GL_SHORT, 4755 GL_INT, 4756 GL_FIXED, 4757 GL_FLOAT, 4758 GL_HALF_FLOAT, 4759 GL_DOUBLE, 4760 GL_UNSIGNED_BYTE, 4761 GL_UNSIGNED_SHORT, 4762 GL_UNSIGNED_INT, 4763 GL_INT_2_10_10_10_REV, 4764 GL_UNSIGNED_INT_2_10_10_10_REV, 4765 GL_UNSIGNED_INT_10F_11F_11F_REV }; 4766 4767 { 4768 bool is_accepted_type = true; 4769 while (is_accepted_type) 4770 { 4771 bad_type++; 4772 is_accepted_type = false; 4773 for (glw::GLuint i = 0; i < sizeof(accepted_types) / sizeof(accepted_types); ++i) 4774 { 4775 if (accepted_types[i] == bad_type) 4776 { 4777 is_accepted_type = true; 4778 break; 4779 } 4780 } 4781 } 4782 } 4783 4784 try 4785 { 4786 /* Prepare valid Objects. */ 4787 gl.createVertexArrays(1, &vao); 4788 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed."); 4789 4790 /* Prepare invalid VAO. */ 4791 while (gl.isVertexArray(++not_a_vao)) 4792 ; 4793 4794 /* Prepare limits. */ 4795 gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs); 4796 gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &max_vertex_attrib_relative_offset); 4797 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed."); 4798 4799 /* TESTS OF VERTEXARRAYATTRIBFORMAT */ 4800 4801 /* MAX_VERTEX_ATTRIBS < */ 4802 gl.vertexArrayAttribFormat(vao, max_vertex_attribs, 1, GL_BYTE, GL_FALSE, 0); 4803 4804 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribFormat if " 4805 "attribindex is equal to the value of MAX_VERTEX_ATTRIBS."); 4806 4807 gl.vertexArrayAttribFormat(vao, max_vertex_attribs + 1, 1, GL_BYTE, GL_FALSE, 0); 4808 4809 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribFormat if " 4810 "attribindex is greater than the value of MAX_VERTEX_ATTRIBS."); 4811 4812 gl.vertexArrayAttribIFormat(vao, max_vertex_attribs, 1, GL_BYTE, 0); 4813 4814 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if " 4815 "attribindex is equal to the value of MAX_VERTEX_ATTRIBS."); 4816 4817 gl.vertexArrayAttribIFormat(vao, max_vertex_attribs + 1, 1, GL_BYTE, 0); 4818 4819 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if " 4820 "attribindex is greater than the value of MAX_VERTEX_ATTRIBS."); 4821 4822 gl.vertexArrayAttribLFormat(vao, max_vertex_attribs, 1, GL_DOUBLE, 0); 4823 4824 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if " 4825 "attribindex is equal to the value of MAX_VERTEX_ATTRIBS."); 4826 4827 gl.vertexArrayAttribLFormat(vao, max_vertex_attribs + 1, 1, GL_DOUBLE, 0); 4828 4829 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if " 4830 "attribindex is greater than the value of MAX_VERTEX_ATTRIBS."); 4831 4832 /* size */ 4833 gl.vertexArrayAttribFormat(vao, 0, 0, GL_BYTE, GL_FALSE, 0); 4834 4835 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttrib*Format if size is " 4836 "not one of the accepted values (0)."); 4837 4838 gl.vertexArrayAttribFormat(vao, 0, 5, GL_BYTE, GL_FALSE, 0); 4839 4840 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttrib*Format if size is " 4841 "not one of the accepted values (5)."); 4842 4843 gl.vertexArrayAttribIFormat(vao, 0, 0, GL_BYTE, 0); 4844 4845 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if size is " 4846 "not one of the accepted values (0)."); 4847 4848 gl.vertexArrayAttribIFormat(vao, 0, 5, GL_BYTE, 0); 4849 4850 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if size is " 4851 "not one of the accepted values (5)."); 4852 4853 gl.vertexArrayAttribLFormat(vao, 0, 0, GL_DOUBLE, 0); 4854 4855 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if size is " 4856 "not one of the accepted values (0)."); 4857 4858 gl.vertexArrayAttribLFormat(vao, 0, 5, GL_DOUBLE, 0); 4859 4860 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if size is " 4861 "not one of the accepted values (5)."); 4862 4863 /* relative offset */ 4864 gl.vertexArrayAttribFormat(vao, 0, 1, GL_BYTE, GL_FALSE, max_vertex_attrib_relative_offset + 1); 4865 4866 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttrib*Format if " 4867 "relativeoffset is greater than the value of " 4868 "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET."); 4869 4870 gl.vertexArrayAttribIFormat(vao, 0, 1, GL_BYTE, max_vertex_attrib_relative_offset + 1); 4871 4872 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if " 4873 "relativeoffset is greater than the value of " 4874 "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET."); 4875 4876 gl.vertexArrayAttribLFormat(vao, 0, 1, GL_DOUBLE, max_vertex_attrib_relative_offset + 1); 4877 4878 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if " 4879 "relativeoffset is greater than the value of " 4880 "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET."); 4881 4882 /* type */ 4883 gl.vertexArrayAttribFormat(vao, 0, 1, bad_type, GL_FALSE, 0); 4884 4885 is_ok &= CheckError( 4886 GL_INVALID_ENUM, 4887 "INVALID_ENUM was not generated by VertexArrayAttribFormat if type is not one of the accepted tokens."); 4888 4889 gl.vertexArrayAttribIFormat(vao, 0, 1, bad_type, 0); 4890 4891 is_ok &= CheckError( 4892 GL_INVALID_ENUM, 4893 "INVALID_ENUM was not generated by VertexArrayAttribIFormat if type is not one of the accepted tokens."); 4894 4895 gl.vertexArrayAttribLFormat(vao, 0, 1, bad_type, 0); 4896 4897 is_ok &= CheckError( 4898 GL_INVALID_ENUM, 4899 "INVALID_ENUM was not generated by VertexArrayAttribLFormat if type is not one of the accepted tokens."); 4900 4901 /* type UNSIGNED_INT_10F_11F_11F_REV case */ 4902 gl.vertexArrayAttribIFormat(vao, 0, 1, GL_UNSIGNED_INT_10F_11F_11F_REV, 0); 4903 4904 is_ok &= CheckError( 4905 GL_INVALID_ENUM, 4906 "INVALID_ENUM was not generated by VertexArrayAttribIFormat if type is UNSIGNED_INT_10F_11F_11F_REV."); 4907 4908 gl.vertexArrayAttribLFormat(vao, 0, 1, GL_UNSIGNED_INT_10F_11F_11F_REV, 0); 4909 4910 is_ok &= CheckError( 4911 GL_INVALID_ENUM, 4912 "INVALID_ENUM was not generated by VertexArrayAttribLFormat if type is UNSIGNED_INT_10F_11F_11F_REV."); 4913 4914 /* Test not a VAO. */ 4915 gl.vertexArrayAttribFormat(not_a_vao, 0, 1, GL_BYTE, GL_FALSE, 0); 4916 4917 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if " 4918 "vaobj is not the name of an existing vertex array object."); 4919 4920 gl.vertexArrayAttribIFormat(not_a_vao, 0, 1, GL_BYTE, 0); 4921 4922 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribIFormat if " 4923 "vaobj is not the name of an existing vertex array object."); 4924 4925 gl.vertexArrayAttribLFormat(not_a_vao, 0, 1, GL_DOUBLE, 0); 4926 4927 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribLFormat if " 4928 "vaobj is not the name of an existing vertex array object."); 4929 4930 /* BGRA */ 4931 gl.vertexArrayAttribFormat(vao, 0, GL_BGRA, GL_BYTE, GL_TRUE, 0); 4932 4933 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if " 4934 "size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV or " 4935 "UNSIGNED_INT_2_10_10_10_REV."); 4936 4937 gl.vertexArrayAttribFormat(vao, 0, 1, GL_INT_2_10_10_10_REV, GL_TRUE, 0); 4938 4939 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if " 4940 "type is INT_2_10_10_10_REV and size is neither 4 nor BGRA."); 4941 4942 gl.vertexArrayAttribFormat(vao, 0, 1, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 0); 4943 4944 is_ok &= 4945 CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if type " 4946 "is UNSIGNED_INT_2_10_10_10_REV and size is neither 4 nor BGRA."); 4947 4948 gl.vertexArrayAttribFormat(vao, 0, 1, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_TRUE, 0); 4949 4950 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if " 4951 "type is UNSIGNED_INT_10F_11F_11F_REV and size is not 3."); 4952 4953 gl.vertexArrayAttribFormat(vao, 0, GL_BGRA, GL_UNSIGNED_BYTE, GL_FALSE, 0); 4954 4955 is_ok &= CheckError( 4956 GL_INVALID_OPERATION, 4957 "INVALID_OPERATION was not generated by VertexArrayAttribFormat if size is BGRA and normalized is FALSE."); 4958 } 4959 catch (...) 4960 { 4961 is_ok = false; 4962 is_error = true; 4963 } 4964 4965 /* Clean up. */ 4966 if (vao) 4967 { 4968 gl.deleteVertexArrays(1, &vao); 4969 } 4970 4971 /* Errors clean up. */ 4972 while (gl.getError()) 4973 ; 4974 4975 /* Result's setup. */ 4976 if (is_ok) 4977 { 4978 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 4979 } 4980 else 4981 { 4982 if (is_error) 4983 { 4984 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 4985 } 4986 else 4987 { 4988 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 4989 } 4990 } 4991 4992 return STOP; 4993 } 4994 4995 /** @brief Compare error returned by GL with expected value and log. 4996 * 4997 * @param [in] expected Expected error. 4998 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one. 4999 * 5000 * @return True if GL error is equal to expected, false otherwise. 5001 */ 5002 bool AttributeFormatErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message) 5003 { 5004 /* Shortcut for GL functionality. */ 5005 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5006 5007 glw::GLenum error = 0; 5008 5009 if (expected != (error = gl.getError())) 5010 { 5011 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error) 5012 << " was observed instead." << tcu::TestLog::EndMessage; 5013 5014 return false; 5015 } 5016 5017 return true; 5018 } 5019 5020 /******************************** Attribute Binding Errors Test Implementation ********************************/ 5021 5022 /** @brief Attribute Binding Errors Test constructor. 5023 * 5024 * @param [in] context OpenGL context. 5025 */ 5026 AttributeBindingErrorsTest::AttributeBindingErrorsTest(deqp::Context& context) 5027 : deqp::TestCase(context, "vertex_arrays_attribute_binding_errors", "Attribute Binding Errors Test") 5028 { 5029 } 5030 5031 /** @brief Attribute Binding Errors Test cases. 5032 * 5033 * @return Iteration result. 5034 */ 5035 tcu::TestNode::IterateResult AttributeBindingErrorsTest::iterate() 5036 { 5037 /* Shortcut for GL functionality. */ 5038 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5039 5040 /* Get context setup. */ 5041 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 5042 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 5043 5044 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 5045 { 5046 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 5047 5048 return STOP; 5049 } 5050 5051 /* Running tests. */ 5052 bool is_ok = true; 5053 bool is_error = false; 5054 5055 /* Tested Objects. */ 5056 glw::GLuint vao = 0; 5057 glw::GLuint not_a_vao = 0; 5058 5059 /* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */ 5060 glw::GLint max_vertex_attribs = 16; 5061 glw::GLint max_vertex_attrib_bindings = 16; 5062 5063 try 5064 { 5065 /* Prepare valid Objects. */ 5066 gl.createVertexArrays(1, &vao); 5067 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed."); 5068 5069 /* Prepare invalid VAO. */ 5070 while (gl.isVertexArray(++not_a_vao)) 5071 ; 5072 5073 /* Prepare limits. */ 5074 gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs); 5075 gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings); 5076 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed."); 5077 5078 /* Not a VAO. */ 5079 gl.vertexArrayAttribBinding(not_a_vao, 0, 0); 5080 5081 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribBinding if " 5082 "vaobj is not the name of an existing vertex array object."); 5083 5084 /* Too big attribute index. */ 5085 gl.vertexArrayAttribBinding(vao, max_vertex_attribs, 0); 5086 5087 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if " 5088 "attribindex is equal to the value of MAX_VERTEX_ATTRIBS."); 5089 5090 gl.vertexArrayAttribBinding(vao, max_vertex_attribs + 1, 0); 5091 5092 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if " 5093 "attribindex is greater than the value of MAX_VERTEX_ATTRIBS."); 5094 5095 /* Too big binding index. */ 5096 gl.vertexArrayAttribBinding(vao, 0, max_vertex_attrib_bindings); 5097 5098 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if " 5099 "bindingindex is equal to the value of MAX_VERTEX_ATTRIB_BINDINGS."); 5100 5101 gl.vertexArrayAttribBinding(vao, 0, max_vertex_attrib_bindings + 1); 5102 5103 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if " 5104 "bindingindex is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS."); 5105 } 5106 catch (...) 5107 { 5108 is_ok = false; 5109 is_error = true; 5110 } 5111 5112 /* Clean up. */ 5113 if (vao) 5114 { 5115 gl.deleteVertexArrays(1, &vao); 5116 } 5117 5118 /* Errors clean up. */ 5119 while (gl.getError()) 5120 ; 5121 5122 /* Result's setup. */ 5123 if (is_ok) 5124 { 5125 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 5126 } 5127 else 5128 { 5129 if (is_error) 5130 { 5131 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 5132 } 5133 else 5134 { 5135 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 5136 } 5137 } 5138 5139 return STOP; 5140 } 5141 5142 /** @brief Compare error returned by GL with expected value and log. 5143 * 5144 * @param [in] expected Expected error. 5145 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one. 5146 * 5147 * @return True if GL error is equal to expected, false otherwise. 5148 */ 5149 bool AttributeBindingErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message) 5150 { 5151 /* Shortcut for GL functionality. */ 5152 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5153 5154 glw::GLenum error = 0; 5155 5156 if (expected != (error = gl.getError())) 5157 { 5158 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error) 5159 << " was observed instead." << tcu::TestLog::EndMessage; 5160 5161 return false; 5162 } 5163 5164 return true; 5165 } 5166 5167 /******************************** Attribute Binding Divisor Errors Test Implementation ********************************/ 5168 5169 /** @brief Attribute Binding Divisor Errors Test constructor. 5170 * 5171 * @param [in] context OpenGL context. 5172 */ 5173 AttributeBindingDivisorErrorsTest::AttributeBindingDivisorErrorsTest(deqp::Context& context) 5174 : deqp::TestCase(context, "vertex_arrays_attribute_binding_divisor_errors", "Attribute Binding Divisor Errors Test") 5175 { 5176 } 5177 5178 /** @brief Attribute Binding Divisor Errors Test cases. 5179 * 5180 * @return Iteration result. 5181 */ 5182 tcu::TestNode::IterateResult AttributeBindingDivisorErrorsTest::iterate() 5183 { 5184 /* Shortcut for GL functionality. */ 5185 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5186 5187 /* Get context setup. */ 5188 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 5189 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 5190 5191 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 5192 { 5193 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 5194 5195 return STOP; 5196 } 5197 5198 /* Running tests. */ 5199 bool is_ok = true; 5200 bool is_error = false; 5201 5202 /* Tested Objects. */ 5203 glw::GLuint vao = 0; 5204 glw::GLuint not_a_vao = 0; 5205 5206 /* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */ 5207 glw::GLint max_vertex_attrib_bindings = 16; 5208 5209 try 5210 { 5211 /* Prepare valid Objects. */ 5212 gl.createVertexArrays(1, &vao); 5213 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed."); 5214 5215 /* Prepare invalid VAO. */ 5216 while (gl.isVertexArray(++not_a_vao)) 5217 ; 5218 5219 /* Prepare limits. */ 5220 gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings); 5221 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed."); 5222 5223 /* Not a VAO. */ 5224 gl.vertexArrayBindingDivisor(not_a_vao, 0, 0); 5225 5226 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayBindingDivisor if " 5227 "vaobj is not the name of an existing vertex array object."); 5228 5229 /* Too big binding index. */ 5230 gl.vertexArrayBindingDivisor(vao, max_vertex_attrib_bindings, 0); 5231 5232 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayBindingDivisor if " 5233 "bindingindex is equal to the value of MAX_VERTEX_ATTRIB_BINDINGS."); 5234 5235 gl.vertexArrayBindingDivisor(vao, max_vertex_attrib_bindings + 1, 0); 5236 5237 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayBindingDivisor if " 5238 "bindingindex is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS."); 5239 } 5240 catch (...) 5241 { 5242 is_ok = false; 5243 is_error = true; 5244 } 5245 5246 /* Clean up. */ 5247 if (vao) 5248 { 5249 gl.deleteVertexArrays(1, &vao); 5250 } 5251 5252 /* Errors clean up. */ 5253 while (gl.getError()) 5254 ; 5255 5256 /* Result's setup. */ 5257 if (is_ok) 5258 { 5259 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 5260 } 5261 else 5262 { 5263 if (is_error) 5264 { 5265 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 5266 } 5267 else 5268 { 5269 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 5270 } 5271 } 5272 5273 return STOP; 5274 } 5275 5276 /** @brief Compare error returned by GL with expected value and log. 5277 * 5278 * @param [in] expected Expected error. 5279 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one. 5280 * 5281 * @return True if GL error is equal to expected, false otherwise. 5282 */ 5283 bool AttributeBindingDivisorErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message) 5284 { 5285 /* Shortcut for GL functionality. */ 5286 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5287 5288 glw::GLenum error = 0; 5289 5290 if (expected != (error = gl.getError())) 5291 { 5292 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error) 5293 << " was observed instead." << tcu::TestLog::EndMessage; 5294 5295 return false; 5296 } 5297 5298 return true; 5299 } 5300 5301 /******************************** Get Vertex Array Errors Test Implementation ********************************/ 5302 5303 /** @brief Get Vertex Array Errors Test constructor. 5304 * 5305 * @param [in] context OpenGL context. 5306 */ 5307 GetVertexArrayErrorsTest::GetVertexArrayErrorsTest(deqp::Context& context) 5308 : deqp::TestCase(context, "vertex_arrays_get_vertex_array_errors", "Get Vertex Array Errors Test") 5309 { 5310 } 5311 5312 /** @brief Iterate over Get Vertex Array Errors Test cases. 5313 * 5314 * @return Iteration result. 5315 */ 5316 tcu::TestNode::IterateResult GetVertexArrayErrorsTest::iterate() 5317 { 5318 /* Shortcut for GL functionality. */ 5319 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5320 5321 /* Get context setup. */ 5322 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 5323 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 5324 5325 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 5326 { 5327 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 5328 5329 return STOP; 5330 } 5331 5332 /* Running tests. */ 5333 bool is_ok = true; 5334 bool is_error = false; 5335 5336 /* Tested Objects. */ 5337 glw::GLuint vao = 0; 5338 glw::GLuint not_a_vao = 0; 5339 5340 glw::GLint storage = 0; 5341 5342 try 5343 { 5344 /* Prepare valid Objects. */ 5345 gl.createVertexArrays(1, &vao); 5346 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed."); 5347 5348 /* Prepare invalid VAO. */ 5349 while (gl.isVertexArray(++not_a_vao)) 5350 ; 5351 5352 /* Not a VAO. */ 5353 gl.getVertexArrayiv(not_a_vao, GL_ELEMENT_ARRAY_BUFFER_BINDING, &storage); 5354 5355 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by GetVertexArrayiv if " 5356 "vaobj is not the name of an existing vertex array object."); 5357 5358 /* Bad parameter. */ 5359 gl.getVertexArrayiv(vao, GL_ELEMENT_ARRAY_BUFFER_BINDING + 1, &storage); 5360 5361 is_ok &= CheckError( 5362 GL_INVALID_ENUM, 5363 "INVALID_ENUM error was not generated by GetVertexArrayiv if pname is not ELEMENT_ARRAY_BUFFER_BINDING."); 5364 } 5365 catch (...) 5366 { 5367 is_ok = false; 5368 is_error = true; 5369 } 5370 5371 /* Clean up. */ 5372 if (vao) 5373 { 5374 gl.deleteVertexArrays(1, &vao); 5375 } 5376 5377 /* Errors clean up. */ 5378 while (gl.getError()) 5379 ; 5380 5381 /* Result's setup. */ 5382 if (is_ok) 5383 { 5384 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 5385 } 5386 else 5387 { 5388 if (is_error) 5389 { 5390 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 5391 } 5392 else 5393 { 5394 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 5395 } 5396 } 5397 5398 return STOP; 5399 } 5400 5401 /** @brief Compare error returned by GL with expected value and log. 5402 * 5403 * @param [in] expected Expected error. 5404 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one. 5405 * 5406 * @return True if GL error is equal to expected, false otherwise. 5407 */ 5408 bool GetVertexArrayErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message) 5409 { 5410 /* Shortcut for GL functionality. */ 5411 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5412 5413 glw::GLenum error = 0; 5414 5415 if (expected != (error = gl.getError())) 5416 { 5417 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error) 5418 << " was observed instead." << tcu::TestLog::EndMessage; 5419 5420 return false; 5421 } 5422 5423 return true; 5424 } 5425 5426 /******************************** Get Vertex Array Indexed Errors Test Implementation ********************************/ 5427 5428 /** @brief Get Vertex Array Indexed Errors Test constructor. 5429 * 5430 * @param [in] context OpenGL context. 5431 */ 5432 GetVertexArrayIndexedErrorsTest::GetVertexArrayIndexedErrorsTest(deqp::Context& context) 5433 : deqp::TestCase(context, "vertex_arrays_get_vertex_array_indexed_errors", "Get Vertex Array Indexed Errors Test") 5434 { 5435 } 5436 5437 /** @brief Iterate over Get Vertex Array Indexed Errors Test cases. 5438 * 5439 * @return Iteration result. 5440 */ 5441 tcu::TestNode::IterateResult GetVertexArrayIndexedErrorsTest::iterate() 5442 { 5443 /* Shortcut for GL functionality. */ 5444 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5445 5446 /* Get context setup. */ 5447 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 5448 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 5449 5450 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) 5451 { 5452 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 5453 5454 return STOP; 5455 } 5456 5457 /* Running tests. */ 5458 bool is_ok = true; 5459 bool is_error = false; 5460 5461 /* Tested Objects. */ 5462 glw::GLuint vao = 0; 5463 glw::GLuint not_a_vao = 0; 5464 5465 /* Dummy storage. */ 5466 glw::GLint storage = 0; 5467 glw::GLint64 storage64 = 0; 5468 5469 /* Bad parameter setup. */ 5470 glw::GLenum bad_pname = 0; 5471 5472 static const glw::GLenum accepted_pnames[] = { GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_VERTEX_ATTRIB_ARRAY_SIZE, 5473 GL_VERTEX_ATTRIB_ARRAY_STRIDE, GL_VERTEX_ATTRIB_ARRAY_TYPE, 5474 GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_VERTEX_ATTRIB_ARRAY_INTEGER, 5475 GL_VERTEX_ATTRIB_ARRAY_LONG, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 5476 GL_VERTEX_ATTRIB_RELATIVE_OFFSET }; 5477 5478 { 5479 bool is_accepted_pname = true; 5480 while (is_accepted_pname) 5481 { 5482 bad_pname++; 5483 is_accepted_pname = false; 5484 for (glw::GLuint i = 0; i < sizeof(accepted_pnames) / sizeof(accepted_pnames); ++i) 5485 { 5486 if (accepted_pnames[i] == bad_pname) 5487 { 5488 is_accepted_pname = true; 5489 break; 5490 } 5491 } 5492 } 5493 } 5494 5495 try 5496 { 5497 /* Prepare valid Objects. */ 5498 gl.createVertexArrays(1, &vao); 5499 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed."); 5500 5501 /* Prepare invalid VAO. */ 5502 while (gl.isVertexArray(++not_a_vao)) 5503 ; 5504 5505 /* Not a VAO. */ 5506 gl.getVertexArrayIndexediv(not_a_vao, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &storage); 5507 5508 is_ok &= 5509 CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by GetVertexArrayIndexediv if " 5510 "vaobj is not the name of an existing vertex array object."); 5511 5512 gl.getVertexArrayIndexed64iv(not_a_vao, 0, GL_VERTEX_BINDING_OFFSET, &storage64); 5513 5514 is_ok &= 5515 CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by GetVertexArrayIndexed64iv " 5516 "if vaobj is not the name of an existing vertex array object."); 5517 5518 /* Bad parameter. */ 5519 gl.getVertexArrayIndexediv(vao, 0, bad_pname, &storage); 5520 5521 is_ok &= CheckError( 5522 GL_INVALID_ENUM, 5523 "INVALID_ENUM error was not generated by GetVertexArrayIndexediv if pname is not one of the valid values."); 5524 5525 /* Bad parameter 64. */ 5526 gl.getVertexArrayIndexed64iv(vao, 0, GL_VERTEX_BINDING_OFFSET + 1, &storage64); 5527 5528 is_ok &= CheckError( 5529 GL_INVALID_ENUM, 5530 "INVALID_ENUM error was not generated by GetVertexArrayIndexed64iv if pname is not VERTEX_BINDING_OFFSET."); 5531 } 5532 catch (...) 5533 { 5534 is_ok = false; 5535 is_error = true; 5536 } 5537 5538 /* Clean up. */ 5539 if (vao) 5540 { 5541 gl.deleteVertexArrays(1, &vao); 5542 } 5543 5544 /* Errors clean up. */ 5545 while (gl.getError()) 5546 ; 5547 5548 /* Result's setup. */ 5549 if (is_ok) 5550 { 5551 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 5552 } 5553 else 5554 { 5555 if (is_error) 5556 { 5557 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 5558 } 5559 else 5560 { 5561 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 5562 } 5563 } 5564 5565 return STOP; 5566 } 5567 5568 /** @brief Compare error returned by GL with expected value and log. 5569 * 5570 * @param [in] expected Expected error. 5571 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one. 5572 * 5573 * @return True if GL error is equal to expected, false otherwise. 5574 */ 5575 bool GetVertexArrayIndexedErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message) 5576 { 5577 /* Shortcut for GL functionality. */ 5578 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5579 5580 glw::GLenum error = 0; 5581 5582 if (expected != (error = gl.getError())) 5583 { 5584 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error) 5585 << " was observed instead." << tcu::TestLog::EndMessage; 5586 5587 return false; 5588 } 5589 5590 return true; 5591 } 5592 } /* VertexArrays namespace. */ 5593 } /* DirectStateAccess namespace. */ 5594 } /* gl4cts namespace. */ 5595