1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.0 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 Rbo state query tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es3fShaderStateQueryTests.hpp" 25 #include "glsStateQueryUtil.hpp" 26 #include "es3fApiCase.hpp" 27 #include "gluRenderContext.hpp" 28 #include "glwEnums.hpp" 29 #include "glwFunctions.hpp" 30 #include "deRandom.hpp" 31 #include "deMath.h" 32 #include "deString.h" 33 34 using namespace glw; // GLint and other GL types 35 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard; 36 37 namespace deqp 38 { 39 namespace gles3 40 { 41 namespace Functional 42 { 43 namespace 44 { 45 46 static const char* commonTestVertSource = "#version 300 es\n" 47 "void main (void)\n" 48 "{\n" 49 " gl_Position = vec4(0.0);\n" 50 "}\n\0"; 51 static const char* commonTestFragSource = "#version 300 es\n" 52 "layout(location = 0) out mediump vec4 fragColor;\n" 53 "void main (void)\n" 54 "{\n" 55 " fragColor = vec4(0.0);\n" 56 "}\n\0"; 57 58 static const char* brokenShader = "#version 300 es\n" 59 "broken, this should not compile!\n" 60 "\n\0"; 61 62 // rounds x.1 to x+1 63 template <typename T> 64 T roundGLfloatToNearestIntegerUp (GLfloat val) 65 { 66 return (T)(ceil(val)); 67 } 68 69 // rounds x.9 to x 70 template <typename T> 71 T roundGLfloatToNearestIntegerDown (GLfloat val) 72 { 73 return (T)(floor(val)); 74 } 75 76 bool checkIntEquals (tcu::TestContext& testCtx, GLint got, GLint expected) 77 { 78 using tcu::TestLog; 79 80 if (got != expected) 81 { 82 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage; 83 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 84 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value"); 85 return false; 86 } 87 return true; 88 } 89 90 void checkPointerEquals (tcu::TestContext& testCtx, const void* got, const void* expected) 91 { 92 using tcu::TestLog; 93 94 if (got != expected) 95 { 96 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage; 97 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 98 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value"); 99 } 100 } 101 102 void verifyShaderParam (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint shader, GLenum pname, GLenum reference) 103 { 104 StateQueryMemoryWriteGuard<GLint> state; 105 gl.glGetShaderiv(shader, pname, &state); 106 107 if (state.verifyValidity(testCtx)) 108 checkIntEquals(testCtx, state, reference); 109 } 110 111 bool verifyProgramParam (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLenum pname, GLenum reference) 112 { 113 StateQueryMemoryWriteGuard<GLint> state; 114 gl.glGetProgramiv(program, pname, &state); 115 116 return state.verifyValidity(testCtx) && checkIntEquals(testCtx, state, reference); 117 } 118 119 void verifyActiveUniformParam (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLuint index, GLenum pname, GLenum reference) 120 { 121 StateQueryMemoryWriteGuard<GLint> state; 122 gl.glGetActiveUniformsiv(program, 1, &index, pname, &state); 123 124 if (state.verifyValidity(testCtx)) 125 checkIntEquals(testCtx, state, reference); 126 } 127 128 void verifyActiveUniformBlockParam (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLuint blockIndex, GLenum pname, GLenum reference) 129 { 130 StateQueryMemoryWriteGuard<GLint> state; 131 gl.glGetActiveUniformBlockiv(program, blockIndex, pname, &state); 132 133 if (state.verifyValidity(testCtx)) 134 checkIntEquals(testCtx, state, reference); 135 } 136 137 void verifyCurrentVertexAttribf (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 138 { 139 using tcu::TestLog; 140 141 StateQueryMemoryWriteGuard<GLfloat[4]> attribValue; 142 gl.glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue); 143 144 attribValue.verifyValidity(testCtx); 145 146 if (attribValue[0] != x || attribValue[1] != y || attribValue[2] != z || attribValue[3] != w) 147 { 148 testCtx.getLog() << TestLog::Message 149 << "// ERROR: Expected [" << x << "," << y << "," << z << "," << w << "];" 150 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << "," << attribValue[3] << "]" 151 << TestLog::EndMessage; 152 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 153 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value"); 154 } 155 } 156 157 void verifyCurrentVertexAttribIi (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLint x, GLint y, GLint z, GLint w) 158 { 159 using tcu::TestLog; 160 161 StateQueryMemoryWriteGuard<GLint[4]> attribValue; 162 gl.glGetVertexAttribIiv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue); 163 164 attribValue.verifyValidity(testCtx); 165 166 if (attribValue[0] != x || attribValue[1] != y || attribValue[2] != z || attribValue[3] != w) 167 { 168 testCtx.getLog() << TestLog::Message 169 << "// ERROR: Expected [" << x << "," << y << "," << z << "," << w << "];" 170 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << "," << attribValue[3] << "]" 171 << TestLog::EndMessage; 172 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 173 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value"); 174 } 175 } 176 177 void verifyCurrentVertexAttribIui (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLuint x, GLuint y, GLuint z, GLuint w) 178 { 179 using tcu::TestLog; 180 181 StateQueryMemoryWriteGuard<GLuint[4]> attribValue; 182 gl.glGetVertexAttribIuiv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue); 183 184 attribValue.verifyValidity(testCtx); 185 186 if (attribValue[0] != x || attribValue[1] != y || attribValue[2] != z || attribValue[3] != w) 187 { 188 testCtx.getLog() << TestLog::Message 189 << "// ERROR: Expected [" << x << "," << y << "," << z << "," << w << "];" 190 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << "," << attribValue[3] << "]" 191 << TestLog::EndMessage; 192 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 193 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value"); 194 } 195 } 196 197 void verifyCurrentVertexAttribConversion (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 198 { 199 using tcu::TestLog; 200 201 StateQueryMemoryWriteGuard<GLint[4]> attribValue; 202 gl.glGetVertexAttribiv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue); 203 204 attribValue.verifyValidity(testCtx); 205 206 const GLint referenceAsGLintMin[] = 207 { 208 roundGLfloatToNearestIntegerDown<GLint>(x), 209 roundGLfloatToNearestIntegerDown<GLint>(y), 210 roundGLfloatToNearestIntegerDown<GLint>(z), 211 roundGLfloatToNearestIntegerDown<GLint>(w) 212 }; 213 const GLint referenceAsGLintMax[] = 214 { 215 roundGLfloatToNearestIntegerUp<GLint>(x), 216 roundGLfloatToNearestIntegerUp<GLint>(y), 217 roundGLfloatToNearestIntegerUp<GLint>(z), 218 roundGLfloatToNearestIntegerUp<GLint>(w) 219 }; 220 221 if (attribValue[0] < referenceAsGLintMin[0] || attribValue[0] > referenceAsGLintMax[0] || 222 attribValue[1] < referenceAsGLintMin[1] || attribValue[1] > referenceAsGLintMax[1] || 223 attribValue[2] < referenceAsGLintMin[2] || attribValue[2] > referenceAsGLintMax[2] || 224 attribValue[3] < referenceAsGLintMin[3] || attribValue[3] > referenceAsGLintMax[3]) 225 { 226 testCtx.getLog() << TestLog::Message 227 << "// ERROR: expected in range " 228 << "[" << referenceAsGLintMin[0] << " " << referenceAsGLintMax[0] << "], " 229 << "[" << referenceAsGLintMin[1] << " " << referenceAsGLintMax[1] << "], " 230 << "[" << referenceAsGLintMin[2] << " " << referenceAsGLintMax[2] << "], " 231 << "[" << referenceAsGLintMin[3] << " " << referenceAsGLintMax[3] << "]" 232 << "; got " 233 << attribValue[0] << ", " 234 << attribValue[1] << ", " 235 << attribValue[2] << ", " 236 << attribValue[3] << " " 237 << "; Input=" 238 << x << "; " 239 << y << "; " 240 << z << "; " 241 << w << " " << TestLog::EndMessage; 242 243 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 244 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid attribute value"); 245 } 246 } 247 248 void verifyVertexAttrib (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLenum pname, GLenum reference) 249 { 250 StateQueryMemoryWriteGuard<GLint> state; 251 gl.glGetVertexAttribIiv(index, pname, &state); 252 253 if (state.verifyValidity(testCtx)) 254 checkIntEquals(testCtx, state, reference); 255 } 256 257 void verifyUniformValue1f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x) 258 { 259 using tcu::TestLog; 260 261 StateQueryMemoryWriteGuard<GLfloat[1]> state; 262 gl.glGetUniformfv(program, location, state); 263 264 if (!state.verifyValidity(testCtx)) 265 return; 266 267 if (state[0] != x) 268 { 269 testCtx.getLog() << TestLog::Message 270 << "// ERROR: expected [" 271 << x 272 << "]; got [" 273 << state[0] 274 << "]" 275 << TestLog::EndMessage; 276 277 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 278 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 279 } 280 } 281 282 void verifyUniformValue2f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y) 283 { 284 using tcu::TestLog; 285 286 StateQueryMemoryWriteGuard<GLfloat[2]> state; 287 gl.glGetUniformfv(program, location, state); 288 289 if (!state.verifyValidity(testCtx)) 290 return; 291 292 if (state[0] != x || 293 state[1] != y) 294 { 295 testCtx.getLog() << TestLog::Message 296 << "// ERROR: expected [" 297 << x << ", " 298 << y 299 << "]; got [" 300 << state[0] << ", " 301 << state[1] 302 << "]" 303 << TestLog::EndMessage; 304 305 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 306 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 307 } 308 } 309 310 void verifyUniformValue3f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y, float z) 311 { 312 using tcu::TestLog; 313 314 StateQueryMemoryWriteGuard<GLfloat[3]> state; 315 gl.glGetUniformfv(program, location, state); 316 317 if (!state.verifyValidity(testCtx)) 318 return; 319 320 if (state[0] != x || 321 state[1] != y || 322 state[2] != z) 323 { 324 testCtx.getLog() << TestLog::Message 325 << "// ERROR: expected [" 326 << x << ", " 327 << y << ", " 328 << z 329 << "]; got [" 330 << state[0] << ", " 331 << state[1] << ", " 332 << state[2] 333 << "]" 334 << TestLog::EndMessage; 335 336 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 337 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 338 } 339 } 340 341 void verifyUniformValue4f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y, float z, float w) 342 { 343 using tcu::TestLog; 344 345 StateQueryMemoryWriteGuard<GLfloat[4]> state; 346 gl.glGetUniformfv(program, location, state); 347 348 if (!state.verifyValidity(testCtx)) 349 return; 350 351 if (state[0] != x || 352 state[1] != y || 353 state[2] != z || 354 state[3] != w) 355 { 356 testCtx.getLog() << TestLog::Message 357 << "// ERROR: expected [" 358 << x << ", " 359 << y << ", " 360 << z << ", " 361 << w 362 << "]; got [" 363 << state[0] << ", " 364 << state[1] << ", " 365 << state[2] << ", " 366 << state[3] 367 << "]" 368 << TestLog::EndMessage; 369 370 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 371 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 372 } 373 } 374 375 void verifyUniformValue1i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x) 376 { 377 using tcu::TestLog; 378 379 StateQueryMemoryWriteGuard<GLint[1]> state; 380 gl.glGetUniformiv(program, location, state); 381 382 if (!state.verifyValidity(testCtx)) 383 return; 384 385 if (state[0] != x) 386 { 387 testCtx.getLog() << TestLog::Message 388 << "// ERROR: expected [" 389 << x 390 << "]; got [" 391 << state[0] 392 << "]" 393 << TestLog::EndMessage; 394 395 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 396 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 397 } 398 } 399 400 void verifyUniformValue2i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y) 401 { 402 using tcu::TestLog; 403 404 StateQueryMemoryWriteGuard<GLint[2]> state; 405 gl.glGetUniformiv(program, location, state); 406 407 if (!state.verifyValidity(testCtx)) 408 return; 409 410 if (state[0] != x || 411 state[1] != y) 412 { 413 testCtx.getLog() << TestLog::Message 414 << "// ERROR: expected [" 415 << x << ", " 416 << y 417 << "]; got [" 418 << state[0] << ", " 419 << state[1] 420 << "]" 421 << TestLog::EndMessage; 422 423 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 424 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 425 } 426 } 427 428 void verifyUniformValue3i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y, GLint z) 429 { 430 using tcu::TestLog; 431 432 StateQueryMemoryWriteGuard<GLint[3]> state; 433 gl.glGetUniformiv(program, location, state); 434 435 if (!state.verifyValidity(testCtx)) 436 return; 437 438 if (state[0] != x || 439 state[1] != y || 440 state[2] != z) 441 { 442 testCtx.getLog() << TestLog::Message 443 << "// ERROR: expected [" 444 << x << ", " 445 << y << ", " 446 << z 447 << "]; got [" 448 << state[0] << ", " 449 << state[1] << ", " 450 << state[2] 451 << "]" 452 << TestLog::EndMessage; 453 454 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 455 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 456 } 457 } 458 459 void verifyUniformValue4i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w) 460 { 461 using tcu::TestLog; 462 463 StateQueryMemoryWriteGuard<GLint[4]> state; 464 gl.glGetUniformiv(program, location, state); 465 466 if (!state.verifyValidity(testCtx)) 467 return; 468 469 if (state[0] != x || 470 state[1] != y || 471 state[2] != z || 472 state[3] != w) 473 { 474 testCtx.getLog() << TestLog::Message 475 << "// ERROR: expected [" 476 << x << ", " 477 << y << ", " 478 << z << ", " 479 << w 480 << "]; got [" 481 << state[0] << ", " 482 << state[1] << ", " 483 << state[2] << ", " 484 << state[3] 485 << "]" 486 << TestLog::EndMessage; 487 488 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 489 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 490 } 491 } 492 493 void verifyUniformValue1ui (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLuint x) 494 { 495 using tcu::TestLog; 496 497 StateQueryMemoryWriteGuard<GLuint[1]> state; 498 gl.glGetUniformuiv(program, location, state); 499 500 if (!state.verifyValidity(testCtx)) 501 return; 502 503 if (state[0] != x) 504 { 505 testCtx.getLog() << TestLog::Message 506 << "// ERROR: expected [" 507 << x 508 << "]; got [" 509 << state[0] 510 << "]" 511 << TestLog::EndMessage; 512 513 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 514 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 515 } 516 } 517 518 void verifyUniformValue2ui (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLuint x, GLuint y) 519 { 520 using tcu::TestLog; 521 522 StateQueryMemoryWriteGuard<GLuint[2]> state; 523 gl.glGetUniformuiv(program, location, state); 524 525 if (!state.verifyValidity(testCtx)) 526 return; 527 528 if (state[0] != x || 529 state[1] != y) 530 { 531 testCtx.getLog() << TestLog::Message 532 << "// ERROR: expected [" 533 << x << ", " 534 << y 535 << "]; got [" 536 << state[0] << ", " 537 << state[1] 538 << "]" 539 << TestLog::EndMessage; 540 541 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 542 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 543 } 544 } 545 546 void verifyUniformValue3ui (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLuint x, GLuint y, GLuint z) 547 { 548 using tcu::TestLog; 549 550 StateQueryMemoryWriteGuard<GLuint[3]> state; 551 gl.glGetUniformuiv(program, location, state); 552 553 if (!state.verifyValidity(testCtx)) 554 return; 555 556 if (state[0] != x || 557 state[1] != y || 558 state[2] != z) 559 { 560 testCtx.getLog() << TestLog::Message 561 << "// ERROR: expected [" 562 << x << ", " 563 << y << ", " 564 << z 565 << "]; got [" 566 << state[0] << ", " 567 << state[1] << ", " 568 << state[2] 569 << "]" 570 << TestLog::EndMessage; 571 572 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 573 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 574 } 575 } 576 577 void verifyUniformValue4ui (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLuint x, GLuint y, GLuint z, GLuint w) 578 { 579 using tcu::TestLog; 580 581 StateQueryMemoryWriteGuard<GLuint[4]> state; 582 gl.glGetUniformuiv(program, location, state); 583 584 if (!state.verifyValidity(testCtx)) 585 return; 586 587 if (state[0] != x || 588 state[1] != y || 589 state[2] != z || 590 state[3] != w) 591 { 592 testCtx.getLog() << TestLog::Message 593 << "// ERROR: expected [" 594 << x << ", " 595 << y << ", " 596 << z << ", " 597 << w 598 << "]; got [" 599 << state[0] << ", " 600 << state[1] << ", " 601 << state[2] << ", " 602 << state[3] 603 << "]" 604 << TestLog::EndMessage; 605 606 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 607 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 608 } 609 } 610 611 template <int Count> 612 void verifyUniformValues (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, const GLfloat* values) 613 { 614 using tcu::TestLog; 615 616 StateQueryMemoryWriteGuard<GLfloat[Count]> state; 617 gl.glGetUniformfv(program, location, state); 618 619 if (!state.verifyValidity(testCtx)) 620 return; 621 622 for (int ndx = 0; ndx < Count; ++ndx) 623 { 624 if (values[ndx] != state[ndx]) 625 { 626 testCtx.getLog() << TestLog::Message << "// ERROR: at index " << ndx << " expected " << values[ndx] << "; got " << state[ndx] << TestLog::EndMessage; 627 628 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 629 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 630 } 631 } 632 } 633 634 template <int N> 635 void verifyUniformMatrixValues (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, const GLfloat* values, bool transpose) 636 { 637 using tcu::TestLog; 638 639 StateQueryMemoryWriteGuard<GLfloat[N*N]> state; 640 gl.glGetUniformfv(program, location, state); 641 642 if (!state.verifyValidity(testCtx)) 643 return; 644 645 for (int y = 0; y < N; ++y) 646 for (int x = 0; x < N; ++x) 647 { 648 const int refIndex = y*N + x; 649 const int stateIndex = transpose ? (x*N + y) : (y*N + x); 650 651 if (values[refIndex] != state[stateIndex]) 652 { 653 testCtx.getLog() << TestLog::Message << "// ERROR: at index [" << y << "][" << x << "] expected " << values[refIndex] << "; got " << state[stateIndex] << TestLog::EndMessage; 654 655 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 656 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 657 } 658 } 659 } 660 661 class ShaderTypeCase : public ApiCase 662 { 663 public: 664 ShaderTypeCase (Context& context, const char* name, const char* description) 665 : ApiCase(context, name, description) 666 { 667 } 668 669 void test (void) 670 { 671 const GLenum shaderTypes[] = {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER}; 672 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(shaderTypes); ++ndx) 673 { 674 const GLuint shader = glCreateShader(shaderTypes[ndx]); 675 verifyShaderParam(m_testCtx, *this, shader, GL_SHADER_TYPE, shaderTypes[ndx]); 676 glDeleteShader(shader); 677 } 678 } 679 }; 680 681 class ShaderCompileStatusCase : public ApiCase 682 { 683 public: 684 ShaderCompileStatusCase (Context& context, const char* name, const char* description) 685 : ApiCase(context, name, description) 686 { 687 } 688 689 void test (void) 690 { 691 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 692 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 693 694 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_FALSE); 695 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_FALSE); 696 697 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL); 698 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL); 699 700 glCompileShader(shaderVert); 701 glCompileShader(shaderFrag); 702 expectError(GL_NO_ERROR); 703 704 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE); 705 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE); 706 707 glDeleteShader(shaderVert); 708 glDeleteShader(shaderFrag); 709 expectError(GL_NO_ERROR); 710 } 711 }; 712 713 class ShaderInfoLogCase : public ApiCase 714 { 715 public: 716 ShaderInfoLogCase (Context& context, const char* name, const char* description) 717 : ApiCase(context, name, description) 718 { 719 } 720 721 void test (void) 722 { 723 using tcu::TestLog; 724 725 // INFO_LOG_LENGTH is 0 by default and it includes null-terminator 726 const GLuint shader = glCreateShader(GL_VERTEX_SHADER); 727 verifyShaderParam(m_testCtx, *this, shader, GL_INFO_LOG_LENGTH, 0); 728 729 glShaderSource(shader, 1, &brokenShader, DE_NULL); 730 glCompileShader(shader); 731 expectError(GL_NO_ERROR); 732 733 // check the log length 734 StateQueryMemoryWriteGuard<GLint> logLength; 735 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); 736 if (!logLength.verifyValidity(m_testCtx)) 737 { 738 glDeleteShader(shader); 739 return; 740 } 741 if (logLength == 0) 742 { 743 glDeleteShader(shader); 744 return; 745 } 746 747 // check normal case 748 { 749 char buffer[2048] = {'x'}; // non-zero initialization 750 751 GLint written = 0; // written does not include null terminator 752 glGetShaderInfoLog(shader, DE_LENGTH_OF_ARRAY(buffer), &written, buffer); 753 754 // check lengths are consistent 755 if (logLength <= DE_LENGTH_OF_ARRAY(buffer)) 756 { 757 if (written != logLength-1) 758 { 759 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << logLength-1 << "; got " << written << TestLog::EndMessage; 760 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 761 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length"); 762 } 763 } 764 765 // check null-terminator, either at end of buffer or at buffer[written] 766 const char* terminator = &buffer[DE_LENGTH_OF_ARRAY(buffer) - 1]; 767 if (logLength < DE_LENGTH_OF_ARRAY(buffer)) 768 terminator = &buffer[written]; 769 770 if (*terminator != '\0') 771 { 772 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator, got " << (int)*terminator << TestLog::EndMessage; 773 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 774 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log terminator"); 775 } 776 } 777 778 // check with too small buffer 779 { 780 char buffer[2048] = {'x'}; // non-zero initialization 781 782 // check string always ends with \0, even with small buffers 783 GLint written = 0; 784 glGetShaderInfoLog(shader, 1, &written, buffer); 785 if (written != 0) 786 { 787 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length 0; got " << written << TestLog::EndMessage; 788 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 789 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length"); 790 } 791 if (buffer[0] != '\0') 792 { 793 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator, got " << (int)buffer[0] << TestLog::EndMessage; 794 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 795 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log terminator"); 796 } 797 } 798 799 glDeleteShader(shader); 800 expectError(GL_NO_ERROR); 801 } 802 }; 803 804 class ShaderSourceCase : public ApiCase 805 { 806 public: 807 ShaderSourceCase (Context& context, const char* name, const char* description) 808 : ApiCase(context, name, description) 809 { 810 } 811 812 void test (void) 813 { 814 using tcu::TestLog; 815 816 // SHADER_SOURCE_LENGTH does include 0-terminator 817 const GLuint shader = glCreateShader(GL_VERTEX_SHADER); 818 verifyShaderParam(m_testCtx, *this, shader, GL_SHADER_SOURCE_LENGTH, 0); 819 820 // check the SHADER_SOURCE_LENGTH 821 { 822 glShaderSource(shader, 1, &brokenShader, DE_NULL); 823 expectError(GL_NO_ERROR); 824 825 StateQueryMemoryWriteGuard<GLint> sourceLength; 826 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength); 827 828 sourceLength.verifyValidity(m_testCtx); 829 830 const GLint referenceLength = (GLint)std::string(brokenShader).length() + 1; // including the null terminator 831 if (sourceLength != referenceLength) 832 { 833 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << referenceLength << "; got " << sourceLength << TestLog::EndMessage; 834 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 835 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length"); 836 } 837 } 838 839 // check the concat source SHADER_SOURCE_LENGTH 840 { 841 const char* shaders[] = {brokenShader, brokenShader}; 842 glShaderSource(shader, 2, shaders, DE_NULL); 843 expectError(GL_NO_ERROR); 844 845 StateQueryMemoryWriteGuard<GLint> sourceLength; 846 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength); 847 848 sourceLength.verifyValidity(m_testCtx); 849 850 const GLint referenceLength = 2 * (GLint)std::string(brokenShader).length() + 1; // including the null terminator 851 if (sourceLength != referenceLength) 852 { 853 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << referenceLength << "; got " << sourceLength << TestLog::EndMessage; 854 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 855 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length"); 856 } 857 } 858 859 // check the string length 860 { 861 char buffer[2048] = {'x'}; 862 DE_ASSERT(DE_LENGTH_OF_ARRAY(buffer) > 2 * (int)std::string(brokenShader).length()); 863 864 GLint written = 0; // not inluding null-terminator 865 glGetShaderSource(shader, DE_LENGTH_OF_ARRAY(buffer), &written, buffer); 866 867 const GLint referenceLength = 2 * (GLint)std::string(brokenShader).length(); 868 if (written != referenceLength) 869 { 870 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length " << referenceLength << "; got " << written << TestLog::EndMessage; 871 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 872 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length"); 873 } 874 // check null pointer at 875 else 876 { 877 if (buffer[referenceLength] != '\0') 878 { 879 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator at " << referenceLength << TestLog::EndMessage; 880 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 881 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "did not get a null terminator"); 882 } 883 } 884 } 885 886 // check with small buffer 887 { 888 char buffer[2048] = {'x'}; 889 890 GLint written = 0; 891 glGetShaderSource(shader, 1, &written, buffer); 892 893 if (written != 0) 894 { 895 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length 0; got " << written << TestLog::EndMessage; 896 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 897 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length"); 898 } 899 if (buffer[0] != '\0') 900 { 901 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator; got=" << int(buffer[0]) << ", char=" << buffer[0] << TestLog::EndMessage; 902 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 903 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid terminator"); 904 } 905 } 906 907 glDeleteShader(shader); 908 expectError(GL_NO_ERROR); 909 } 910 }; 911 912 class DeleteStatusCase : public ApiCase 913 { 914 public: 915 DeleteStatusCase (Context& context, const char* name, const char* description) 916 : ApiCase(context, name, description) 917 { 918 } 919 920 void test (void) 921 { 922 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 923 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 924 925 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL); 926 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL); 927 928 glCompileShader(shaderVert); 929 glCompileShader(shaderFrag); 930 expectError(GL_NO_ERROR); 931 932 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE); 933 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE); 934 935 GLuint shaderProg = glCreateProgram(); 936 glAttachShader(shaderProg, shaderVert); 937 glAttachShader(shaderProg, shaderFrag); 938 glLinkProgram(shaderProg); 939 expectError(GL_NO_ERROR); 940 941 verifyProgramParam (m_testCtx, *this, shaderProg, GL_LINK_STATUS, GL_TRUE); 942 943 verifyShaderParam (m_testCtx, *this, shaderVert, GL_DELETE_STATUS, GL_FALSE); 944 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_DELETE_STATUS, GL_FALSE); 945 verifyProgramParam (m_testCtx, *this, shaderProg, GL_DELETE_STATUS, GL_FALSE); 946 expectError(GL_NO_ERROR); 947 948 glUseProgram(shaderProg); 949 950 glDeleteShader(shaderVert); 951 glDeleteShader(shaderFrag); 952 glDeleteProgram(shaderProg); 953 expectError(GL_NO_ERROR); 954 955 verifyShaderParam (m_testCtx, *this, shaderVert, GL_DELETE_STATUS, GL_TRUE); 956 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_DELETE_STATUS, GL_TRUE); 957 verifyProgramParam (m_testCtx, *this, shaderProg, GL_DELETE_STATUS, GL_TRUE); 958 expectError(GL_NO_ERROR); 959 960 glUseProgram(0); 961 expectError(GL_NO_ERROR); 962 } 963 }; 964 965 class CurrentVertexAttribInitialCase : public ApiCase 966 { 967 public: 968 CurrentVertexAttribInitialCase (Context& context, const char* name, const char* description) 969 : ApiCase(context, name, description) 970 { 971 } 972 973 void test (void) 974 { 975 using tcu::TestLog; 976 977 int attribute_count = 16; 978 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count); 979 980 // initial 981 982 for (int index = 0; index < attribute_count; ++index) 983 { 984 StateQueryMemoryWriteGuard<GLfloat[4]> attribValue; 985 glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue); 986 attribValue.verifyValidity(m_testCtx); 987 988 if (attribValue[0] != 0.0f || attribValue[1] != 0.0f || attribValue[2] != 0.0f || attribValue[3] != 1.0f) 989 { 990 m_testCtx.getLog() << TestLog::Message 991 << "// ERROR: Expected [0, 0, 0, 1];" 992 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << "," << attribValue[3] << "]" 993 << TestLog::EndMessage; 994 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 995 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value"); 996 } 997 } 998 } 999 }; 1000 1001 class CurrentVertexAttribFloatCase : public ApiCase 1002 { 1003 public: 1004 CurrentVertexAttribFloatCase (Context& context, const char* name, const char* description) 1005 : ApiCase(context, name, description) 1006 { 1007 } 1008 1009 void test (void) 1010 { 1011 using tcu::TestLog; 1012 1013 de::Random rnd(0xabcdef); 1014 1015 int attribute_count = 16; 1016 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count); 1017 1018 // test write float/read float 1019 1020 for (int index = 0; index < attribute_count; ++index) 1021 { 1022 const GLfloat x = rnd.getFloat(-64000, 64000); 1023 const GLfloat y = rnd.getFloat(-64000, 64000); 1024 const GLfloat z = rnd.getFloat(-64000, 64000); 1025 const GLfloat w = rnd.getFloat(-64000, 64000); 1026 1027 glVertexAttrib4f(index, x, y, z, w); 1028 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w); 1029 } 1030 for (int index = 0; index < attribute_count; ++index) 1031 { 1032 const GLfloat x = rnd.getFloat(-64000, 64000); 1033 const GLfloat y = rnd.getFloat(-64000, 64000); 1034 const GLfloat z = rnd.getFloat(-64000, 64000); 1035 const GLfloat w = 1.0f; 1036 1037 glVertexAttrib3f(index, x, y, z); 1038 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w); 1039 } 1040 for (int index = 0; index < attribute_count; ++index) 1041 { 1042 const GLfloat x = rnd.getFloat(-64000, 64000); 1043 const GLfloat y = rnd.getFloat(-64000, 64000); 1044 const GLfloat z = 0.0f; 1045 const GLfloat w = 1.0f; 1046 1047 glVertexAttrib2f(index, x, y); 1048 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w); 1049 } 1050 for (int index = 0; index < attribute_count; ++index) 1051 { 1052 const GLfloat x = rnd.getFloat(-64000, 64000); 1053 const GLfloat y = 0.0f; 1054 const GLfloat z = 0.0f; 1055 const GLfloat w = 1.0f; 1056 1057 glVertexAttrib1f(index, x); 1058 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w); 1059 } 1060 } 1061 }; 1062 1063 class CurrentVertexAttribIntCase : public ApiCase 1064 { 1065 public: 1066 CurrentVertexAttribIntCase (Context& context, const char* name, const char* description) 1067 : ApiCase(context, name, description) 1068 { 1069 } 1070 1071 void test (void) 1072 { 1073 using tcu::TestLog; 1074 1075 de::Random rnd(0xabcdef); 1076 1077 int attribute_count = 16; 1078 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count); 1079 1080 // test write float/read float 1081 1082 for (int index = 0; index < attribute_count; ++index) 1083 { 1084 const GLint x = rnd.getInt(-64000, 64000); 1085 const GLint y = rnd.getInt(-64000, 64000); 1086 const GLint z = rnd.getInt(-64000, 64000); 1087 const GLint w = rnd.getInt(-64000, 64000); 1088 1089 glVertexAttribI4i(index, x, y, z, w); 1090 verifyCurrentVertexAttribIi(m_testCtx, *this, index, x, y, z, w); 1091 } 1092 } 1093 }; 1094 1095 class CurrentVertexAttribUintCase : public ApiCase 1096 { 1097 public: 1098 CurrentVertexAttribUintCase (Context& context, const char* name, const char* description) 1099 : ApiCase(context, name, description) 1100 { 1101 } 1102 1103 void test (void) 1104 { 1105 using tcu::TestLog; 1106 1107 de::Random rnd(0xabcdef); 1108 1109 int attribute_count = 16; 1110 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count); 1111 1112 // test write float/read float 1113 1114 for (int index = 0; index < attribute_count; ++index) 1115 { 1116 const GLuint x = rnd.getInt(0, 64000); 1117 const GLuint y = rnd.getInt(0, 64000); 1118 const GLuint z = rnd.getInt(0, 64000); 1119 const GLuint w = rnd.getInt(0, 64000); 1120 1121 glVertexAttribI4ui(index, x, y, z, w); 1122 verifyCurrentVertexAttribIui(m_testCtx, *this, index, x, y, z, w); 1123 } 1124 } 1125 }; 1126 1127 class CurrentVertexAttribConversionCase : public ApiCase 1128 { 1129 public: 1130 CurrentVertexAttribConversionCase (Context& context, const char* name, const char* description) 1131 : ApiCase(context, name, description) 1132 { 1133 } 1134 1135 void test (void) 1136 { 1137 using tcu::TestLog; 1138 1139 de::Random rnd(0xabcdef); 1140 1141 int attribute_count = 16; 1142 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count); 1143 1144 // test write float/read float 1145 1146 for (int index = 0; index < attribute_count; ++index) 1147 { 1148 const GLfloat x = rnd.getFloat(-64000, 64000); 1149 const GLfloat y = rnd.getFloat(-64000, 64000); 1150 const GLfloat z = rnd.getFloat(-64000, 64000); 1151 const GLfloat w = rnd.getFloat(-64000, 64000); 1152 1153 glVertexAttrib4f(index, x, y, z, w); 1154 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w); 1155 } 1156 for (int index = 0; index < attribute_count; ++index) 1157 { 1158 const GLfloat x = rnd.getFloat(-64000, 64000); 1159 const GLfloat y = rnd.getFloat(-64000, 64000); 1160 const GLfloat z = rnd.getFloat(-64000, 64000); 1161 const GLfloat w = 1.0f; 1162 1163 glVertexAttrib3f(index, x, y, z); 1164 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w); 1165 } 1166 for (int index = 0; index < attribute_count; ++index) 1167 { 1168 const GLfloat x = rnd.getFloat(-64000, 64000); 1169 const GLfloat y = rnd.getFloat(-64000, 64000); 1170 const GLfloat z = 0.0f; 1171 const GLfloat w = 1.0f; 1172 1173 glVertexAttrib2f(index, x, y); 1174 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w); 1175 } 1176 for (int index = 0; index < attribute_count; ++index) 1177 { 1178 const GLfloat x = rnd.getFloat(-64000, 64000); 1179 const GLfloat y = 0.0f; 1180 const GLfloat z = 0.0f; 1181 const GLfloat w = 1.0f; 1182 1183 glVertexAttrib1f(index, x); 1184 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w); 1185 } 1186 } 1187 }; 1188 1189 class ProgramInfoLogCase : public ApiCase 1190 { 1191 public: 1192 ProgramInfoLogCase (Context& context, const char* name, const char* description) 1193 : ApiCase(context, name, description) 1194 { 1195 } 1196 1197 void test (void) 1198 { 1199 using tcu::TestLog; 1200 1201 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1202 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1203 1204 glShaderSource(shaderVert, 1, &brokenShader, DE_NULL); 1205 glShaderSource(shaderFrag, 1, &brokenShader, DE_NULL); 1206 1207 glCompileShader(shaderVert); 1208 glCompileShader(shaderFrag); 1209 expectError(GL_NO_ERROR); 1210 1211 GLuint program = glCreateProgram(); 1212 glAttachShader(program, shaderVert); 1213 glAttachShader(program, shaderFrag); 1214 glLinkProgram(program); 1215 1216 // check INFO_LOG_LENGTH == GetProgramInfoLog len 1217 { 1218 char buffer[2048] = {'x'}; 1219 1220 GLint written = 0; 1221 glGetProgramInfoLog(program, DE_LENGTH_OF_ARRAY(buffer), &written, buffer); 1222 1223 StateQueryMemoryWriteGuard<GLint> logLength; 1224 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); 1225 logLength.verifyValidity(m_testCtx); 1226 1227 if (logLength != 0 && written+1 != logLength) // INFO_LOG_LENGTH contains 0-terminator 1228 { 1229 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected INFO_LOG_LENGTH " << written+1 << "; got " << logLength << TestLog::EndMessage; 1230 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1231 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length"); 1232 } 1233 } 1234 1235 // check GetProgramInfoLog works with too small buffer 1236 { 1237 char buffer[2048] = {'x'}; 1238 1239 GLint written = 0; 1240 glGetProgramInfoLog(program, 1, &written, buffer); 1241 1242 if (written != 0) 1243 { 1244 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length 0; got " << written << TestLog::EndMessage; 1245 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1246 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length"); 1247 } 1248 } 1249 1250 glDeleteShader(shaderVert); 1251 glDeleteShader(shaderFrag); 1252 glDeleteProgram(program); 1253 expectError(GL_NO_ERROR); 1254 } 1255 }; 1256 1257 class ProgramValidateStatusCase : public ApiCase 1258 { 1259 public: 1260 ProgramValidateStatusCase (Context& context, const char* name, const char* description) 1261 : ApiCase(context, name, description) 1262 { 1263 } 1264 1265 void test (void) 1266 { 1267 // test validate ok 1268 { 1269 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1270 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1271 1272 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL); 1273 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL); 1274 1275 glCompileShader(shaderVert); 1276 glCompileShader(shaderFrag); 1277 expectError(GL_NO_ERROR); 1278 1279 GLuint program = glCreateProgram(); 1280 glAttachShader(program, shaderVert); 1281 glAttachShader(program, shaderFrag); 1282 glLinkProgram(program); 1283 expectError(GL_NO_ERROR); 1284 1285 verifyShaderParam (m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE); 1286 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE); 1287 verifyProgramParam (m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE); 1288 1289 glValidateProgram(program); 1290 verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_TRUE); 1291 1292 glDeleteShader(shaderVert); 1293 glDeleteShader(shaderFrag); 1294 glDeleteProgram(program); 1295 expectError(GL_NO_ERROR); 1296 } 1297 1298 // test with broken shader 1299 { 1300 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1301 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1302 1303 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL); 1304 glShaderSource(shaderFrag, 1, &brokenShader, DE_NULL); 1305 1306 glCompileShader(shaderVert); 1307 glCompileShader(shaderFrag); 1308 expectError(GL_NO_ERROR); 1309 1310 GLuint program = glCreateProgram(); 1311 glAttachShader(program, shaderVert); 1312 glAttachShader(program, shaderFrag); 1313 glLinkProgram(program); 1314 expectError(GL_NO_ERROR); 1315 1316 verifyShaderParam (m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE); 1317 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_FALSE); 1318 verifyProgramParam (m_testCtx, *this, program, GL_LINK_STATUS, GL_FALSE); 1319 1320 glValidateProgram(program); 1321 verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_FALSE); 1322 1323 glDeleteShader(shaderVert); 1324 glDeleteShader(shaderFrag); 1325 glDeleteProgram(program); 1326 expectError(GL_NO_ERROR); 1327 } 1328 } 1329 }; 1330 1331 class ProgramAttachedShadersCase : public ApiCase 1332 { 1333 public: 1334 ProgramAttachedShadersCase (Context& context, const char* name, const char* description) 1335 : ApiCase(context, name, description) 1336 { 1337 } 1338 1339 void test (void) 1340 { 1341 using tcu::TestLog; 1342 1343 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1344 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1345 1346 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL); 1347 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL); 1348 1349 glCompileShader(shaderVert); 1350 glCompileShader(shaderFrag); 1351 expectError(GL_NO_ERROR); 1352 1353 // check ATTACHED_SHADERS 1354 1355 GLuint program = glCreateProgram(); 1356 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 0); 1357 expectError(GL_NO_ERROR); 1358 1359 glAttachShader(program, shaderVert); 1360 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 1); 1361 expectError(GL_NO_ERROR); 1362 1363 glAttachShader(program, shaderFrag); 1364 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 2); 1365 expectError(GL_NO_ERROR); 1366 1367 // check GetAttachedShaders 1368 { 1369 GLuint shaders[2] = {0, 0}; 1370 GLint count = 0; 1371 glGetAttachedShaders(program, DE_LENGTH_OF_ARRAY(shaders), &count, shaders); 1372 1373 if (count != 2) 1374 { 1375 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 2; got " << count << TestLog::EndMessage; 1376 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1377 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count"); 1378 } 1379 // shaders are the attached shaders? 1380 if (!((shaders[0] == shaderVert && shaders[1] == shaderFrag) || 1381 (shaders[0] == shaderFrag && shaders[1] == shaderVert))) 1382 { 1383 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected {" << shaderVert << ", " << shaderFrag << "}; got {" << shaders[0] << ", " << shaders[1] << "}" << TestLog::EndMessage; 1384 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1385 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count"); 1386 } 1387 } 1388 1389 // check GetAttachedShaders with too small buffer 1390 { 1391 GLuint shaders[2] = {0, 0}; 1392 GLint count = 0; 1393 1394 glGetAttachedShaders(program, 0, &count, shaders); 1395 if (count != 0) 1396 { 1397 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0; got " << count << TestLog::EndMessage; 1398 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1399 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count"); 1400 } 1401 1402 count = 0; 1403 glGetAttachedShaders(program, 1, &count, shaders); 1404 if (count != 1) 1405 { 1406 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 1; got " << count << TestLog::EndMessage; 1407 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1408 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count"); 1409 } 1410 } 1411 1412 glDeleteShader(shaderVert); 1413 glDeleteShader(shaderFrag); 1414 glDeleteProgram(program); 1415 expectError(GL_NO_ERROR); 1416 } 1417 }; 1418 1419 class ProgramActiveUniformNameCase : public ApiCase 1420 { 1421 public: 1422 ProgramActiveUniformNameCase (Context& context, const char* name, const char* description) 1423 : ApiCase(context, name, description) 1424 { 1425 } 1426 1427 void test (void) 1428 { 1429 using tcu::TestLog; 1430 1431 static const char* testVertSource = 1432 "#version 300 es\n" 1433 "uniform highp float uniformNameWithLength23;\n" 1434 "uniform highp vec2 uniformVec2;\n" 1435 "uniform highp mat4 uniformMat4;\n" 1436 "void main (void)\n" 1437 "{\n" 1438 " gl_Position = vec4(0.0) + vec4(uniformNameWithLength23) + vec4(uniformVec2.x) + vec4(uniformMat4[2][3]);\n" 1439 "}\n\0"; 1440 static const char* testFragSource = 1441 "#version 300 es\n" 1442 "layout(location = 0) out mediump vec4 fragColor;" 1443 "void main (void)\n" 1444 "{\n" 1445 " fragColor = vec4(0.0);\n" 1446 "}\n\0"; 1447 1448 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1449 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1450 1451 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); 1452 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); 1453 1454 glCompileShader(shaderVert); 1455 glCompileShader(shaderFrag); 1456 expectError(GL_NO_ERROR); 1457 1458 GLuint program = glCreateProgram(); 1459 glAttachShader(program, shaderVert); 1460 glAttachShader(program, shaderFrag); 1461 glLinkProgram(program); 1462 expectError(GL_NO_ERROR); 1463 1464 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORMS, 3); 1465 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, (GLint)std::string("uniformNameWithLength23").length() + 1); // including a null terminator 1466 expectError(GL_NO_ERROR); 1467 1468 const char* uniformNames[] = 1469 { 1470 "uniformNameWithLength23", 1471 "uniformVec2", 1472 "uniformMat4" 1473 }; 1474 StateQueryMemoryWriteGuard<GLuint[DE_LENGTH_OF_ARRAY(uniformNames)]> uniformIndices; 1475 glGetUniformIndices(program, DE_LENGTH_OF_ARRAY(uniformNames), uniformNames, uniformIndices); 1476 uniformIndices.verifyValidity(m_testCtx); 1477 1478 // check name lengths 1479 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformNames); ++ndx) 1480 { 1481 const GLuint uniformIndex = uniformIndices[ndx]; 1482 1483 StateQueryMemoryWriteGuard<GLint> uniformNameLen; 1484 glGetActiveUniformsiv(program, 1, &uniformIndex, GL_UNIFORM_NAME_LENGTH, &uniformNameLen); 1485 1486 uniformNameLen.verifyValidity(m_testCtx); 1487 1488 const GLint referenceLength = (GLint)std::string(uniformNames[ndx]).length() + 1; 1489 if (referenceLength != uniformNameLen) // uniformNameLen is with null terminator 1490 { 1491 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << referenceLength << "got " << uniformNameLen << TestLog::EndMessage; 1492 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1493 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name length"); 1494 } 1495 } 1496 1497 // check names 1498 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformNames); ++ndx) 1499 { 1500 char buffer[2048] = {'x'}; 1501 1502 const GLuint uniformIndex = uniformIndices[ndx]; 1503 1504 GLint written = 0; // null terminator not included 1505 GLint size = 0; 1506 GLenum type = 0; 1507 glGetActiveUniform(program, uniformIndex, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer); 1508 1509 const GLint referenceLength = (GLint)std::string(uniformNames[ndx]).length(); 1510 if (referenceLength != written) 1511 { 1512 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << referenceLength << "got " << written << TestLog::EndMessage; 1513 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1514 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name length"); 1515 } 1516 1517 // and with too small buffer 1518 written = 0; 1519 glGetActiveUniform(program, uniformIndex, 1, &written, &size, &type, buffer); 1520 1521 if (written != 0) 1522 { 1523 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0 got " << written << TestLog::EndMessage; 1524 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1525 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name length"); 1526 } 1527 } 1528 1529 1530 glDeleteShader(shaderVert); 1531 glDeleteShader(shaderFrag); 1532 glDeleteProgram(program); 1533 expectError(GL_NO_ERROR); 1534 } 1535 }; 1536 1537 class ProgramUniformCase : public ApiCase 1538 { 1539 public: 1540 ProgramUniformCase (Context& context, const char* name, const char* description) 1541 : ApiCase(context, name, description) 1542 { 1543 } 1544 1545 void test (void) 1546 { 1547 const struct UniformType 1548 { 1549 const char* declaration; 1550 const char* postDeclaration; 1551 const char* precision; 1552 const char* layout; 1553 const char* getter; 1554 GLenum type; 1555 GLint size; 1556 GLint isRowMajor; 1557 } uniformTypes[] = 1558 { 1559 { "float", "", "highp", "", "uniformValue", GL_FLOAT, 1, GL_FALSE }, 1560 { "float[2]", "", "highp", "", "uniformValue[1]", GL_FLOAT, 2, GL_FALSE }, 1561 { "vec2", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC2, 1, GL_FALSE }, 1562 { "vec3", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC3, 1, GL_FALSE }, 1563 { "vec4", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC4, 1, GL_FALSE }, 1564 { "int", "", "highp", "", "float(uniformValue)", GL_INT, 1, GL_FALSE }, 1565 { "ivec2", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC2, 1, GL_FALSE }, 1566 { "ivec3", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC3, 1, GL_FALSE }, 1567 { "ivec4", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC4, 1, GL_FALSE }, 1568 { "uint", "", "highp", "", "float(uniformValue)", GL_UNSIGNED_INT, 1, GL_FALSE }, 1569 { "uvec2", "", "highp", "", "float(uniformValue.x)", GL_UNSIGNED_INT_VEC2, 1, GL_FALSE }, 1570 { "uvec3", "", "highp", "", "float(uniformValue.x)", GL_UNSIGNED_INT_VEC3, 1, GL_FALSE }, 1571 { "uvec4", "", "highp", "", "float(uniformValue.x)", GL_UNSIGNED_INT_VEC4, 1, GL_FALSE }, 1572 { "bool", "", "", "", "float(uniformValue)", GL_BOOL, 1, GL_FALSE }, 1573 { "bvec2", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC2, 1, GL_FALSE }, 1574 { "bvec3", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC3, 1, GL_FALSE }, 1575 { "bvec4", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC4, 1, GL_FALSE }, 1576 { "mat2", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT2, 1, GL_FALSE }, 1577 { "mat3", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT3, 1, GL_FALSE }, 1578 { "mat4", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT4, 1, GL_FALSE }, 1579 { "mat2x3", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT2x3, 1, GL_FALSE }, 1580 { "mat2x4", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT2x4, 1, GL_FALSE }, 1581 { "mat3x2", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT3x2, 1, GL_FALSE }, 1582 { "mat3x4", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT3x4, 1, GL_FALSE }, 1583 { "mat4x2", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT4x2, 1, GL_FALSE }, 1584 { "mat4x3", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT4x3, 1, GL_FALSE }, 1585 { "sampler2D", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_SAMPLER_2D, 1, GL_FALSE }, 1586 { "sampler3D", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_SAMPLER_3D, 1, GL_FALSE }, 1587 { "samplerCube", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_SAMPLER_CUBE, 1, GL_FALSE }, 1588 { "sampler2DShadow", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_SAMPLER_2D_SHADOW, 1, GL_FALSE }, 1589 { "sampler2DArray", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_SAMPLER_2D_ARRAY, 1, GL_FALSE }, 1590 { "sampler2DArrayShadow", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_SAMPLER_2D_ARRAY_SHADOW, 1, GL_FALSE }, 1591 { "samplerCubeShadow", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_SAMPLER_CUBE_SHADOW, 1, GL_FALSE }, 1592 { "isampler2D", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_INT_SAMPLER_2D, 1, GL_FALSE }, 1593 { "isampler3D", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_INT_SAMPLER_3D, 1, GL_FALSE }, 1594 { "isamplerCube", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_INT_SAMPLER_CUBE, 1, GL_FALSE }, 1595 { "isampler2DArray", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_INT_SAMPLER_2D_ARRAY, 1, GL_FALSE }, 1596 { "usampler2D", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_UNSIGNED_INT_SAMPLER_2D, 1, GL_FALSE }, 1597 { "usampler3D", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_UNSIGNED_INT_SAMPLER_3D, 1, GL_FALSE }, 1598 { "usamplerCube", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_UNSIGNED_INT_SAMPLER_CUBE, 1, GL_FALSE }, 1599 { "usampler2DArray", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, 1, GL_FALSE }, 1600 }; 1601 1602 static const char* vertSource = 1603 "#version 300 es\n" 1604 "void main (void)\n" 1605 "{\n" 1606 " gl_Position = vec4(0.0);\n" 1607 "}\n\0"; 1608 1609 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1610 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1611 GLuint program = glCreateProgram(); 1612 1613 glAttachShader(program, shaderVert); 1614 glAttachShader(program, shaderFrag); 1615 1616 glShaderSource(shaderVert, 1, &vertSource, DE_NULL); 1617 glCompileShader(shaderVert); 1618 expectError(GL_NO_ERROR); 1619 1620 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformTypes); ++ndx) 1621 { 1622 tcu::ScopedLogSection(m_log, uniformTypes[ndx].declaration, std::string("Verify type of ") + uniformTypes[ndx].declaration + " variable" + uniformTypes[ndx].postDeclaration ); 1623 1624 // gen fragment shader 1625 1626 std::ostringstream frag; 1627 frag << "#version 300 es\n"; 1628 frag << uniformTypes[ndx].layout << "uniform " << uniformTypes[ndx].precision << " " << uniformTypes[ndx].declaration << " uniformValue" << uniformTypes[ndx].postDeclaration << ";\n"; 1629 frag << "layout(location = 0) out mediump vec4 fragColor;\n"; 1630 frag << "void main (void)\n"; 1631 frag << "{\n"; 1632 frag << " fragColor = vec4(" << uniformTypes[ndx].getter << ");\n"; 1633 frag << "}\n"; 1634 1635 { 1636 std::string fragmentSource = frag.str(); 1637 const char* fragmentSourceCStr = fragmentSource.c_str(); 1638 glShaderSource(shaderFrag, 1, &fragmentSourceCStr, DE_NULL); 1639 } 1640 1641 // compile & link 1642 1643 glCompileShader(shaderFrag); 1644 glLinkProgram(program); 1645 1646 // test 1647 if (verifyProgramParam(m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE)) 1648 { 1649 const char* uniformNames[] = {"uniformValue"}; 1650 StateQueryMemoryWriteGuard<GLuint> uniformIndex; 1651 glGetUniformIndices(program, 1, uniformNames, &uniformIndex); 1652 uniformIndex.verifyValidity(m_testCtx); 1653 1654 verifyActiveUniformParam(m_testCtx, *this, program, uniformIndex, GL_UNIFORM_TYPE, uniformTypes[ndx].type); 1655 verifyActiveUniformParam(m_testCtx, *this, program, uniformIndex, GL_UNIFORM_SIZE, uniformTypes[ndx].size); 1656 verifyActiveUniformParam(m_testCtx, *this, program, uniformIndex, GL_UNIFORM_IS_ROW_MAJOR, uniformTypes[ndx].isRowMajor); 1657 } 1658 } 1659 1660 glDeleteShader(shaderVert); 1661 glDeleteShader(shaderFrag); 1662 glDeleteProgram(program); 1663 expectError(GL_NO_ERROR); 1664 } 1665 }; 1666 1667 class ProgramActiveUniformBlocksCase : public ApiCase 1668 { 1669 public: 1670 ProgramActiveUniformBlocksCase (Context& context, const char* name, const char* description) 1671 : ApiCase(context, name, description) 1672 { 1673 } 1674 1675 void test (void) 1676 { 1677 using tcu::TestLog; 1678 1679 static const char* testVertSource = 1680 "#version 300 es\n" 1681 "uniform longlongUniformBlockName {highp vec2 vector2;} longlongUniformInstanceName;\n" 1682 "uniform shortUniformBlockName {highp vec2 vector2;highp vec4 vector4;} shortUniformInstanceName;\n" 1683 "void main (void)\n" 1684 "{\n" 1685 " gl_Position = shortUniformInstanceName.vector4 + vec4(longlongUniformInstanceName.vector2.x) + vec4(shortUniformInstanceName.vector2.x);\n" 1686 "}\n\0"; 1687 static const char* testFragSource = 1688 "#version 300 es\n" 1689 "uniform longlongUniformBlockName {highp vec2 vector2;} longlongUniformInstanceName;\n" 1690 "layout(location = 0) out mediump vec4 fragColor;" 1691 "void main (void)\n" 1692 "{\n" 1693 " fragColor = vec4(longlongUniformInstanceName.vector2.y);\n" 1694 "}\n\0"; 1695 1696 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1697 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1698 1699 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); 1700 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); 1701 1702 glCompileShader(shaderVert); 1703 glCompileShader(shaderFrag); 1704 expectError(GL_NO_ERROR); 1705 1706 GLuint program = glCreateProgram(); 1707 glAttachShader(program, shaderVert); 1708 glAttachShader(program, shaderFrag); 1709 glLinkProgram(program); 1710 expectError(GL_NO_ERROR); 1711 1712 verifyShaderParam (m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE); 1713 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE); 1714 verifyProgramParam (m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE); 1715 1716 verifyProgramParam (m_testCtx, *this, program, GL_ACTIVE_UNIFORM_BLOCKS, 2); 1717 verifyProgramParam (m_testCtx, *this, program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, (GLint)std::string("longlongUniformBlockName").length() + 1); // including a null terminator 1718 expectError(GL_NO_ERROR); 1719 1720 GLint longlongUniformBlockIndex = glGetUniformBlockIndex(program, "longlongUniformBlockName"); 1721 GLint shortUniformBlockIndex = glGetUniformBlockIndex(program, "shortUniformBlockName"); 1722 1723 const char* uniformNames[] = 1724 { 1725 "longlongUniformBlockName.vector2", 1726 "shortUniformBlockName.vector2", 1727 "shortUniformBlockName.vector4" 1728 }; 1729 1730 // test UNIFORM_BLOCK_INDEX 1731 1732 DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(uniformNames) == 3); 1733 1734 StateQueryMemoryWriteGuard<GLuint[DE_LENGTH_OF_ARRAY(uniformNames)]> uniformIndices; 1735 StateQueryMemoryWriteGuard<GLint[DE_LENGTH_OF_ARRAY(uniformNames)]> uniformsBlockIndices; 1736 1737 glGetUniformIndices(program, DE_LENGTH_OF_ARRAY(uniformNames), uniformNames, uniformIndices); 1738 uniformIndices.verifyValidity(m_testCtx); 1739 expectError(GL_NO_ERROR); 1740 1741 glGetActiveUniformsiv(program, DE_LENGTH_OF_ARRAY(uniformNames), uniformIndices, GL_UNIFORM_BLOCK_INDEX, uniformsBlockIndices); 1742 uniformsBlockIndices.verifyValidity(m_testCtx); 1743 expectError(GL_NO_ERROR); 1744 1745 if (uniformsBlockIndices[0] != longlongUniformBlockIndex || 1746 uniformsBlockIndices[1] != shortUniformBlockIndex || 1747 uniformsBlockIndices[2] != shortUniformBlockIndex) 1748 { 1749 m_testCtx.getLog() << TestLog::Message 1750 << "// ERROR: Expected [" << longlongUniformBlockIndex << ", " << shortUniformBlockIndex << ", " << shortUniformBlockIndex << "];" 1751 << "got [" << uniformsBlockIndices[0] << ", " << uniformsBlockIndices[1] << ", " << uniformsBlockIndices[2] << "]" << TestLog::EndMessage; 1752 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1753 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform block index"); 1754 } 1755 1756 // test UNIFORM_BLOCK_NAME_LENGTH 1757 1758 verifyActiveUniformBlockParam(m_testCtx, *this, program, longlongUniformBlockIndex, GL_UNIFORM_BLOCK_NAME_LENGTH, (GLint)std::string("longlongUniformBlockName").length() + 1); // including null-terminator 1759 verifyActiveUniformBlockParam(m_testCtx, *this, program, shortUniformBlockIndex, GL_UNIFORM_BLOCK_NAME_LENGTH, (GLint)std::string("shortUniformBlockName").length() + 1); // including null-terminator 1760 expectError(GL_NO_ERROR); 1761 1762 // test UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER & UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 1763 1764 verifyActiveUniformBlockParam(m_testCtx, *this, program, longlongUniformBlockIndex, GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, GL_TRUE); 1765 verifyActiveUniformBlockParam(m_testCtx, *this, program, longlongUniformBlockIndex, GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, GL_TRUE); 1766 verifyActiveUniformBlockParam(m_testCtx, *this, program, shortUniformBlockIndex, GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, GL_TRUE); 1767 verifyActiveUniformBlockParam(m_testCtx, *this, program, shortUniformBlockIndex, GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, GL_FALSE); 1768 expectError(GL_NO_ERROR); 1769 1770 // test UNIFORM_BLOCK_ACTIVE_UNIFORMS 1771 1772 verifyActiveUniformBlockParam(m_testCtx, *this, program, longlongUniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, 1); 1773 verifyActiveUniformBlockParam(m_testCtx, *this, program, shortUniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, 2); 1774 expectError(GL_NO_ERROR); 1775 1776 // test UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 1777 1778 { 1779 StateQueryMemoryWriteGuard<GLint> longlongUniformBlockUniforms; 1780 glGetActiveUniformBlockiv(program, longlongUniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &longlongUniformBlockUniforms); 1781 longlongUniformBlockUniforms.verifyValidity(m_testCtx); 1782 1783 if (longlongUniformBlockUniforms == 2) 1784 { 1785 StateQueryMemoryWriteGuard<GLint[2]> longlongUniformBlockUniformIndices; 1786 glGetActiveUniformBlockiv(program, longlongUniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, longlongUniformBlockUniformIndices); 1787 longlongUniformBlockUniformIndices.verifyValidity(m_testCtx); 1788 1789 if ((GLuint(longlongUniformBlockUniformIndices[0]) != uniformIndices[0] || GLuint(longlongUniformBlockUniformIndices[1]) != uniformIndices[1]) && 1790 (GLuint(longlongUniformBlockUniformIndices[1]) != uniformIndices[0] || GLuint(longlongUniformBlockUniformIndices[0]) != uniformIndices[1])) 1791 { 1792 m_testCtx.getLog() << TestLog::Message 1793 << "// ERROR: Expected {" << uniformIndices[0] << ", " << uniformIndices[1] << "};" 1794 << "got {" << longlongUniformBlockUniformIndices[0] << ", " << longlongUniformBlockUniformIndices[1] << "}" << TestLog::EndMessage; 1795 1796 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1797 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform indices"); 1798 } 1799 1800 } 1801 } 1802 1803 // check block names 1804 1805 { 1806 char buffer[2048] = {'x'}; 1807 GLint written = 0; 1808 glGetActiveUniformBlockName(program, longlongUniformBlockIndex, DE_LENGTH_OF_ARRAY(buffer), &written, buffer); 1809 checkIntEquals(m_testCtx, written, (GLint)std::string("longlongUniformBlockName").length()); 1810 1811 written = 0; 1812 glGetActiveUniformBlockName(program, shortUniformBlockIndex, DE_LENGTH_OF_ARRAY(buffer), &written, buffer); 1813 checkIntEquals(m_testCtx, written, (GLint)std::string("shortUniformBlockName").length()); 1814 1815 // and one with too small buffer 1816 written = 0; 1817 glGetActiveUniformBlockName(program, longlongUniformBlockIndex, 1, &written, buffer); 1818 checkIntEquals(m_testCtx, written, 0); 1819 } 1820 1821 expectError(GL_NO_ERROR); 1822 glDeleteShader(shaderVert); 1823 glDeleteShader(shaderFrag); 1824 glDeleteProgram(program); 1825 expectError(GL_NO_ERROR); 1826 } 1827 }; 1828 1829 class ProgramBinaryCase : public ApiCase 1830 { 1831 public: 1832 ProgramBinaryCase (Context& context, const char* name, const char* description) 1833 : ApiCase(context, name, description) 1834 { 1835 } 1836 1837 void test (void) 1838 { 1839 using tcu::TestLog; 1840 1841 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1842 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1843 1844 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL); 1845 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL); 1846 1847 glCompileShader(shaderVert); 1848 glCompileShader(shaderFrag); 1849 expectError(GL_NO_ERROR); 1850 1851 GLuint program = glCreateProgram(); 1852 glAttachShader(program, shaderVert); 1853 glAttachShader(program, shaderFrag); 1854 glLinkProgram(program); 1855 expectError(GL_NO_ERROR); 1856 1857 // test PROGRAM_BINARY_RETRIEVABLE_HINT 1858 verifyProgramParam(m_testCtx, *this, program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_FALSE); 1859 1860 glProgramParameteri(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); 1861 expectError(GL_NO_ERROR); 1862 1863 glLinkProgram(program); 1864 expectError(GL_NO_ERROR); 1865 1866 verifyProgramParam(m_testCtx, *this, program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); 1867 1868 // test PROGRAM_BINARY_LENGTH does something 1869 1870 StateQueryMemoryWriteGuard<GLint> programLength; 1871 glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &programLength); 1872 expectError(GL_NO_ERROR); 1873 programLength.verifyValidity(m_testCtx); 1874 1875 glDeleteShader(shaderVert); 1876 glDeleteShader(shaderFrag); 1877 glDeleteProgram(program); 1878 expectError(GL_NO_ERROR); 1879 } 1880 }; 1881 1882 class TransformFeedbackCase : public ApiCase 1883 { 1884 public: 1885 TransformFeedbackCase (Context& context, const char* name, const char* description) 1886 : ApiCase(context, name, description) 1887 { 1888 } 1889 1890 void test (void) 1891 { 1892 using tcu::TestLog; 1893 1894 static const char* transformFeedbackTestVertSource = 1895 "#version 300 es\n" 1896 "out highp vec4 tfOutput2withLongName;\n" 1897 "void main (void)\n" 1898 "{\n" 1899 " gl_Position = vec4(0.0);\n" 1900 " tfOutput2withLongName = vec4(0.0);\n" 1901 "}\n"; 1902 static const char* transformFeedbackTestFragSource = 1903 "#version 300 es\n" 1904 "layout(location = 0) out highp vec4 fragColor;\n" 1905 "void main (void)\n" 1906 "{\n" 1907 " fragColor = vec4(0.0);\n" 1908 "}\n"; 1909 1910 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1911 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1912 GLuint shaderProg = glCreateProgram(); 1913 1914 verifyProgramParam(m_testCtx, *this, shaderProg, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, GL_INTERLEAVED_ATTRIBS); 1915 1916 glShaderSource(shaderVert, 1, &transformFeedbackTestVertSource, DE_NULL); 1917 glShaderSource(shaderFrag, 1, &transformFeedbackTestFragSource, DE_NULL); 1918 1919 glCompileShader(shaderVert); 1920 glCompileShader(shaderFrag); 1921 1922 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE); 1923 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE); 1924 1925 glAttachShader(shaderProg, shaderVert); 1926 glAttachShader(shaderProg, shaderFrag); 1927 1928 // check TRANSFORM_FEEDBACK_BUFFER_MODE 1929 1930 const char* transform_feedback_outputs[] = {"gl_Position", "tfOutput2withLongName"}; 1931 const char* longest_output = transform_feedback_outputs[1]; 1932 const GLenum bufferModes[] = {GL_SEPARATE_ATTRIBS, GL_INTERLEAVED_ATTRIBS}; 1933 1934 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bufferModes); ++ndx) 1935 { 1936 glTransformFeedbackVaryings(shaderProg, DE_LENGTH_OF_ARRAY(transform_feedback_outputs), transform_feedback_outputs, bufferModes[ndx]); 1937 glLinkProgram(shaderProg); 1938 expectError(GL_NO_ERROR); 1939 1940 verifyProgramParam(m_testCtx, *this, shaderProg, GL_LINK_STATUS, GL_TRUE); 1941 verifyProgramParam(m_testCtx, *this, shaderProg, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, bufferModes[ndx]); 1942 } 1943 1944 // TRANSFORM_FEEDBACK_VARYINGS 1945 verifyProgramParam(m_testCtx, *this, shaderProg, GL_TRANSFORM_FEEDBACK_VARYINGS, 2); 1946 1947 // TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 1948 { 1949 StateQueryMemoryWriteGuard<GLint> maxOutputLen; 1950 glGetProgramiv(shaderProg, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &maxOutputLen); 1951 1952 maxOutputLen.verifyValidity(m_testCtx); 1953 1954 const GLint referenceLength = (GLint)std::string(longest_output).length() + 1; 1955 checkIntEquals(m_testCtx, maxOutputLen, referenceLength); 1956 } 1957 1958 // check varyings 1959 { 1960 StateQueryMemoryWriteGuard<GLint> varyings; 1961 glGetProgramiv(shaderProg, GL_TRANSFORM_FEEDBACK_VARYINGS, &varyings); 1962 1963 if (!varyings.isUndefined()) 1964 for (int index = 0; index < varyings; ++index) 1965 { 1966 char buffer[2048] = {'x'}; 1967 1968 GLint written = 0; 1969 GLint size = 0; 1970 GLenum type = 0; 1971 glGetTransformFeedbackVarying(shaderProg, index, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer); 1972 1973 if (written < DE_LENGTH_OF_ARRAY(buffer) && buffer[written] != '\0') 1974 { 1975 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator" << TestLog::EndMessage; 1976 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1977 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid string terminator"); 1978 } 1979 1980 // check with too small buffer 1981 written = 0; 1982 glGetTransformFeedbackVarying(shaderProg, index, 1, &written, &size, &type, buffer); 1983 if (written != 0) 1984 { 1985 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0; got " << written << TestLog::EndMessage; 1986 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1987 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid write length"); 1988 } 1989 } 1990 } 1991 1992 1993 glDeleteShader(shaderVert); 1994 glDeleteShader(shaderFrag); 1995 glDeleteProgram(shaderProg); 1996 expectError(GL_NO_ERROR); 1997 } 1998 }; 1999 2000 class ActiveAttributesCase : public ApiCase 2001 { 2002 public: 2003 ActiveAttributesCase (Context& context, const char* name, const char* description) 2004 : ApiCase(context, name, description) 2005 { 2006 } 2007 2008 void test (void) 2009 { 2010 using tcu::TestLog; 2011 2012 static const char* testVertSource = 2013 "#version 300 es\n" 2014 "in highp vec2 longInputAttributeName;\n" 2015 "in highp vec2 shortName;\n" 2016 "void main (void)\n" 2017 "{\n" 2018 " gl_Position = longInputAttributeName.yxxy + shortName.xyxy;\n" 2019 "}\n\0"; 2020 static const char* testFragSource = 2021 "#version 300 es\n" 2022 "layout(location = 0) out mediump vec4 fragColor;" 2023 "void main (void)\n" 2024 "{\n" 2025 " fragColor = vec4(0.0);\n" 2026 "}\n\0"; 2027 2028 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 2029 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 2030 2031 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); 2032 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); 2033 2034 glCompileShader(shaderVert); 2035 glCompileShader(shaderFrag); 2036 expectError(GL_NO_ERROR); 2037 2038 GLuint program = glCreateProgram(); 2039 glAttachShader(program, shaderVert); 2040 glAttachShader(program, shaderFrag); 2041 glLinkProgram(program); 2042 expectError(GL_NO_ERROR); 2043 2044 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTES, 2); 2045 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, (GLint)std::string("longInputAttributeName").length() + 1); // does include null-terminator 2046 2047 // check names 2048 for (int attributeNdx = 0; attributeNdx < 2; ++attributeNdx) 2049 { 2050 char buffer[2048] = {'x'}; 2051 2052 GLint written = 0; 2053 GLint size = 0; 2054 GLenum type = 0; 2055 glGetActiveAttrib(program, attributeNdx, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer); 2056 expectError(GL_NO_ERROR); 2057 2058 if (deStringBeginsWith(buffer, "longInputAttributeName")) 2059 { 2060 checkIntEquals(m_testCtx, written, (GLint)std::string("longInputAttributeName").length()); // does NOT include null-terminator 2061 } 2062 else if (deStringBeginsWith(buffer, "shortName")) 2063 { 2064 checkIntEquals(m_testCtx, written, (GLint)std::string("shortName").length()); // does NOT include null-terminator 2065 } 2066 else 2067 { 2068 m_testCtx.getLog() << TestLog::Message << "// ERROR: Got unexpected attribute name." << TestLog::EndMessage; 2069 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 2070 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected name"); 2071 } 2072 } 2073 2074 // and with too short buffer 2075 { 2076 char buffer[2048] = {'x'}; 2077 2078 GLint written = 0; 2079 GLint size = 0; 2080 GLenum type = 0; 2081 2082 glGetActiveAttrib(program, 0, 1, &written, &size, &type, buffer); 2083 expectError(GL_NO_ERROR); 2084 checkIntEquals(m_testCtx, written, 0); 2085 } 2086 2087 glDeleteShader(shaderVert); 2088 glDeleteShader(shaderFrag); 2089 glDeleteProgram(program); 2090 expectError(GL_NO_ERROR); 2091 } 2092 }; 2093 2094 struct PointerData 2095 { 2096 GLint size; 2097 GLenum type; 2098 GLint stride; 2099 GLboolean normalized; 2100 const void* pointer; 2101 }; 2102 2103 class VertexAttributeSizeCase : public ApiCase 2104 { 2105 public: 2106 VertexAttributeSizeCase (Context& context, const char* name, const char* description) 2107 : ApiCase(context, name, description) 2108 { 2109 } 2110 2111 void test (void) 2112 { 2113 GLfloat vertexData[4] = {0.0f}; // never accessed 2114 2115 const PointerData pointers[] = 2116 { 2117 // size test 2118 { 4, GL_FLOAT, 0, GL_FALSE, vertexData }, 2119 { 3, GL_FLOAT, 0, GL_FALSE, vertexData }, 2120 { 2, GL_FLOAT, 0, GL_FALSE, vertexData }, 2121 { 1, GL_FLOAT, 0, GL_FALSE, vertexData }, 2122 { 4, GL_INT, 0, GL_FALSE, vertexData }, 2123 { 3, GL_INT, 0, GL_FALSE, vertexData }, 2124 { 2, GL_INT, 0, GL_FALSE, vertexData }, 2125 { 1, GL_INT, 0, GL_FALSE, vertexData }, 2126 }; 2127 2128 // Test with default VAO 2129 { 2130 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO"); 2131 2132 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 2133 { 2134 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer); 2135 expectError(GL_NO_ERROR); 2136 2137 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[ndx].size); 2138 } 2139 } 2140 2141 // Test with multiple VAOs 2142 { 2143 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO"); 2144 2145 GLuint buf = 0; 2146 GLuint vaos[2] = {0}; 2147 2148 glGenVertexArrays(2, vaos); 2149 glGenBuffers(1, &buf); 2150 glBindBuffer(GL_ARRAY_BUFFER, buf); 2151 expectError(GL_NO_ERROR); 2152 2153 // initial 2154 glBindVertexArray(vaos[0]); 2155 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, 4); 2156 expectError(GL_NO_ERROR); 2157 2158 // set vao 0 to some value 2159 glVertexAttribPointer(0, pointers[0].size, pointers[0].type, pointers[0].normalized, pointers[0].stride, DE_NULL); 2160 expectError(GL_NO_ERROR); 2161 2162 // set vao 1 to some other value 2163 glBindVertexArray(vaos[1]); 2164 glVertexAttribPointer(0, pointers[1].size, pointers[1].type, pointers[1].normalized, pointers[1].stride, DE_NULL); 2165 expectError(GL_NO_ERROR); 2166 2167 // verify vao 1 state 2168 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[1].size); 2169 expectError(GL_NO_ERROR); 2170 2171 // verify vao 0 state 2172 glBindVertexArray(vaos[0]); 2173 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[0].size); 2174 expectError(GL_NO_ERROR); 2175 2176 glDeleteVertexArrays(2, vaos); 2177 glDeleteBuffers(1, &buf); 2178 expectError(GL_NO_ERROR); 2179 } 2180 } 2181 }; 2182 2183 class VertexAttributeTypeCase : public ApiCase 2184 { 2185 public: 2186 VertexAttributeTypeCase (Context& context, const char* name, const char* description) 2187 : ApiCase(context, name, description) 2188 { 2189 } 2190 2191 void test (void) 2192 { 2193 // Test with default VAO 2194 { 2195 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO"); 2196 2197 const GLfloat vertexData[4] = {0.0f}; // never accessed 2198 2199 // test VertexAttribPointer 2200 { 2201 const PointerData pointers[] = 2202 { 2203 { 1, GL_BYTE, 0, GL_FALSE, vertexData }, 2204 { 1, GL_SHORT, 0, GL_FALSE, vertexData }, 2205 { 1, GL_INT, 0, GL_FALSE, vertexData }, 2206 { 1, GL_FIXED, 0, GL_FALSE, vertexData }, 2207 { 1, GL_FLOAT, 0, GL_FALSE, vertexData }, 2208 { 1, GL_HALF_FLOAT, 0, GL_FALSE, vertexData }, 2209 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData }, 2210 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData }, 2211 { 1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData }, 2212 { 4, GL_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData }, 2213 { 4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData }, 2214 }; 2215 2216 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 2217 { 2218 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer); 2219 expectError(GL_NO_ERROR); 2220 2221 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, pointers[ndx].type); 2222 } 2223 } 2224 2225 // test glVertexAttribIPointer 2226 { 2227 const PointerData pointers[] = 2228 { 2229 { 1, GL_BYTE, 0, GL_FALSE, vertexData }, 2230 { 1, GL_SHORT, 0, GL_FALSE, vertexData }, 2231 { 1, GL_INT, 0, GL_FALSE, vertexData }, 2232 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData }, 2233 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData }, 2234 { 1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData }, 2235 }; 2236 2237 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 2238 { 2239 glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride, pointers[ndx].pointer); 2240 expectError(GL_NO_ERROR); 2241 2242 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, pointers[ndx].type); 2243 } 2244 } 2245 } 2246 2247 // Test with multiple VAOs 2248 { 2249 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO"); 2250 2251 GLuint buf = 0; 2252 GLuint vaos[2] = {0}; 2253 2254 glGenVertexArrays(2, vaos); 2255 glGenBuffers(1, &buf); 2256 glBindBuffer(GL_ARRAY_BUFFER, buf); 2257 expectError(GL_NO_ERROR); 2258 2259 // initial 2260 glBindVertexArray(vaos[0]); 2261 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_FLOAT); 2262 expectError(GL_NO_ERROR); 2263 2264 // set vao 0 to some value 2265 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, DE_NULL); 2266 expectError(GL_NO_ERROR); 2267 2268 // set vao 1 to some other value 2269 glBindVertexArray(vaos[1]); 2270 glVertexAttribPointer(0, 1, GL_SHORT, GL_FALSE, 0, DE_NULL); 2271 expectError(GL_NO_ERROR); 2272 2273 // verify vao 1 state 2274 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_SHORT); 2275 expectError(GL_NO_ERROR); 2276 2277 // verify vao 0 state 2278 glBindVertexArray(vaos[0]); 2279 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_FLOAT); 2280 expectError(GL_NO_ERROR); 2281 2282 glDeleteVertexArrays(2, vaos); 2283 glDeleteBuffers(1, &buf); 2284 expectError(GL_NO_ERROR); 2285 } 2286 } 2287 }; 2288 2289 class VertexAttributeStrideCase : public ApiCase 2290 { 2291 public: 2292 VertexAttributeStrideCase (Context& context, const char* name, const char* description) 2293 : ApiCase(context, name, description) 2294 { 2295 } 2296 2297 void test (void) 2298 { 2299 // Test with default VAO 2300 { 2301 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO"); 2302 2303 const GLfloat vertexData[4] = {0.0f}; // never accessed 2304 2305 struct StridePointerData 2306 { 2307 GLint size; 2308 GLenum type; 2309 GLint stride; 2310 const void* pointer; 2311 }; 2312 2313 // test VertexAttribPointer 2314 { 2315 const StridePointerData pointers[] = 2316 { 2317 { 1, GL_FLOAT, 0, vertexData }, 2318 { 1, GL_FLOAT, 1, vertexData }, 2319 { 1, GL_FLOAT, 4, vertexData }, 2320 { 1, GL_HALF_FLOAT, 0, vertexData }, 2321 { 1, GL_HALF_FLOAT, 1, vertexData }, 2322 { 1, GL_HALF_FLOAT, 4, vertexData }, 2323 { 1, GL_FIXED, 0, vertexData }, 2324 { 1, GL_FIXED, 1, vertexData }, 2325 { 1, GL_FIXED, 4, vertexData }, 2326 }; 2327 2328 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 2329 { 2330 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, GL_FALSE, pointers[ndx].stride, pointers[ndx].pointer); 2331 expectError(GL_NO_ERROR); 2332 2333 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, pointers[ndx].stride); 2334 } 2335 } 2336 2337 // test glVertexAttribIPointer 2338 { 2339 const StridePointerData pointers[] = 2340 { 2341 { 1, GL_INT, 0, vertexData }, 2342 { 1, GL_INT, 1, vertexData }, 2343 { 1, GL_INT, 4, vertexData }, 2344 { 4, GL_UNSIGNED_BYTE, 0, vertexData }, 2345 { 4, GL_UNSIGNED_BYTE, 1, vertexData }, 2346 { 4, GL_UNSIGNED_BYTE, 4, vertexData }, 2347 { 2, GL_SHORT, 0, vertexData }, 2348 { 2, GL_SHORT, 1, vertexData }, 2349 { 2, GL_SHORT, 4, vertexData }, 2350 }; 2351 2352 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 2353 { 2354 glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride, pointers[ndx].pointer); 2355 expectError(GL_NO_ERROR); 2356 2357 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, pointers[ndx].stride); 2358 } 2359 } 2360 } 2361 2362 // Test with multiple VAOs 2363 { 2364 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO"); 2365 2366 GLuint buf = 0; 2367 GLuint vaos[2] = {0}; 2368 2369 glGenVertexArrays(2, vaos); 2370 glGenBuffers(1, &buf); 2371 glBindBuffer(GL_ARRAY_BUFFER, buf); 2372 expectError(GL_NO_ERROR); 2373 2374 // initial 2375 glBindVertexArray(vaos[0]); 2376 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, 0); 2377 expectError(GL_NO_ERROR); 2378 2379 // set vao 0 to some value 2380 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 4, DE_NULL); 2381 expectError(GL_NO_ERROR); 2382 2383 // set vao 1 to some other value 2384 glBindVertexArray(vaos[1]); 2385 glVertexAttribPointer(0, 1, GL_SHORT, GL_FALSE, 8, DE_NULL); 2386 expectError(GL_NO_ERROR); 2387 2388 // verify vao 1 state 2389 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, 8); 2390 expectError(GL_NO_ERROR); 2391 2392 // verify vao 0 state 2393 glBindVertexArray(vaos[0]); 2394 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, 4); 2395 expectError(GL_NO_ERROR); 2396 2397 glDeleteVertexArrays(2, vaos); 2398 glDeleteBuffers(1, &buf); 2399 expectError(GL_NO_ERROR); 2400 } 2401 } 2402 }; 2403 2404 class VertexAttributeNormalizedCase : public ApiCase 2405 { 2406 public: 2407 VertexAttributeNormalizedCase (Context& context, const char* name, const char* description) 2408 : ApiCase(context, name, description) 2409 { 2410 } 2411 2412 void test (void) 2413 { 2414 // Test with default VAO 2415 { 2416 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO"); 2417 2418 const GLfloat vertexData[4] = {0.0f}; // never accessed 2419 2420 // test VertexAttribPointer 2421 { 2422 const PointerData pointers[] = 2423 { 2424 { 1, GL_BYTE, 0, GL_FALSE, vertexData }, 2425 { 1, GL_SHORT, 0, GL_FALSE, vertexData }, 2426 { 1, GL_INT, 0, GL_FALSE, vertexData }, 2427 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData }, 2428 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData }, 2429 { 1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData }, 2430 { 4, GL_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData }, 2431 { 4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData }, 2432 { 1, GL_BYTE, 0, GL_TRUE, vertexData }, 2433 { 1, GL_SHORT, 0, GL_TRUE, vertexData }, 2434 { 1, GL_INT, 0, GL_TRUE, vertexData }, 2435 { 1, GL_UNSIGNED_BYTE, 0, GL_TRUE, vertexData }, 2436 { 1, GL_UNSIGNED_SHORT, 0, GL_TRUE, vertexData }, 2437 { 1, GL_UNSIGNED_INT, 0, GL_TRUE, vertexData }, 2438 { 4, GL_INT_2_10_10_10_REV, 0, GL_TRUE, vertexData }, 2439 { 4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, GL_TRUE, vertexData }, 2440 }; 2441 2442 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 2443 { 2444 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer); 2445 expectError(GL_NO_ERROR); 2446 2447 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, pointers[ndx].normalized); 2448 } 2449 } 2450 2451 // test glVertexAttribIPointer 2452 { 2453 const PointerData pointers[] = 2454 { 2455 { 1, GL_BYTE, 0, GL_FALSE, vertexData }, 2456 { 1, GL_SHORT, 0, GL_FALSE, vertexData }, 2457 { 1, GL_INT, 0, GL_FALSE, vertexData }, 2458 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData }, 2459 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData }, 2460 { 1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData }, 2461 }; 2462 2463 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 2464 { 2465 glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride, pointers[ndx].pointer); 2466 expectError(GL_NO_ERROR); 2467 2468 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_FALSE); 2469 } 2470 } 2471 } 2472 2473 // Test with multiple VAOs 2474 { 2475 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO"); 2476 2477 GLuint buf = 0; 2478 GLuint vaos[2] = {0}; 2479 2480 glGenVertexArrays(2, vaos); 2481 glGenBuffers(1, &buf); 2482 glBindBuffer(GL_ARRAY_BUFFER, buf); 2483 expectError(GL_NO_ERROR); 2484 2485 // initial 2486 glBindVertexArray(vaos[0]); 2487 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_FALSE); 2488 expectError(GL_NO_ERROR); 2489 2490 // set vao 0 to some value 2491 glVertexAttribPointer(0, 1, GL_INT, GL_TRUE, 0, DE_NULL); 2492 expectError(GL_NO_ERROR); 2493 2494 // set vao 1 to some other value 2495 glBindVertexArray(vaos[1]); 2496 glVertexAttribPointer(0, 1, GL_INT, GL_FALSE, 0, DE_NULL); 2497 expectError(GL_NO_ERROR); 2498 2499 // verify vao 1 state 2500 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_FALSE); 2501 expectError(GL_NO_ERROR); 2502 2503 // verify vao 0 state 2504 glBindVertexArray(vaos[0]); 2505 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_TRUE); 2506 expectError(GL_NO_ERROR); 2507 2508 glDeleteVertexArrays(2, vaos); 2509 glDeleteBuffers(1, &buf); 2510 expectError(GL_NO_ERROR); 2511 } 2512 } 2513 }; 2514 2515 class VertexAttributeIntegerCase : public ApiCase 2516 { 2517 public: 2518 VertexAttributeIntegerCase (Context& context, const char* name, const char* description) 2519 : ApiCase(context, name, description) 2520 { 2521 } 2522 2523 void test (void) 2524 { 2525 // Test with default VAO 2526 { 2527 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO"); 2528 2529 const GLfloat vertexData[4] = {0.0f}; // never accessed 2530 2531 // test VertexAttribPointer 2532 { 2533 const PointerData pointers[] = 2534 { 2535 { 1, GL_BYTE, 0, GL_FALSE, vertexData }, 2536 { 1, GL_SHORT, 0, GL_FALSE, vertexData }, 2537 { 1, GL_INT, 0, GL_FALSE, vertexData }, 2538 { 1, GL_FIXED, 0, GL_FALSE, vertexData }, 2539 { 1, GL_FLOAT, 0, GL_FALSE, vertexData }, 2540 { 1, GL_HALF_FLOAT, 0, GL_FALSE, vertexData }, 2541 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData }, 2542 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData }, 2543 { 1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData }, 2544 { 4, GL_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData }, 2545 { 4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData }, 2546 }; 2547 2548 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 2549 { 2550 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer); 2551 expectError(GL_NO_ERROR); 2552 2553 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FALSE); 2554 } 2555 } 2556 2557 // test glVertexAttribIPointer 2558 { 2559 const PointerData pointers[] = 2560 { 2561 { 1, GL_BYTE, 0, GL_FALSE, vertexData }, 2562 { 1, GL_SHORT, 0, GL_FALSE, vertexData }, 2563 { 1, GL_INT, 0, GL_FALSE, vertexData }, 2564 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData }, 2565 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData }, 2566 { 1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData }, 2567 }; 2568 2569 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 2570 { 2571 glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride, pointers[ndx].pointer); 2572 expectError(GL_NO_ERROR); 2573 2574 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_TRUE); 2575 } 2576 } 2577 } 2578 2579 // Test with multiple VAOs 2580 { 2581 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO"); 2582 2583 GLuint buf = 0; 2584 GLuint vaos[2] = {0}; 2585 2586 glGenVertexArrays(2, vaos); 2587 glGenBuffers(1, &buf); 2588 glBindBuffer(GL_ARRAY_BUFFER, buf); 2589 expectError(GL_NO_ERROR); 2590 2591 // initial 2592 glBindVertexArray(vaos[0]); 2593 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FALSE); 2594 expectError(GL_NO_ERROR); 2595 2596 // set vao 0 to some value 2597 glVertexAttribIPointer(0, 1, GL_INT, 0, DE_NULL); 2598 expectError(GL_NO_ERROR); 2599 2600 // set vao 1 to some other value 2601 glBindVertexArray(vaos[1]); 2602 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, DE_NULL); 2603 expectError(GL_NO_ERROR); 2604 2605 // verify vao 1 state 2606 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FALSE); 2607 expectError(GL_NO_ERROR); 2608 2609 // verify vao 0 state 2610 glBindVertexArray(vaos[0]); 2611 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_TRUE); 2612 expectError(GL_NO_ERROR); 2613 2614 glDeleteVertexArrays(2, vaos); 2615 glDeleteBuffers(1, &buf); 2616 expectError(GL_NO_ERROR); 2617 } 2618 } 2619 }; 2620 2621 class VertexAttributeEnabledCase : public ApiCase 2622 { 2623 public: 2624 VertexAttributeEnabledCase (Context& context, const char* name, const char* description) 2625 : ApiCase(context, name, description) 2626 { 2627 } 2628 2629 void test (void) 2630 { 2631 // VERTEX_ATTRIB_ARRAY_ENABLED 2632 2633 // Test with default VAO 2634 { 2635 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO"); 2636 2637 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE); 2638 glEnableVertexAttribArray(0); 2639 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_TRUE); 2640 glDisableVertexAttribArray(0); 2641 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE); 2642 } 2643 2644 // Test with multiple VAOs 2645 { 2646 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO"); 2647 2648 GLuint vaos[2] = {0}; 2649 2650 glGenVertexArrays(2, vaos); 2651 expectError(GL_NO_ERROR); 2652 2653 // set vao 0 to some value 2654 glBindVertexArray(vaos[0]); 2655 glEnableVertexAttribArray(0); 2656 expectError(GL_NO_ERROR); 2657 2658 // set vao 1 to some other value 2659 glBindVertexArray(vaos[1]); 2660 glDisableVertexAttribArray(0); 2661 expectError(GL_NO_ERROR); 2662 2663 // verify vao 1 state 2664 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE); 2665 expectError(GL_NO_ERROR); 2666 2667 // verify vao 0 state 2668 glBindVertexArray(vaos[0]); 2669 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_TRUE); 2670 expectError(GL_NO_ERROR); 2671 2672 glDeleteVertexArrays(2, vaos); 2673 expectError(GL_NO_ERROR); 2674 } 2675 } 2676 }; 2677 2678 class VertexAttributeDivisorCase : public ApiCase 2679 { 2680 public: 2681 VertexAttributeDivisorCase (Context& context, const char* name, const char* description) 2682 : ApiCase(context, name, description) 2683 { 2684 } 2685 2686 void test (void) 2687 { 2688 // Test with default VAO 2689 { 2690 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO"); 2691 2692 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 0); 2693 glVertexAttribDivisor(0, 1); 2694 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 1); 2695 glVertexAttribDivisor(0, 5); 2696 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 5); 2697 } 2698 2699 // Test with multiple VAOs 2700 { 2701 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO"); 2702 2703 GLuint vaos[2] = {0}; 2704 2705 glGenVertexArrays(2, vaos); 2706 expectError(GL_NO_ERROR); 2707 2708 // set vao 0 to some value 2709 glBindVertexArray(vaos[0]); 2710 glVertexAttribDivisor(0, 1); 2711 expectError(GL_NO_ERROR); 2712 2713 // set vao 1 to some other value 2714 glBindVertexArray(vaos[1]); 2715 glVertexAttribDivisor(0, 5); 2716 expectError(GL_NO_ERROR); 2717 2718 // verify vao 1 state 2719 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 5); 2720 expectError(GL_NO_ERROR); 2721 2722 // verify vao 0 state 2723 glBindVertexArray(vaos[0]); 2724 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 1); 2725 expectError(GL_NO_ERROR); 2726 2727 glDeleteVertexArrays(2, vaos); 2728 expectError(GL_NO_ERROR); 2729 } 2730 } 2731 }; 2732 2733 class VertexAttributeBufferBindingCase : public ApiCase 2734 { 2735 public: 2736 VertexAttributeBufferBindingCase (Context& context, const char* name, const char* description) 2737 : ApiCase(context, name, description) 2738 { 2739 } 2740 2741 void test (void) 2742 { 2743 // Test with default VAO 2744 { 2745 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO"); 2746 2747 // initial 2748 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, 0); 2749 2750 GLuint bufferID; 2751 glGenBuffers(1, &bufferID); 2752 glBindBuffer(GL_ARRAY_BUFFER, bufferID); 2753 expectError(GL_NO_ERROR); 2754 2755 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL); 2756 expectError(GL_NO_ERROR); 2757 2758 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufferID); 2759 2760 glDeleteBuffers(1, &bufferID); 2761 expectError(GL_NO_ERROR); 2762 } 2763 2764 // Test with multiple VAOs 2765 { 2766 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO"); 2767 2768 GLuint vaos[2] = {0}; 2769 GLuint bufs[2] = {0}; 2770 2771 glGenBuffers(2, bufs); 2772 expectError(GL_NO_ERROR); 2773 2774 glGenVertexArrays(2, vaos); 2775 expectError(GL_NO_ERROR); 2776 2777 // set vao 0 to some value 2778 glBindVertexArray(vaos[0]); 2779 glBindBuffer(GL_ARRAY_BUFFER, bufs[0]); 2780 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL); 2781 expectError(GL_NO_ERROR); 2782 2783 // set vao 1 to some other value 2784 glBindVertexArray(vaos[1]); 2785 glBindBuffer(GL_ARRAY_BUFFER, bufs[1]); 2786 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL); 2787 expectError(GL_NO_ERROR); 2788 2789 // verify vao 1 state 2790 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufs[1]); 2791 expectError(GL_NO_ERROR); 2792 2793 // verify vao 0 state 2794 glBindVertexArray(vaos[0]); 2795 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufs[0]); 2796 expectError(GL_NO_ERROR); 2797 2798 glDeleteVertexArrays(2, vaos); 2799 glDeleteBuffers(2, bufs); 2800 expectError(GL_NO_ERROR); 2801 } 2802 } 2803 }; 2804 2805 class VertexAttributePointerCase : public ApiCase 2806 { 2807 public: 2808 VertexAttributePointerCase (Context& context, const char* name, const char* description) 2809 : ApiCase(context, name, description) 2810 { 2811 } 2812 2813 void test (void) 2814 { 2815 // Test with default VAO 2816 { 2817 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO"); 2818 2819 StateQueryMemoryWriteGuard<GLvoid*> initialState; 2820 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &initialState); 2821 initialState.verifyValidity(m_testCtx); 2822 checkPointerEquals(m_testCtx, initialState, 0); 2823 2824 const GLfloat vertexData[4] = {0.0f}; // never accessed 2825 const PointerData pointers[] = 2826 { 2827 { 1, GL_BYTE, 0, GL_FALSE, &vertexData[2] }, 2828 { 1, GL_SHORT, 0, GL_FALSE, &vertexData[1] }, 2829 { 1, GL_INT, 0, GL_FALSE, &vertexData[2] }, 2830 { 1, GL_FIXED, 0, GL_FALSE, &vertexData[2] }, 2831 { 1, GL_FIXED, 0, GL_FALSE, &vertexData[1] }, 2832 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[0] }, 2833 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[3] }, 2834 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[2] }, 2835 { 1, GL_HALF_FLOAT, 0, GL_FALSE, &vertexData[0] }, 2836 { 4, GL_HALF_FLOAT, 0, GL_FALSE, &vertexData[1] }, 2837 { 4, GL_HALF_FLOAT, 0, GL_FALSE, &vertexData[2] }, 2838 }; 2839 2840 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 2841 { 2842 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer); 2843 expectError(GL_NO_ERROR); 2844 2845 StateQueryMemoryWriteGuard<GLvoid*> state; 2846 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state); 2847 state.verifyValidity(m_testCtx); 2848 checkPointerEquals(m_testCtx, state, pointers[ndx].pointer); 2849 } 2850 } 2851 2852 // Test with multiple VAOs 2853 { 2854 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO"); 2855 2856 GLuint vaos[2] = {0}; 2857 GLuint bufs[2] = {0}; 2858 2859 glGenBuffers(2, bufs); 2860 expectError(GL_NO_ERROR); 2861 2862 glGenVertexArrays(2, vaos); 2863 expectError(GL_NO_ERROR); 2864 2865 // set vao 0 to some value 2866 glBindVertexArray(vaos[0]); 2867 glBindBuffer(GL_ARRAY_BUFFER, bufs[0]); 2868 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, ((deUint8*)DE_NULL) + 8); 2869 expectError(GL_NO_ERROR); 2870 2871 // set vao 1 to some other value 2872 glBindVertexArray(vaos[1]); 2873 glBindBuffer(GL_ARRAY_BUFFER, bufs[1]); 2874 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, ((deUint8*)DE_NULL) + 4); 2875 expectError(GL_NO_ERROR); 2876 2877 // verify vao 1 state 2878 { 2879 StateQueryMemoryWriteGuard<GLvoid*> state; 2880 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state); 2881 state.verifyValidity(m_testCtx); 2882 checkPointerEquals(m_testCtx, state, ((deUint8*)DE_NULL) + 4); 2883 } 2884 expectError(GL_NO_ERROR); 2885 2886 // verify vao 0 state 2887 glBindVertexArray(vaos[0]); 2888 { 2889 StateQueryMemoryWriteGuard<GLvoid*> state; 2890 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state); 2891 state.verifyValidity(m_testCtx); 2892 checkPointerEquals(m_testCtx, state, ((deUint8*)DE_NULL) + 8); 2893 } 2894 expectError(GL_NO_ERROR); 2895 2896 glDeleteVertexArrays(2, vaos); 2897 glDeleteBuffers(2, bufs); 2898 expectError(GL_NO_ERROR); 2899 } 2900 } 2901 }; 2902 2903 class UniformValueFloatCase : public ApiCase 2904 { 2905 public: 2906 UniformValueFloatCase (Context& context, const char* name, const char* description) 2907 : ApiCase(context, name, description) 2908 { 2909 } 2910 2911 void test (void) 2912 { 2913 static const char* testVertSource = 2914 "#version 300 es\n" 2915 "uniform highp float floatUniform;\n" 2916 "uniform highp vec2 float2Uniform;\n" 2917 "uniform highp vec3 float3Uniform;\n" 2918 "uniform highp vec4 float4Uniform;\n" 2919 "void main (void)\n" 2920 "{\n" 2921 " gl_Position = vec4(floatUniform + float2Uniform.x + float3Uniform.x + float4Uniform.x);\n" 2922 "}\n"; 2923 static const char* testFragSource = 2924 "#version 300 es\n" 2925 "layout(location = 0) out mediump vec4 fragColor;" 2926 "void main (void)\n" 2927 "{\n" 2928 " fragColor = vec4(0.0);\n" 2929 "}\n"; 2930 2931 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 2932 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 2933 2934 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); 2935 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); 2936 2937 glCompileShader(shaderVert); 2938 glCompileShader(shaderFrag); 2939 expectError(GL_NO_ERROR); 2940 2941 GLuint program = glCreateProgram(); 2942 glAttachShader(program, shaderVert); 2943 glAttachShader(program, shaderFrag); 2944 glLinkProgram(program); 2945 glUseProgram(program); 2946 expectError(GL_NO_ERROR); 2947 2948 GLint location; 2949 2950 location = glGetUniformLocation(program,"floatUniform"); 2951 glUniform1f(location, 1.0f); 2952 verifyUniformValue1f(m_testCtx, *this, program, location, 1.0f); 2953 2954 location = glGetUniformLocation(program,"float2Uniform"); 2955 glUniform2f(location, 1.0f, 2.0f); 2956 verifyUniformValue2f(m_testCtx, *this, program, location, 1.0f, 2.0f); 2957 2958 location = glGetUniformLocation(program,"float3Uniform"); 2959 glUniform3f(location, 1.0f, 2.0f, 3.0f); 2960 verifyUniformValue3f(m_testCtx, *this, program, location, 1.0f, 2.0f, 3.0f); 2961 2962 location = glGetUniformLocation(program,"float4Uniform"); 2963 glUniform4f(location, 1.0f, 2.0f, 3.0f, 4.0f); 2964 verifyUniformValue4f(m_testCtx, *this, program, location, 1.0f, 2.0f, 3.0f, 4.0f); 2965 2966 glUseProgram(0); 2967 glDeleteShader(shaderVert); 2968 glDeleteShader(shaderFrag); 2969 glDeleteProgram(program); 2970 expectError(GL_NO_ERROR); 2971 } 2972 }; 2973 2974 class UniformValueIntCase : public ApiCase 2975 { 2976 public: 2977 UniformValueIntCase (Context& context, const char* name, const char* description) 2978 : ApiCase(context, name, description) 2979 { 2980 } 2981 2982 void test (void) 2983 { 2984 static const char* testVertSource = 2985 "#version 300 es\n" 2986 "uniform highp int intUniform;\n" 2987 "uniform highp ivec2 int2Uniform;\n" 2988 "uniform highp ivec3 int3Uniform;\n" 2989 "uniform highp ivec4 int4Uniform;\n" 2990 "void main (void)\n" 2991 "{\n" 2992 " gl_Position = vec4(float(intUniform + int2Uniform.x + int3Uniform.x + int4Uniform.x));\n" 2993 "}\n"; 2994 static const char* testFragSource = 2995 "#version 300 es\n" 2996 "layout(location = 0) out mediump vec4 fragColor;" 2997 "void main (void)\n" 2998 "{\n" 2999 " fragColor = vec4(0.0);\n" 3000 "}\n"; 3001 3002 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 3003 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 3004 3005 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); 3006 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); 3007 3008 glCompileShader(shaderVert); 3009 glCompileShader(shaderFrag); 3010 expectError(GL_NO_ERROR); 3011 3012 GLuint program = glCreateProgram(); 3013 glAttachShader(program, shaderVert); 3014 glAttachShader(program, shaderFrag); 3015 glLinkProgram(program); 3016 glUseProgram(program); 3017 expectError(GL_NO_ERROR); 3018 3019 GLint location; 3020 3021 location = glGetUniformLocation(program,"intUniform"); 3022 glUniform1i(location, 1); 3023 verifyUniformValue1i(m_testCtx, *this, program, location, 1); 3024 3025 location = glGetUniformLocation(program,"int2Uniform"); 3026 glUniform2i(location, 1, 2); 3027 verifyUniformValue2i(m_testCtx, *this, program, location, 1, 2); 3028 3029 location = glGetUniformLocation(program,"int3Uniform"); 3030 glUniform3i(location, 1, 2, 3); 3031 verifyUniformValue3i(m_testCtx, *this, program, location, 1, 2, 3); 3032 3033 location = glGetUniformLocation(program,"int4Uniform"); 3034 glUniform4i(location, 1, 2, 3, 4); 3035 verifyUniformValue4i(m_testCtx, *this, program, location, 1, 2, 3, 4); 3036 3037 glUseProgram(0); 3038 glDeleteShader(shaderVert); 3039 glDeleteShader(shaderFrag); 3040 glDeleteProgram(program); 3041 expectError(GL_NO_ERROR); 3042 } 3043 }; 3044 3045 class UniformValueUintCase : public ApiCase 3046 { 3047 public: 3048 UniformValueUintCase (Context& context, const char* name, const char* description) 3049 : ApiCase(context, name, description) 3050 { 3051 } 3052 3053 void test (void) 3054 { 3055 static const char* testVertSource = 3056 "#version 300 es\n" 3057 "uniform highp uint uintUniform;\n" 3058 "uniform highp uvec2 uint2Uniform;\n" 3059 "uniform highp uvec3 uint3Uniform;\n" 3060 "uniform highp uvec4 uint4Uniform;\n" 3061 "void main (void)\n" 3062 "{\n" 3063 " gl_Position = vec4(float(uintUniform + uint2Uniform.x + uint3Uniform.x + uint4Uniform.x));\n" 3064 "}\n"; 3065 static const char* testFragSource = 3066 "#version 300 es\n" 3067 "layout(location = 0) out mediump vec4 fragColor;" 3068 "void main (void)\n" 3069 "{\n" 3070 " fragColor = vec4(0.0);\n" 3071 "}\n"; 3072 3073 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 3074 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 3075 3076 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); 3077 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); 3078 3079 glCompileShader(shaderVert); 3080 glCompileShader(shaderFrag); 3081 expectError(GL_NO_ERROR); 3082 3083 GLuint program = glCreateProgram(); 3084 glAttachShader(program, shaderVert); 3085 glAttachShader(program, shaderFrag); 3086 glLinkProgram(program); 3087 glUseProgram(program); 3088 expectError(GL_NO_ERROR); 3089 3090 GLint location; 3091 3092 location = glGetUniformLocation(program,"uintUniform"); 3093 glUniform1ui(location, 1); 3094 verifyUniformValue1ui(m_testCtx, *this, program, location, 1); 3095 3096 location = glGetUniformLocation(program,"uint2Uniform"); 3097 glUniform2ui(location, 1, 2); 3098 verifyUniformValue2ui(m_testCtx, *this, program, location, 1, 2); 3099 3100 location = glGetUniformLocation(program,"uint3Uniform"); 3101 glUniform3ui(location, 1, 2, 3); 3102 verifyUniformValue3ui(m_testCtx, *this, program, location, 1, 2, 3); 3103 3104 location = glGetUniformLocation(program,"uint4Uniform"); 3105 glUniform4ui(location, 1, 2, 3, 4); 3106 verifyUniformValue4ui(m_testCtx, *this, program, location, 1, 2, 3, 4); 3107 3108 glUseProgram(0); 3109 glDeleteShader(shaderVert); 3110 glDeleteShader(shaderFrag); 3111 glDeleteProgram(program); 3112 expectError(GL_NO_ERROR); 3113 } 3114 }; 3115 3116 3117 class UniformValueBooleanCase : public ApiCase 3118 { 3119 public: 3120 UniformValueBooleanCase (Context& context, const char* name, const char* description) 3121 : ApiCase(context, name, description) 3122 { 3123 } 3124 3125 void test (void) 3126 { 3127 static const char* testVertSource = 3128 "#version 300 es\n" 3129 "uniform bool boolUniform;\n" 3130 "uniform bvec2 bool2Uniform;\n" 3131 "uniform bvec3 bool3Uniform;\n" 3132 "uniform bvec4 bool4Uniform;\n" 3133 "void main (void)\n" 3134 "{\n" 3135 " gl_Position = vec4(float(boolUniform) + float(bool2Uniform.x) + float(bool3Uniform.x) + float(bool4Uniform.x));\n" 3136 "}\n"; 3137 static const char* testFragSource = 3138 "#version 300 es\n" 3139 "layout(location = 0) out mediump vec4 fragColor;" 3140 "void main (void)\n" 3141 "{\n" 3142 " fragColor = vec4(0.0);\n" 3143 "}\n"; 3144 3145 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 3146 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 3147 3148 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); 3149 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); 3150 3151 glCompileShader(shaderVert); 3152 glCompileShader(shaderFrag); 3153 expectError(GL_NO_ERROR); 3154 3155 GLuint program = glCreateProgram(); 3156 glAttachShader(program, shaderVert); 3157 glAttachShader(program, shaderFrag); 3158 glLinkProgram(program); 3159 glUseProgram(program); 3160 expectError(GL_NO_ERROR); 3161 3162 GLint location; 3163 3164 // int conversion 3165 3166 location = glGetUniformLocation(program,"boolUniform"); 3167 glUniform1i(location, 1); 3168 verifyUniformValue1i(m_testCtx, *this, program, location, 1); 3169 3170 location = glGetUniformLocation(program,"bool2Uniform"); 3171 glUniform2i(location, 1, 2); 3172 verifyUniformValue2i(m_testCtx, *this, program, location, 1, 1); 3173 3174 location = glGetUniformLocation(program,"bool3Uniform"); 3175 glUniform3i(location, 0, 1, 2); 3176 verifyUniformValue3i(m_testCtx, *this, program, location, 0, 1, 1); 3177 3178 location = glGetUniformLocation(program,"bool4Uniform"); 3179 glUniform4i(location, 1, 0, 1, -1); 3180 verifyUniformValue4i(m_testCtx, *this, program, location, 1, 0, 1, 1); 3181 3182 // float conversion 3183 3184 location = glGetUniformLocation(program,"boolUniform"); 3185 glUniform1f(location, 1.0f); 3186 verifyUniformValue1i(m_testCtx, *this, program, location, 1); 3187 3188 location = glGetUniformLocation(program,"bool2Uniform"); 3189 glUniform2f(location, 1.0f, 0.1f); 3190 verifyUniformValue2i(m_testCtx, *this, program, location, 1, 1); 3191 3192 location = glGetUniformLocation(program,"bool3Uniform"); 3193 glUniform3f(location, 0.0f, 0.1f, -0.1f); 3194 verifyUniformValue3i(m_testCtx, *this, program, location, 0, 1, 1); 3195 3196 location = glGetUniformLocation(program,"bool4Uniform"); 3197 glUniform4f(location, 1.0f, 0.0f, 0.1f, -0.9f); 3198 verifyUniformValue4i(m_testCtx, *this, program, location, 1, 0, 1, 1); 3199 3200 glUseProgram(0); 3201 glDeleteShader(shaderVert); 3202 glDeleteShader(shaderFrag); 3203 glDeleteProgram(program); 3204 expectError(GL_NO_ERROR); 3205 } 3206 }; 3207 3208 class UniformValueSamplerCase : public ApiCase 3209 { 3210 public: 3211 UniformValueSamplerCase (Context& context, const char* name, const char* description) 3212 : ApiCase(context, name, description) 3213 { 3214 } 3215 3216 void test (void) 3217 { 3218 static const char* testVertSource = 3219 "#version 300 es\n" 3220 "void main (void)\n" 3221 "{\n" 3222 " gl_Position = vec4(0.0);\n" 3223 "}\n"; 3224 static const char* testFragSource = 3225 "#version 300 es\n" 3226 "uniform highp sampler2D uniformSampler;\n" 3227 "layout(location = 0) out mediump vec4 fragColor;" 3228 "void main (void)\n" 3229 "{\n" 3230 " fragColor = vec4(textureSize(uniformSampler, 0).x);\n" 3231 "}\n"; 3232 3233 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 3234 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 3235 3236 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); 3237 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); 3238 3239 glCompileShader(shaderVert); 3240 glCompileShader(shaderFrag); 3241 expectError(GL_NO_ERROR); 3242 3243 GLuint program = glCreateProgram(); 3244 glAttachShader(program, shaderVert); 3245 glAttachShader(program, shaderFrag); 3246 glLinkProgram(program); 3247 glUseProgram(program); 3248 expectError(GL_NO_ERROR); 3249 3250 GLint location; 3251 3252 location = glGetUniformLocation(program,"uniformSampler"); 3253 glUniform1i(location, 1); 3254 verifyUniformValue1i(m_testCtx, *this, program, location, 1); 3255 3256 glUseProgram(0); 3257 glDeleteShader(shaderVert); 3258 glDeleteShader(shaderFrag); 3259 glDeleteProgram(program); 3260 expectError(GL_NO_ERROR); 3261 } 3262 }; 3263 3264 class UniformValueArrayCase : public ApiCase 3265 { 3266 public: 3267 UniformValueArrayCase (Context& context, const char* name, const char* description) 3268 : ApiCase(context, name, description) 3269 { 3270 } 3271 3272 void test (void) 3273 { 3274 static const char* testVertSource = 3275 "#version 300 es\n" 3276 "uniform highp float arrayUniform[5];" 3277 "uniform highp vec2 array2Uniform[5];" 3278 "uniform highp vec3 array3Uniform[5];" 3279 "uniform highp vec4 array4Uniform[5];" 3280 "void main (void)\n" 3281 "{\n" 3282 " gl_Position = \n" 3283 " + vec4(arrayUniform[0] + arrayUniform[1] + arrayUniform[2] + arrayUniform[3] + arrayUniform[4])\n" 3284 " + vec4(array2Uniform[0].x + array2Uniform[1].x + array2Uniform[2].x + array2Uniform[3].x + array2Uniform[4].x)\n" 3285 " + vec4(array3Uniform[0].x + array3Uniform[1].x + array3Uniform[2].x + array3Uniform[3].x + array3Uniform[4].x)\n" 3286 " + vec4(array4Uniform[0].x + array4Uniform[1].x + array4Uniform[2].x + array4Uniform[3].x + array4Uniform[4].x);\n" 3287 "}\n"; 3288 static const char* testFragSource = 3289 "#version 300 es\n" 3290 "layout(location = 0) out mediump vec4 fragColor;" 3291 "void main (void)\n" 3292 "{\n" 3293 " fragColor = vec4(0.0);\n" 3294 "}\n"; 3295 3296 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 3297 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 3298 3299 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); 3300 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); 3301 3302 glCompileShader(shaderVert); 3303 glCompileShader(shaderFrag); 3304 expectError(GL_NO_ERROR); 3305 3306 GLuint program = glCreateProgram(); 3307 glAttachShader(program, shaderVert); 3308 glAttachShader(program, shaderFrag); 3309 glLinkProgram(program); 3310 glUseProgram(program); 3311 expectError(GL_NO_ERROR); 3312 3313 GLint location; 3314 3315 float uniformValue[5 * 4] = 3316 { 3317 -1.0f, 0.1f, 4.0f, 800.0f, 3318 13.0f, 55.0f, 12.0f, 91.0f, 3319 -55.1f, 1.1f, 98.0f, 19.0f, 3320 41.0f, 65.0f, 4.0f, 12.2f, 3321 95.0f, 77.0f, 32.0f, 48.0f 3322 }; 3323 3324 location = glGetUniformLocation(program,"arrayUniform"); 3325 glUniform1fv(location, 5, uniformValue); 3326 expectError(GL_NO_ERROR); 3327 3328 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[0]"), uniformValue[0]); 3329 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[1]"), uniformValue[1]); 3330 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[2]"), uniformValue[2]); 3331 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[3]"), uniformValue[3]); 3332 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[4]"), uniformValue[4]); 3333 expectError(GL_NO_ERROR); 3334 3335 location = glGetUniformLocation(program,"array2Uniform"); 3336 glUniform2fv(location, 5, uniformValue); 3337 expectError(GL_NO_ERROR); 3338 3339 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[0]"), uniformValue[2 * 0], uniformValue[(2 * 0) + 1]); 3340 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[1]"), uniformValue[2 * 1], uniformValue[(2 * 1) + 1]); 3341 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[2]"), uniformValue[2 * 2], uniformValue[(2 * 2) + 1]); 3342 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[3]"), uniformValue[2 * 3], uniformValue[(2 * 3) + 1]); 3343 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[4]"), uniformValue[2 * 4], uniformValue[(2 * 4) + 1]); 3344 expectError(GL_NO_ERROR); 3345 3346 location = glGetUniformLocation(program,"array3Uniform"); 3347 glUniform3fv(location, 5, uniformValue); 3348 expectError(GL_NO_ERROR); 3349 3350 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[0]"), uniformValue[3 * 0], uniformValue[(3 * 0) + 1], uniformValue[(3 * 0) + 2]); 3351 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[1]"), uniformValue[3 * 1], uniformValue[(3 * 1) + 1], uniformValue[(3 * 1) + 2]); 3352 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[2]"), uniformValue[3 * 2], uniformValue[(3 * 2) + 1], uniformValue[(3 * 2) + 2]); 3353 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[3]"), uniformValue[3 * 3], uniformValue[(3 * 3) + 1], uniformValue[(3 * 3) + 2]); 3354 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[4]"), uniformValue[3 * 4], uniformValue[(3 * 4) + 1], uniformValue[(3 * 4) + 2]); 3355 expectError(GL_NO_ERROR); 3356 3357 location = glGetUniformLocation(program,"array4Uniform"); 3358 glUniform4fv(location, 5, uniformValue); 3359 expectError(GL_NO_ERROR); 3360 3361 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[0]"), uniformValue[4 * 0], uniformValue[(4 * 0) + 1], uniformValue[(4 * 0) + 2], uniformValue[(4 * 0) + 3]); 3362 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[1]"), uniformValue[4 * 1], uniformValue[(4 * 1) + 1], uniformValue[(4 * 1) + 2], uniformValue[(4 * 1) + 3]); 3363 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[2]"), uniformValue[4 * 2], uniformValue[(4 * 2) + 1], uniformValue[(4 * 2) + 2], uniformValue[(4 * 2) + 3]); 3364 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[3]"), uniformValue[4 * 3], uniformValue[(4 * 3) + 1], uniformValue[(4 * 3) + 2], uniformValue[(4 * 3) + 3]); 3365 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[4]"), uniformValue[4 * 4], uniformValue[(4 * 4) + 1], uniformValue[(4 * 4) + 2], uniformValue[(4 * 4) + 3]); 3366 expectError(GL_NO_ERROR); 3367 3368 glUseProgram(0); 3369 glDeleteShader(shaderVert); 3370 glDeleteShader(shaderFrag); 3371 glDeleteProgram(program); 3372 expectError(GL_NO_ERROR); 3373 } 3374 }; 3375 3376 class UniformValueMatrixCase : public ApiCase 3377 { 3378 public: 3379 UniformValueMatrixCase (Context& context, const char* name, const char* description) 3380 : ApiCase(context, name, description) 3381 { 3382 } 3383 3384 void test (void) 3385 { 3386 static const char* testVertSource = 3387 "#version 300 es\n" 3388 "uniform highp mat2 mat2Uniform;" 3389 "uniform highp mat3 mat3Uniform;" 3390 "uniform highp mat4 mat4Uniform;" 3391 "void main (void)\n" 3392 "{\n" 3393 " gl_Position = vec4(mat2Uniform[0][0] + mat3Uniform[0][0] + mat4Uniform[0][0]);\n" 3394 "}\n"; 3395 static const char* testFragSource = 3396 "#version 300 es\n" 3397 "layout(location = 0) out mediump vec4 fragColor;" 3398 "void main (void)\n" 3399 "{\n" 3400 " fragColor = vec4(0.0);\n" 3401 "}\n"; 3402 3403 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 3404 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 3405 3406 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); 3407 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); 3408 3409 glCompileShader(shaderVert); 3410 glCompileShader(shaderFrag); 3411 expectError(GL_NO_ERROR); 3412 3413 GLuint program = glCreateProgram(); 3414 glAttachShader(program, shaderVert); 3415 glAttachShader(program, shaderFrag); 3416 glLinkProgram(program); 3417 glUseProgram(program); 3418 expectError(GL_NO_ERROR); 3419 3420 GLint location; 3421 3422 float matrixValues[4 * 4] = 3423 { 3424 -1.0f, 0.1f, 4.0f, 800.0f, 3425 13.0f, 55.0f, 12.0f, 91.0f, 3426 -55.1f, 1.1f, 98.0f, 19.0f, 3427 41.0f, 65.0f, 4.0f, 12.2f, 3428 }; 3429 3430 // the values of the matrix are returned in column major order but they can be given in either order 3431 3432 location = glGetUniformLocation(program,"mat2Uniform"); 3433 glUniformMatrix2fv(location, 1, GL_FALSE, matrixValues); 3434 verifyUniformMatrixValues<2>(m_testCtx, *this, program, location, matrixValues, false); 3435 glUniformMatrix2fv(location, 1, GL_TRUE, matrixValues); 3436 verifyUniformMatrixValues<2>(m_testCtx, *this, program, location, matrixValues, true); 3437 3438 location = glGetUniformLocation(program,"mat3Uniform"); 3439 glUniformMatrix3fv(location, 1, GL_FALSE, matrixValues); 3440 verifyUniformMatrixValues<3>(m_testCtx, *this, program, location, matrixValues, false); 3441 glUniformMatrix3fv(location, 1, GL_TRUE, matrixValues); 3442 verifyUniformMatrixValues<3>(m_testCtx, *this, program, location, matrixValues, true); 3443 3444 location = glGetUniformLocation(program,"mat4Uniform"); 3445 glUniformMatrix4fv(location, 1, GL_FALSE, matrixValues); 3446 verifyUniformMatrixValues<4>(m_testCtx, *this, program, location, matrixValues, false); 3447 glUniformMatrix4fv(location, 1, GL_TRUE, matrixValues); 3448 verifyUniformMatrixValues<4>(m_testCtx, *this, program, location, matrixValues, true); 3449 3450 glUseProgram(0); 3451 glDeleteShader(shaderVert); 3452 glDeleteShader(shaderFrag); 3453 glDeleteProgram(program); 3454 expectError(GL_NO_ERROR); 3455 } 3456 }; 3457 3458 class PrecisionFormatCase : public ApiCase 3459 { 3460 public: 3461 struct RequiredFormat 3462 { 3463 int negativeRange; 3464 int positiveRange; 3465 int precision; 3466 }; 3467 3468 PrecisionFormatCase (Context& context, const char* name, const char* description, glw::GLenum shaderType, glw::GLenum precisionType) 3469 : ApiCase (context, name, description) 3470 , m_shaderType (shaderType) 3471 , m_precisionType (precisionType) 3472 { 3473 } 3474 3475 private: 3476 void test (void) 3477 { 3478 const RequiredFormat expected = getRequiredFormat(); 3479 bool error = false; 3480 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLboolean> shaderCompiler; 3481 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint[2]> range; 3482 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint> precision; 3483 3484 // query values 3485 glGetShaderPrecisionFormat(m_shaderType, m_precisionType, range, &precision); 3486 expectError(GL_NO_ERROR); 3487 3488 if (!range.verifyValidity(m_testCtx)) 3489 return; 3490 if (!precision.verifyValidity(m_testCtx)) 3491 return; 3492 3493 m_log 3494 << tcu::TestLog::Message 3495 << "range[0] = " << range[0] << "\n" 3496 << "range[1] = " << range[1] << "\n" 3497 << "precision = " << precision 3498 << tcu::TestLog::EndMessage; 3499 3500 // verify values 3501 3502 if (m_precisionType == GL_HIGH_FLOAT) 3503 { 3504 // highp float must be IEEE 754 single 3505 3506 if (range[0] != expected.negativeRange || 3507 range[1] != expected.positiveRange || 3508 precision != expected.precision) 3509 { 3510 m_log 3511 << tcu::TestLog::Message 3512 << "// ERROR: Invalid precision format, expected:\n" 3513 << "\trange[0] = " << expected.negativeRange << "\n" 3514 << "\trange[1] = " << expected.positiveRange << "\n" 3515 << "\tprecision = " << expected.precision 3516 << tcu::TestLog::EndMessage; 3517 error = true; 3518 } 3519 } 3520 else 3521 { 3522 if (range[0] < expected.negativeRange) 3523 { 3524 m_log << tcu::TestLog::Message << "// ERROR: Invalid range[0], expected greater or equal to " << expected.negativeRange << tcu::TestLog::EndMessage; 3525 error = true; 3526 } 3527 3528 if (range[1] < expected.positiveRange) 3529 { 3530 m_log << tcu::TestLog::Message << "// ERROR: Invalid range[1], expected greater or equal to " << expected.positiveRange << tcu::TestLog::EndMessage; 3531 error = true; 3532 } 3533 3534 if (precision < expected.precision) 3535 { 3536 m_log << tcu::TestLog::Message << "// ERROR: Invalid precision, expected greater or equal to " << expected.precision << tcu::TestLog::EndMessage; 3537 error = true; 3538 } 3539 } 3540 3541 if (error) 3542 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid precision/range"); 3543 } 3544 3545 RequiredFormat getRequiredFormat (void) const 3546 { 3547 // Precisions for different types. 3548 const RequiredFormat requirements[] = 3549 { 3550 { 0, 0, 8 }, //!< lowp float 3551 { 13, 13, 10 }, //!< mediump float 3552 { 127, 127, 23 }, //!< highp float 3553 { 8, 7, 0 }, //!< lowp int 3554 { 15, 14, 0 }, //!< mediump int 3555 { 31, 30, 0 }, //!< highp int 3556 }; 3557 const int ndx = (int)m_precisionType - (int)GL_LOW_FLOAT; 3558 3559 DE_ASSERT(ndx >= 0); 3560 DE_ASSERT(ndx < DE_LENGTH_OF_ARRAY(requirements)); 3561 return requirements[ndx]; 3562 } 3563 3564 const glw::GLenum m_shaderType; 3565 const glw::GLenum m_precisionType; 3566 }; 3567 3568 } // anonymous 3569 3570 3571 ShaderStateQueryTests::ShaderStateQueryTests (Context& context) 3572 : TestCaseGroup(context, "shader", "Shader State Query tests") 3573 { 3574 } 3575 3576 void ShaderStateQueryTests::init (void) 3577 { 3578 // shader 3579 addChild(new ShaderTypeCase (m_context, "shader_type", "SHADER_TYPE")); 3580 addChild(new ShaderCompileStatusCase (m_context, "shader_compile_status", "COMPILE_STATUS")); 3581 addChild(new ShaderInfoLogCase (m_context, "shader_info_log_length", "INFO_LOG_LENGTH")); 3582 addChild(new ShaderSourceCase (m_context, "shader_source_length", "SHADER_SOURCE_LENGTH")); 3583 3584 // shader and program 3585 addChild(new DeleteStatusCase (m_context, "delete_status", "DELETE_STATUS")); 3586 3587 // vertex-attrib 3588 addChild(new CurrentVertexAttribInitialCase (m_context, "current_vertex_attrib_initial", "CURRENT_VERTEX_ATTRIB")); 3589 addChild(new CurrentVertexAttribFloatCase (m_context, "current_vertex_attrib_float", "CURRENT_VERTEX_ATTRIB")); 3590 addChild(new CurrentVertexAttribIntCase (m_context, "current_vertex_attrib_int", "CURRENT_VERTEX_ATTRIB")); 3591 addChild(new CurrentVertexAttribUintCase (m_context, "current_vertex_attrib_uint", "CURRENT_VERTEX_ATTRIB")); 3592 addChild(new CurrentVertexAttribConversionCase (m_context, "current_vertex_attrib_float_to_int", "CURRENT_VERTEX_ATTRIB")); 3593 3594 // program 3595 addChild(new ProgramInfoLogCase (m_context, "program_info_log_length", "INFO_LOG_LENGTH")); 3596 addChild(new ProgramValidateStatusCase (m_context, "program_validate_status", "VALIDATE_STATUS")); 3597 addChild(new ProgramAttachedShadersCase (m_context, "program_attached_shaders", "ATTACHED_SHADERS")); 3598 3599 addChild(new ProgramActiveUniformNameCase (m_context, "program_active_uniform_name", "ACTIVE_UNIFORMS and ACTIVE_UNIFORM_MAX_LENGTH")); 3600 addChild(new ProgramUniformCase (m_context, "program_active_uniform_types", "UNIFORM_TYPE, UNIFORM_SIZE, and UNIFORM_IS_ROW_MAJOR")); 3601 addChild(new ProgramActiveUniformBlocksCase (m_context, "program_active_uniform_blocks", "ACTIVE_UNIFORM_BLOCK_x")); 3602 addChild(new ProgramBinaryCase (m_context, "program_binary", "PROGRAM_BINARY_LENGTH and PROGRAM_BINARY_RETRIEVABLE_HINT")); 3603 3604 // transform feedback 3605 addChild(new TransformFeedbackCase (m_context, "transform_feedback", "TRANSFORM_FEEDBACK_BUFFER_MODE, TRANSFORM_FEEDBACK_VARYINGS, TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH")); 3606 3607 // attribute related 3608 addChild(new ActiveAttributesCase (m_context, "active_attributes", "ACTIVE_ATTRIBUTES and ACTIVE_ATTRIBUTE_MAX_LENGTH")); 3609 addChild(new VertexAttributeSizeCase (m_context, "vertex_attrib_size", "VERTEX_ATTRIB_ARRAY_SIZE")); 3610 addChild(new VertexAttributeTypeCase (m_context, "vertex_attrib_type", "VERTEX_ATTRIB_ARRAY_TYPE")); 3611 addChild(new VertexAttributeStrideCase (m_context, "vertex_attrib_stride", "VERTEX_ATTRIB_ARRAY_STRIDE")); 3612 addChild(new VertexAttributeNormalizedCase (m_context, "vertex_attrib_normalized", "VERTEX_ATTRIB_ARRAY_NORMALIZED")); 3613 addChild(new VertexAttributeIntegerCase (m_context, "vertex_attrib_integer", "VERTEX_ATTRIB_ARRAY_INTEGER")); 3614 addChild(new VertexAttributeEnabledCase (m_context, "vertex_attrib_array_enabled", "VERTEX_ATTRIB_ARRAY_ENABLED")); 3615 addChild(new VertexAttributeDivisorCase (m_context, "vertex_attrib_array_divisor", "VERTEX_ATTRIB_ARRAY_DIVISOR")); 3616 addChild(new VertexAttributeBufferBindingCase (m_context, "vertex_attrib_array_buffer_binding", "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING")); 3617 addChild(new VertexAttributePointerCase (m_context, "vertex_attrib_pointerv", "GetVertexAttribPointerv")); 3618 3619 // uniform values 3620 addChild(new UniformValueFloatCase (m_context, "uniform_value_float", "GetUniform*")); 3621 addChild(new UniformValueIntCase (m_context, "uniform_value_int", "GetUniform*")); 3622 addChild(new UniformValueUintCase (m_context, "uniform_value_uint", "GetUniform*")); 3623 addChild(new UniformValueBooleanCase (m_context, "uniform_value_boolean", "GetUniform*")); 3624 addChild(new UniformValueSamplerCase (m_context, "uniform_value_sampler", "GetUniform*")); 3625 addChild(new UniformValueArrayCase (m_context, "uniform_value_array", "GetUniform*")); 3626 addChild(new UniformValueMatrixCase (m_context, "uniform_value_matrix", "GetUniform*")); 3627 3628 // precision format query 3629 addChild(new PrecisionFormatCase (m_context, "precision_vertex_lowp_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_LOW_FLOAT)); 3630 addChild(new PrecisionFormatCase (m_context, "precision_vertex_mediump_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_MEDIUM_FLOAT)); 3631 addChild(new PrecisionFormatCase (m_context, "precision_vertex_highp_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_HIGH_FLOAT)); 3632 addChild(new PrecisionFormatCase (m_context, "precision_vertex_lowp_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_LOW_INT)); 3633 addChild(new PrecisionFormatCase (m_context, "precision_vertex_mediump_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_MEDIUM_INT)); 3634 addChild(new PrecisionFormatCase (m_context, "precision_vertex_highp_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_HIGH_INT)); 3635 addChild(new PrecisionFormatCase (m_context, "precision_fragment_lowp_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_LOW_FLOAT)); 3636 addChild(new PrecisionFormatCase (m_context, "precision_fragment_mediump_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT)); 3637 addChild(new PrecisionFormatCase (m_context, "precision_fragment_highp_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_HIGH_FLOAT)); 3638 addChild(new PrecisionFormatCase (m_context, "precision_fragment_lowp_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_LOW_INT)); 3639 addChild(new PrecisionFormatCase (m_context, "precision_fragment_mediump_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_MEDIUM_INT)); 3640 addChild(new PrecisionFormatCase (m_context, "precision_fragment_highp_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_HIGH_INT)); 3641 } 3642 3643 } // Functional 3644 } // gles3 3645 } // deqp 3646