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