1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.1 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 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 Vertex attribute binding state query tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es31fVertexAttributeBindingStateQueryTests.hpp" 25 #include "tcuTestLog.hpp" 26 #include "gluCallLogWrapper.hpp" 27 #include "gluRenderContext.hpp" 28 #include "gluObjectWrapper.hpp" 29 #include "gluStrUtil.hpp" 30 #include "glsStateQueryUtil.hpp" 31 #include "glwEnums.hpp" 32 #include "glwFunctions.hpp" 33 #include "deRandom.hpp" 34 35 namespace deqp 36 { 37 namespace gles31 38 { 39 namespace Functional 40 { 41 namespace 42 { 43 44 class AttributeBindingCase : public TestCase 45 { 46 public: 47 AttributeBindingCase (Context& context, const char* name, const char* desc); 48 IterateResult iterate (void); 49 }; 50 51 AttributeBindingCase::AttributeBindingCase (Context& context, const char* name, const char* desc) 52 : TestCase(context, name, desc) 53 { 54 } 55 56 AttributeBindingCase::IterateResult AttributeBindingCase::iterate (void) 57 { 58 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 59 glu::VertexArray vao (m_context.getRenderContext()); 60 glw::GLenum error = 0; 61 glw::GLint maxAttrs = -1; 62 bool allOk = true; 63 64 gl.enableLogging(true); 65 66 gl.glBindVertexArray(*vao); 67 gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttrs); 68 69 // initial 70 { 71 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values"); 72 73 for (int attr = 0; attr < de::max(16, maxAttrs); ++attr) 74 { 75 glw::GLint bindingState = -1; 76 77 gl.glGetVertexAttribiv(attr, GL_VERTEX_ATTRIB_BINDING, &bindingState); 78 error = gl.glGetError(); 79 80 if (error != GL_NO_ERROR) 81 { 82 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Got error " << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 83 allOk = false; 84 } 85 else if (bindingState != attr) 86 { 87 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << attr << ", got " << bindingState << tcu::TestLog::EndMessage; 88 allOk = false; 89 } 90 } 91 } 92 93 // is part of vao 94 { 95 const tcu::ScopedLogSection section (m_testCtx.getLog(), "vao", "VAO state"); 96 glu::VertexArray otherVao (m_context.getRenderContext()); 97 glw::GLint bindingState = -1; 98 99 // set to value A in vao1 100 gl.glVertexAttribBinding(1, 4); 101 102 // set to value B in vao2 103 gl.glBindVertexArray(*otherVao); 104 gl.glVertexAttribBinding(1, 7); 105 106 // check value is still ok in original vao 107 gl.glBindVertexArray(*vao); 108 gl.glGetVertexAttribiv(1, GL_VERTEX_ATTRIB_BINDING, &bindingState); 109 error = gl.glGetError(); 110 111 if (error != GL_NO_ERROR) 112 { 113 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Got error " << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 114 allOk = false; 115 } 116 else if (bindingState != 4) 117 { 118 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected 4, got " << bindingState << tcu::TestLog::EndMessage; 119 allOk = false; 120 } 121 } 122 123 // random values 124 { 125 const tcu::ScopedLogSection section (m_testCtx.getLog(), "random", "Random values"); 126 de::Random rnd (0xabc); 127 const int numRandomTests = 10; 128 129 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx) 130 { 131 // switch random va to random binding 132 const int va = rnd.getInt(0, de::max(16, maxAttrs)-1); 133 const int binding = rnd.getInt(0, 16); 134 glw::GLint bindingState = -1; 135 136 gl.glVertexAttribBinding(va, binding); 137 gl.glGetVertexAttribiv(va, GL_VERTEX_ATTRIB_BINDING, &bindingState); 138 error = gl.glGetError(); 139 140 if (error != GL_NO_ERROR) 141 { 142 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Got error " << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 143 allOk = false; 144 } 145 else if (bindingState != binding) 146 { 147 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << binding << ", got " << bindingState << tcu::TestLog::EndMessage; 148 allOk = false; 149 } 150 } 151 } 152 153 if (allOk) 154 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 155 else 156 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value"); 157 return STOP; 158 } 159 160 class AttributeRelativeOffsetCase : public TestCase 161 { 162 public: 163 AttributeRelativeOffsetCase (Context& context, const char* name, const char* desc); 164 IterateResult iterate (void); 165 }; 166 167 AttributeRelativeOffsetCase::AttributeRelativeOffsetCase (Context& context, const char* name, const char* desc) 168 : TestCase(context, name, desc) 169 { 170 } 171 172 AttributeRelativeOffsetCase::IterateResult AttributeRelativeOffsetCase::iterate (void) 173 { 174 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 175 glu::VertexArray vao (m_context.getRenderContext()); 176 glw::GLenum error = 0; 177 glw::GLint maxAttrs = -1; 178 bool allOk = true; 179 180 gl.enableLogging(true); 181 182 gl.glBindVertexArray(*vao); 183 gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttrs); 184 185 // initial 186 { 187 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values"); 188 189 for (int attr = 0; attr < de::max(16, maxAttrs); ++attr) 190 { 191 glw::GLint relOffsetState = -1; 192 193 gl.glGetVertexAttribiv(attr, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &relOffsetState); 194 error = gl.glGetError(); 195 196 if (error != GL_NO_ERROR) 197 { 198 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Got error " << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 199 allOk = false; 200 } 201 else if (relOffsetState != 0) 202 { 203 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected 0, got " << relOffsetState << tcu::TestLog::EndMessage; 204 allOk = false; 205 } 206 } 207 } 208 209 // is part of vao 210 { 211 const tcu::ScopedLogSection section (m_testCtx.getLog(), "vao", "VAO state"); 212 glu::VertexArray otherVao (m_context.getRenderContext()); 213 glw::GLint relOffsetState = -1; 214 215 // set to value A in vao1 216 gl.glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 9); 217 218 // set to value B in vao2 219 gl.glBindVertexArray(*otherVao); 220 gl.glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 21); 221 222 // check value is still ok in original vao 223 gl.glBindVertexArray(*vao); 224 gl.glGetVertexAttribiv(1, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &relOffsetState); 225 error = gl.glGetError(); 226 227 if (error != GL_NO_ERROR) 228 { 229 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Got error " << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 230 allOk = false; 231 } 232 else if (relOffsetState != 9) 233 { 234 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected 9, got " << relOffsetState << tcu::TestLog::EndMessage; 235 allOk = false; 236 } 237 } 238 239 // random values 240 { 241 const tcu::ScopedLogSection section (m_testCtx.getLog(), "random", "Random values"); 242 de::Random rnd (0xabc); 243 const int numRandomTests = 10; 244 245 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx) 246 { 247 const int va = rnd.getInt(0, de::max(16, maxAttrs)-1); 248 const int offset = rnd.getInt(0, 2047); 249 glw::GLint relOffsetState = -1; 250 251 gl.glVertexAttribFormat(va, 4, GL_FLOAT, GL_FALSE, offset); 252 gl.glGetVertexAttribiv(va, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &relOffsetState); 253 error = gl.glGetError(); 254 255 if (error != GL_NO_ERROR) 256 { 257 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Got error " << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 258 allOk = false; 259 } 260 else if (relOffsetState != offset) 261 { 262 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << offset << ", got " << relOffsetState << tcu::TestLog::EndMessage; 263 allOk = false; 264 } 265 } 266 } 267 268 if (allOk) 269 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 270 else 271 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value"); 272 return STOP; 273 } 274 275 class IndexedCase : public TestCase 276 { 277 public: 278 enum VerifierType 279 { 280 VERIFIER_INT, 281 VERIFIER_INT64, 282 283 VERIFIER_LAST 284 }; 285 286 IndexedCase (Context& context, const char* name, const char* desc, VerifierType verifier); 287 288 IterateResult iterate (void); 289 void verifyValue (glu::CallLogWrapper& gl, glw::GLenum name, int index, int expected); 290 291 virtual void test (void) = 0; 292 private: 293 const VerifierType m_verifier; 294 }; 295 296 IndexedCase::IndexedCase (Context& context, const char* name, const char* desc, VerifierType verifier) 297 : TestCase (context, name, desc) 298 , m_verifier (verifier) 299 { 300 DE_ASSERT(verifier < VERIFIER_LAST); 301 } 302 303 IndexedCase::IterateResult IndexedCase::iterate (void) 304 { 305 // default value 306 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 307 308 test(); 309 310 return STOP; 311 } 312 313 void IndexedCase::verifyValue (glu::CallLogWrapper& gl, glw::GLenum name, int index, int expected) 314 { 315 if (m_verifier == VERIFIER_INT) 316 { 317 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint> value; 318 glw::GLenum error = 0; 319 320 gl.glGetIntegeri_v(name, index, &value); 321 error = gl.glGetError(); 322 323 if (error != GL_NO_ERROR) 324 { 325 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Got unexpected error: " << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 326 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 327 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected error"); 328 } 329 else if (!value.verifyValidity(m_testCtx)) 330 { 331 // verifyValidity sets error 332 } 333 else 334 { 335 if (value != expected) 336 { 337 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << expected << ", got " << value << tcu::TestLog::EndMessage; 338 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 339 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected value"); 340 } 341 } 342 } 343 else if (m_verifier == VERIFIER_INT64) 344 { 345 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint64> value; 346 glw::GLenum error = 0; 347 348 gl.glGetInteger64i_v(name, index, &value); 349 error = gl.glGetError(); 350 351 if (error != GL_NO_ERROR) 352 { 353 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Got unexpected error: " << glu::getErrorStr(error) << tcu::TestLog::EndMessage; 354 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 355 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected error"); 356 } 357 else if (!value.verifyValidity(m_testCtx)) 358 { 359 // verifyValidity sets error 360 } 361 else 362 { 363 if (value != expected) 364 { 365 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << expected << ", got " << value << tcu::TestLog::EndMessage; 366 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 367 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected value"); 368 } 369 } 370 } 371 else 372 DE_ASSERT(false); 373 } 374 375 class VertexBindingDivisorCase : public IndexedCase 376 { 377 public: 378 VertexBindingDivisorCase (Context& context, const char* name, const char* desc, VerifierType verifier); 379 void test (void); 380 }; 381 382 VertexBindingDivisorCase::VertexBindingDivisorCase (Context& context, const char* name, const char* desc, VerifierType verifier) 383 : IndexedCase(context, name, desc, verifier) 384 { 385 } 386 387 void VertexBindingDivisorCase::test (void) 388 { 389 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 390 glu::VertexArray vao (m_context.getRenderContext()); 391 glw::GLint reportedMaxBindings = -1; 392 glw::GLint maxBindings; 393 394 gl.enableLogging(true); 395 396 gl.glBindVertexArray(*vao); 397 gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings); 398 maxBindings = de::max(16, reportedMaxBindings); 399 400 // initial 401 { 402 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values"); 403 404 for (int binding = 0; binding < maxBindings; ++binding) 405 verifyValue(gl, GL_VERTEX_BINDING_DIVISOR, binding, 0); 406 } 407 408 // is part of vao 409 { 410 const tcu::ScopedLogSection section (m_testCtx.getLog(), "vao", "VAO state"); 411 glu::VertexArray otherVao (m_context.getRenderContext()); 412 413 // set to value A in vao1 414 gl.glVertexBindingDivisor(1, 4); 415 416 // set to value B in vao2 417 gl.glBindVertexArray(*otherVao); 418 gl.glVertexBindingDivisor(1, 9); 419 420 // check value is still ok in original vao 421 gl.glBindVertexArray(*vao); 422 verifyValue(gl, GL_VERTEX_BINDING_DIVISOR, 1, 4); 423 } 424 425 // random values 426 { 427 const tcu::ScopedLogSection section (m_testCtx.getLog(), "random", "Random values"); 428 de::Random rnd (0xabc); 429 const int numRandomTests = 10; 430 431 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx) 432 { 433 const int binding = rnd.getInt(0, maxBindings-1); 434 const int divisor = rnd.getInt(0, 2047); 435 436 gl.glVertexBindingDivisor(binding, divisor); 437 verifyValue(gl, GL_VERTEX_BINDING_DIVISOR, binding, divisor); 438 } 439 } 440 } 441 442 class VertexBindingOffsetCase : public IndexedCase 443 { 444 public: 445 VertexBindingOffsetCase (Context& context, const char* name, const char* desc, VerifierType verifier); 446 void test (void); 447 }; 448 449 VertexBindingOffsetCase::VertexBindingOffsetCase (Context& context, const char* name, const char* desc, VerifierType verifier) 450 : IndexedCase(context, name, desc, verifier) 451 { 452 } 453 454 void VertexBindingOffsetCase::test (void) 455 { 456 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 457 glu::VertexArray vao (m_context.getRenderContext()); 458 glu::Buffer buffer (m_context.getRenderContext()); 459 glw::GLint reportedMaxBindings = -1; 460 glw::GLint maxBindings; 461 462 gl.enableLogging(true); 463 464 gl.glBindVertexArray(*vao); 465 gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings); 466 maxBindings = de::max(16, reportedMaxBindings); 467 468 // initial 469 { 470 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values"); 471 472 for (int binding = 0; binding < maxBindings; ++binding) 473 verifyValue(gl, GL_VERTEX_BINDING_OFFSET, binding, 0); 474 } 475 476 // is part of vao 477 { 478 const tcu::ScopedLogSection section (m_testCtx.getLog(), "vao", "VAO state"); 479 glu::VertexArray otherVao (m_context.getRenderContext()); 480 481 // set to value A in vao1 482 gl.glBindVertexBuffer(1, *buffer, 4, 32); 483 484 // set to value B in vao2 485 gl.glBindVertexArray(*otherVao); 486 gl.glBindVertexBuffer(1, *buffer, 13, 32); 487 488 // check value is still ok in original vao 489 gl.glBindVertexArray(*vao); 490 verifyValue(gl, GL_VERTEX_BINDING_OFFSET, 1, 4); 491 } 492 493 // random values 494 { 495 const tcu::ScopedLogSection section (m_testCtx.getLog(), "random", "Random values"); 496 de::Random rnd (0xabc); 497 const int numRandomTests = 10; 498 499 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx) 500 { 501 const int binding = rnd.getInt(0, maxBindings-1); 502 const int offset = rnd.getInt(0, 4000); 503 504 gl.glBindVertexBuffer(binding, *buffer, offset, 32); 505 verifyValue(gl, GL_VERTEX_BINDING_OFFSET, binding, offset); 506 } 507 } 508 } 509 510 class VertexBindingStrideCase : public IndexedCase 511 { 512 public: 513 VertexBindingStrideCase (Context& context, const char* name, const char* desc, VerifierType verifier); 514 void test (void); 515 }; 516 517 VertexBindingStrideCase::VertexBindingStrideCase (Context& context, const char* name, const char* desc, VerifierType verifier) 518 : IndexedCase(context, name, desc, verifier) 519 { 520 } 521 522 void VertexBindingStrideCase::test (void) 523 { 524 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 525 glu::VertexArray vao (m_context.getRenderContext()); 526 glu::Buffer buffer (m_context.getRenderContext()); 527 glw::GLint reportedMaxBindings = -1; 528 glw::GLint maxBindings; 529 530 gl.enableLogging(true); 531 532 gl.glBindVertexArray(*vao); 533 gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings); 534 maxBindings = de::max(16, reportedMaxBindings); 535 536 // initial 537 { 538 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values"); 539 540 for (int binding = 0; binding < maxBindings; ++binding) 541 verifyValue(gl, GL_VERTEX_BINDING_STRIDE, binding, 16); 542 } 543 544 // is part of vao 545 { 546 const tcu::ScopedLogSection section (m_testCtx.getLog(), "vao", "VAO state"); 547 glu::VertexArray otherVao (m_context.getRenderContext()); 548 549 // set to value A in vao1 550 gl.glBindVertexBuffer(1, *buffer, 0, 32); 551 552 // set to value B in vao2 553 gl.glBindVertexArray(*otherVao); 554 gl.glBindVertexBuffer(1, *buffer, 0, 64); 555 556 // check value is still ok in original vao 557 gl.glBindVertexArray(*vao); 558 verifyValue(gl, GL_VERTEX_BINDING_STRIDE, 1, 32); 559 } 560 561 // random values 562 { 563 const tcu::ScopedLogSection section (m_testCtx.getLog(), "random", "Random values"); 564 de::Random rnd (0xabc); 565 const int numRandomTests = 10; 566 567 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx) 568 { 569 const int binding = rnd.getInt(0, maxBindings-1); 570 const int stride = rnd.getInt(0, 2048); 571 572 gl.glBindVertexBuffer(binding, *buffer, 0, stride); 573 verifyValue(gl, GL_VERTEX_BINDING_STRIDE, binding, stride); 574 } 575 } 576 } 577 578 class VertexBindingBufferCase : public IndexedCase 579 { 580 public: 581 VertexBindingBufferCase (Context& context, const char* name, const char* desc, VerifierType verifier); 582 void test (void); 583 }; 584 585 VertexBindingBufferCase::VertexBindingBufferCase (Context& context, const char* name, const char* desc, VerifierType verifier) 586 : IndexedCase(context, name, desc, verifier) 587 { 588 } 589 590 void VertexBindingBufferCase::test (void) 591 { 592 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 593 glu::VertexArray vao (m_context.getRenderContext()); 594 glu::Buffer buffer (m_context.getRenderContext()); 595 glw::GLint reportedMaxBindings = -1; 596 glw::GLint maxBindings; 597 598 gl.enableLogging(true); 599 600 gl.glBindVertexArray(*vao); 601 gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings); 602 maxBindings = de::max(16, reportedMaxBindings); 603 604 // initial 605 { 606 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values"); 607 608 for (int binding = 0; binding < maxBindings; ++binding) 609 verifyValue(gl, GL_VERTEX_BINDING_BUFFER, binding, 0); 610 } 611 612 // is part of vao 613 { 614 const tcu::ScopedLogSection section (m_testCtx.getLog(), "vao", "VAO state"); 615 glu::VertexArray otherVao (m_context.getRenderContext()); 616 glu::Buffer otherBuffer (m_context.getRenderContext()); 617 618 // set to value A in vao1 619 gl.glBindVertexBuffer(1, *buffer, 0, 32); 620 621 // set to value B in vao2 622 gl.glBindVertexArray(*otherVao); 623 gl.glBindVertexBuffer(1, *otherBuffer, 0, 32); 624 625 // check value is still ok in original vao 626 gl.glBindVertexArray(*vao); 627 verifyValue(gl, GL_VERTEX_BINDING_BUFFER, 1, *buffer); 628 } 629 630 // Is detached in delete from active vao and not from deactive 631 { 632 const tcu::ScopedLogSection section (m_testCtx.getLog(), "autoUnbind", "Unbind on delete"); 633 glu::VertexArray otherVao (m_context.getRenderContext()); 634 glw::GLuint otherBuffer = -1; 635 636 gl.glGenBuffers(1, &otherBuffer); 637 638 // set in vao1 and vao2 639 gl.glBindVertexBuffer(1, otherBuffer, 0, 32); 640 gl.glBindVertexArray(*otherVao); 641 gl.glBindVertexBuffer(1, otherBuffer, 0, 32); 642 643 // delete buffer. This unbinds it from active (vao2) but not from unactive 644 gl.glDeleteBuffers(1, &otherBuffer); 645 verifyValue(gl, GL_VERTEX_BINDING_BUFFER, 1, 0); 646 gl.glBindVertexArray(*vao); 647 verifyValue(gl, GL_VERTEX_BINDING_BUFFER, 1, otherBuffer); 648 } 649 } 650 651 class MixedVertexBindingDivisorCase : public IndexedCase 652 { 653 public: 654 MixedVertexBindingDivisorCase (Context& context, const char* name, const char* desc); 655 void test (void); 656 }; 657 658 MixedVertexBindingDivisorCase::MixedVertexBindingDivisorCase (Context& context, const char* name, const char* desc) 659 : IndexedCase(context, name, desc, VERIFIER_INT) 660 { 661 } 662 663 void MixedVertexBindingDivisorCase::test (void) 664 { 665 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 666 glu::VertexArray vao (m_context.getRenderContext()); 667 668 gl.enableLogging(true); 669 670 gl.glVertexAttribDivisor(1, 4); 671 verifyValue(gl, GL_VERTEX_BINDING_DIVISOR, 1, 4); 672 } 673 674 class MixedVertexBindingOffsetCase : public IndexedCase 675 { 676 public: 677 MixedVertexBindingOffsetCase (Context& context, const char* name, const char* desc); 678 void test (void); 679 }; 680 681 MixedVertexBindingOffsetCase::MixedVertexBindingOffsetCase (Context& context, const char* name, const char* desc) 682 : IndexedCase(context, name, desc, VERIFIER_INT) 683 { 684 } 685 686 void MixedVertexBindingOffsetCase::test (void) 687 { 688 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 689 glu::VertexArray vao (m_context.getRenderContext()); 690 glu::Buffer buffer (m_context.getRenderContext()); 691 692 gl.enableLogging(true); 693 694 gl.glBindBuffer(GL_ARRAY_BUFFER, *buffer); 695 gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (const deUint8*)DE_NULL + 12); 696 697 verifyValue(gl, GL_VERTEX_BINDING_OFFSET, 1, 12); 698 } 699 700 class MixedVertexBindingStrideCase : public IndexedCase 701 { 702 public: 703 MixedVertexBindingStrideCase (Context& context, const char* name, const char* desc); 704 void test (void); 705 }; 706 707 MixedVertexBindingStrideCase::MixedVertexBindingStrideCase (Context& context, const char* name, const char* desc) 708 : IndexedCase(context, name, desc, VERIFIER_INT) 709 { 710 } 711 712 void MixedVertexBindingStrideCase::test (void) 713 { 714 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 715 glu::VertexArray vao (m_context.getRenderContext()); 716 glu::Buffer buffer (m_context.getRenderContext()); 717 718 gl.enableLogging(true); 719 720 gl.glBindBuffer(GL_ARRAY_BUFFER, *buffer); 721 gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 12, 0); 722 verifyValue(gl, GL_VERTEX_BINDING_STRIDE, 1, 12); 723 724 // test effectiveStride 725 gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0); 726 verifyValue(gl, GL_VERTEX_BINDING_STRIDE, 1, 16); 727 } 728 729 class MixedVertexBindingBufferCase : public IndexedCase 730 { 731 public: 732 MixedVertexBindingBufferCase (Context& context, const char* name, const char* desc); 733 void test (void); 734 }; 735 736 MixedVertexBindingBufferCase::MixedVertexBindingBufferCase (Context& context, const char* name, const char* desc) 737 : IndexedCase(context, name, desc, VERIFIER_INT) 738 { 739 } 740 741 void MixedVertexBindingBufferCase::test (void) 742 { 743 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 744 glu::VertexArray vao (m_context.getRenderContext()); 745 glu::Buffer buffer (m_context.getRenderContext()); 746 747 gl.enableLogging(true); 748 749 gl.glBindBuffer(GL_ARRAY_BUFFER, *buffer); 750 gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0); 751 verifyValue(gl, GL_VERTEX_BINDING_BUFFER, 1, *buffer); 752 } 753 754 } // anonymous 755 756 VertexAttributeBindingStateQueryTests::VertexAttributeBindingStateQueryTests (Context& context) 757 : TestCaseGroup(context, "vertex_attribute_binding", "Query vertex attribute binding state.") 758 { 759 } 760 761 VertexAttributeBindingStateQueryTests::~VertexAttributeBindingStateQueryTests (void) 762 { 763 } 764 765 void VertexAttributeBindingStateQueryTests::init (void) 766 { 767 tcu::TestCaseGroup* const attributeGroup = new TestCaseGroup(m_context, "vertex_attrib", "Vertex attribute state"); 768 tcu::TestCaseGroup* const indexedGroup = new TestCaseGroup(m_context, "indexed", "Indexed state"); 769 770 addChild(attributeGroup); 771 addChild(indexedGroup); 772 773 // .vertex_attrib 774 { 775 attributeGroup->addChild(new AttributeBindingCase (m_context, "vertex_attrib_binding", "Test VERTEX_ATTRIB_BINDING")); 776 attributeGroup->addChild(new AttributeRelativeOffsetCase(m_context, "vertex_attrib_relative_offset", "Test VERTEX_ATTRIB_RELATIVE_OFFSET")); 777 } 778 779 // .indexed (and 64) 780 { 781 static const struct Verifier 782 { 783 const char* name; 784 IndexedCase::VerifierType type; 785 } verifiers[] = 786 { 787 { "getintegeri", IndexedCase::VERIFIER_INT }, 788 { "getintegeri64", IndexedCase::VERIFIER_INT64 }, 789 }; 790 791 // states 792 793 for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx) 794 { 795 indexedGroup->addChild(new VertexBindingDivisorCase (m_context, (std::string("vertex_binding_divisor_") + verifiers[verifierNdx].name).c_str(), "Test VERTEX_BINDING_DIVISOR", verifiers[verifierNdx].type)); 796 indexedGroup->addChild(new VertexBindingOffsetCase (m_context, (std::string("vertex_binding_offset_") + verifiers[verifierNdx].name).c_str(), "Test VERTEX_BINDING_OFFSET", verifiers[verifierNdx].type)); 797 indexedGroup->addChild(new VertexBindingStrideCase (m_context, (std::string("vertex_binding_stride_") + verifiers[verifierNdx].name).c_str(), "Test VERTEX_BINDING_STRIDE", verifiers[verifierNdx].type)); 798 indexedGroup->addChild(new VertexBindingBufferCase (m_context, (std::string("vertex_binding_buffer_") + verifiers[verifierNdx].name).c_str(), "Test VERTEX_BINDING_BUFFER", verifiers[verifierNdx].type)); 799 } 800 801 // mixed apis 802 803 indexedGroup->addChild(new MixedVertexBindingDivisorCase(m_context, "vertex_binding_divisor_mixed", "Test VERTEX_BINDING_DIVISOR")); 804 indexedGroup->addChild(new MixedVertexBindingOffsetCase (m_context, "vertex_binding_offset_mixed", "Test VERTEX_BINDING_OFFSET")); 805 indexedGroup->addChild(new MixedVertexBindingStrideCase (m_context, "vertex_binding_stride_mixed", "Test VERTEX_BINDING_STRIDE")); 806 indexedGroup->addChild(new MixedVertexBindingBufferCase (m_context, "vertex_binding_buffer_mixed", "Test VERTEX_BINDING_BUFFER")); 807 } 808 } 809 810 } // Functional 811 } // gles31 812 } // deqp 813