1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 2.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 "es2fShaderStateQueryTests.hpp" 25 #include "glsStateQueryUtil.hpp" 26 #include "es2fApiCase.hpp" 27 #include "gluRenderContext.hpp" 28 #include "gluShaderProgram.hpp" 29 #include "glwEnums.hpp" 30 #include "glwFunctions.hpp" 31 #include "deRandom.hpp" 32 #include "deMath.h" 33 #include "deString.h" 34 35 using namespace glw; // GLint and other GL types 36 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard; 37 38 namespace deqp 39 { 40 namespace gles2 41 { 42 namespace Functional 43 { 44 namespace 45 { 46 47 static const char* commonTestVertSource = "void main (void)\n" 48 "{\n" 49 " gl_Position = vec4(0.0);\n" 50 "}\n"; 51 static const char* commonTestFragSource = "void main (void)\n" 52 "{\n" 53 " gl_FragColor = vec4(0.0);\n" 54 "}\n"; 55 56 static const char* brokenShader = "broken, this should not compile!\n" 57 "\n"; 58 59 // rounds x.1 to x+1 60 template <typename T> 61 T roundGLfloatToNearestIntegerUp (GLfloat val) 62 { 63 return (T)(ceil(val)); 64 } 65 66 // rounds x.9 to x 67 template <typename T> 68 T roundGLfloatToNearestIntegerDown (GLfloat val) 69 { 70 return (T)(floor(val)); 71 } 72 73 bool checkIntEquals (tcu::TestContext& testCtx, GLint got, GLint expected) 74 { 75 using tcu::TestLog; 76 77 if (got != expected) 78 { 79 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage; 80 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 81 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value"); 82 return false; 83 } 84 return true; 85 } 86 87 void checkPointerEquals (tcu::TestContext& testCtx, const void* got, const void* expected) 88 { 89 using tcu::TestLog; 90 91 if (got != expected) 92 { 93 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage; 94 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 95 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value"); 96 } 97 } 98 99 void verifyShaderParam (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint shader, GLenum pname, GLenum reference) 100 { 101 StateQueryMemoryWriteGuard<GLint> state; 102 gl.glGetShaderiv(shader, pname, &state); 103 104 if (state.verifyValidity(testCtx)) 105 checkIntEquals(testCtx, state, reference); 106 } 107 108 bool verifyProgramParam (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLenum pname, GLenum reference) 109 { 110 StateQueryMemoryWriteGuard<GLint> state; 111 gl.glGetProgramiv(program, pname, &state); 112 113 if (state.verifyValidity(testCtx)) 114 return checkIntEquals(testCtx, state, reference); 115 return false; 116 } 117 118 void verifyCurrentVertexAttribf (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 119 { 120 using tcu::TestLog; 121 122 StateQueryMemoryWriteGuard<GLfloat[4]> attribValue; 123 gl.glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue); 124 125 attribValue.verifyValidity(testCtx); 126 127 if (attribValue[0] != x || attribValue[1] != y || attribValue[2] != z || attribValue[3] != w) 128 { 129 testCtx.getLog() << TestLog::Message 130 << "// ERROR: Expected [" << x << "," << y << "," << z << "," << w << "];" 131 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << "," << attribValue[3] << "]" 132 << TestLog::EndMessage; 133 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 134 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value"); 135 } 136 } 137 138 void verifyCurrentVertexAttribConversion (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 139 { 140 using tcu::TestLog; 141 142 StateQueryMemoryWriteGuard<GLint[4]> attribValue; 143 gl.glGetVertexAttribiv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue); 144 145 attribValue.verifyValidity(testCtx); 146 147 const GLint referenceAsGLintMin[] = 148 { 149 roundGLfloatToNearestIntegerDown<GLint>(x), 150 roundGLfloatToNearestIntegerDown<GLint>(y), 151 roundGLfloatToNearestIntegerDown<GLint>(z), 152 roundGLfloatToNearestIntegerDown<GLint>(w) 153 }; 154 const GLint referenceAsGLintMax[] = 155 { 156 roundGLfloatToNearestIntegerUp<GLint>(x), 157 roundGLfloatToNearestIntegerUp<GLint>(y), 158 roundGLfloatToNearestIntegerUp<GLint>(z), 159 roundGLfloatToNearestIntegerUp<GLint>(w) 160 }; 161 162 if (attribValue[0] < referenceAsGLintMin[0] || attribValue[0] > referenceAsGLintMax[0] || 163 attribValue[1] < referenceAsGLintMin[1] || attribValue[1] > referenceAsGLintMax[1] || 164 attribValue[2] < referenceAsGLintMin[2] || attribValue[2] > referenceAsGLintMax[2] || 165 attribValue[3] < referenceAsGLintMin[3] || attribValue[3] > referenceAsGLintMax[3]) 166 { 167 testCtx.getLog() << TestLog::Message 168 << "// ERROR: expected in range " 169 << "[" << referenceAsGLintMin[0] << " " << referenceAsGLintMax[0] << "], " 170 << "[" << referenceAsGLintMin[1] << " " << referenceAsGLintMax[1] << "], " 171 << "[" << referenceAsGLintMin[2] << " " << referenceAsGLintMax[2] << "], " 172 << "[" << referenceAsGLintMin[3] << " " << referenceAsGLintMax[3] << "]" 173 << "; got " 174 << attribValue[0] << ", " 175 << attribValue[1] << ", " 176 << attribValue[2] << ", " 177 << attribValue[3] << " " 178 << "; Input=" 179 << x << "; " 180 << y << "; " 181 << z << "; " 182 << w << " " << TestLog::EndMessage; 183 184 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 185 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid attribute value"); 186 } 187 } 188 189 void verifyVertexAttrib (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLenum pname, GLenum reference) 190 { 191 StateQueryMemoryWriteGuard<GLint> state; 192 gl.glGetVertexAttribiv(index, pname, &state); 193 194 if (state.verifyValidity(testCtx)) 195 checkIntEquals(testCtx, state, reference); 196 } 197 198 void verifyUniformValue1f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x) 199 { 200 using tcu::TestLog; 201 202 StateQueryMemoryWriteGuard<GLfloat[1]> state; 203 gl.glGetUniformfv(program, location, state); 204 205 if (!state.verifyValidity(testCtx)) 206 return; 207 208 if (state[0] != x) 209 { 210 testCtx.getLog() << TestLog::Message 211 << "// ERROR: expected [" 212 << x 213 << "]; got [" 214 << state[0] 215 << "]" 216 << TestLog::EndMessage; 217 218 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 219 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 220 } 221 } 222 223 void verifyUniformValue2f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y) 224 { 225 using tcu::TestLog; 226 227 StateQueryMemoryWriteGuard<GLfloat[2]> state; 228 gl.glGetUniformfv(program, location, state); 229 230 if (!state.verifyValidity(testCtx)) 231 return; 232 233 if (state[0] != x || 234 state[1] != y) 235 { 236 testCtx.getLog() << TestLog::Message 237 << "// ERROR: expected [" 238 << x << ", " 239 << y 240 << "]; got [" 241 << state[0] << ", " 242 << state[1] 243 << "]" 244 << TestLog::EndMessage; 245 246 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 247 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 248 } 249 } 250 251 void verifyUniformValue3f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y, float z) 252 { 253 using tcu::TestLog; 254 255 StateQueryMemoryWriteGuard<GLfloat[3]> state; 256 gl.glGetUniformfv(program, location, state); 257 258 if (!state.verifyValidity(testCtx)) 259 return; 260 261 if (state[0] != x || 262 state[1] != y || 263 state[2] != z) 264 { 265 testCtx.getLog() << TestLog::Message 266 << "// ERROR: expected [" 267 << x << ", " 268 << y << ", " 269 << z 270 << "]; got [" 271 << state[0] << ", " 272 << state[1] << ", " 273 << state[2] 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 verifyUniformValue4f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y, float z, float w) 283 { 284 using tcu::TestLog; 285 286 StateQueryMemoryWriteGuard<GLfloat[4]> 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 state[2] != z || 295 state[3] != w) 296 { 297 testCtx.getLog() << TestLog::Message 298 << "// ERROR: expected [" 299 << x << ", " 300 << y << ", " 301 << z << ", " 302 << w 303 << "]; got [" 304 << state[0] << ", " 305 << state[1] << ", " 306 << state[2] << ", " 307 << state[3] 308 << "]" 309 << TestLog::EndMessage; 310 311 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 312 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 313 } 314 } 315 316 void verifyUniformValue1i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x) 317 { 318 using tcu::TestLog; 319 320 StateQueryMemoryWriteGuard<GLint[1]> state; 321 gl.glGetUniformiv(program, location, state); 322 323 if (!state.verifyValidity(testCtx)) 324 return; 325 326 if (state[0] != x) 327 { 328 testCtx.getLog() << TestLog::Message 329 << "// ERROR: expected [" 330 << x 331 << "]; got [" 332 << state[0] 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 verifyUniformValue2i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y) 342 { 343 using tcu::TestLog; 344 345 StateQueryMemoryWriteGuard<GLint[2]> state; 346 gl.glGetUniformiv(program, location, state); 347 348 if (!state.verifyValidity(testCtx)) 349 return; 350 351 if (state[0] != x || 352 state[1] != y) 353 { 354 testCtx.getLog() << TestLog::Message 355 << "// ERROR: expected [" 356 << x << ", " 357 << y 358 << "]; got [" 359 << state[0] << ", " 360 << state[1] 361 << "]" 362 << TestLog::EndMessage; 363 364 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 365 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 366 } 367 } 368 369 void verifyUniformValue3i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y, GLint z) 370 { 371 using tcu::TestLog; 372 373 StateQueryMemoryWriteGuard<GLint[3]> state; 374 gl.glGetUniformiv(program, location, state); 375 376 if (!state.verifyValidity(testCtx)) 377 return; 378 379 if (state[0] != x || 380 state[1] != y || 381 state[2] != z) 382 { 383 testCtx.getLog() << TestLog::Message 384 << "// ERROR: expected [" 385 << x << ", " 386 << y << ", " 387 << z 388 << "]; got [" 389 << state[0] << ", " 390 << state[1] << ", " 391 << state[2] 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 verifyUniformValue4i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w) 401 { 402 using tcu::TestLog; 403 404 StateQueryMemoryWriteGuard<GLint[4]> 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 state[2] != z || 413 state[3] != w) 414 { 415 testCtx.getLog() << TestLog::Message 416 << "// ERROR: expected [" 417 << x << ", " 418 << y << ", " 419 << z << ", " 420 << w 421 << "]; got [" 422 << state[0] << ", " 423 << state[1] << ", " 424 << state[2] << ", " 425 << state[3] 426 << "]" 427 << TestLog::EndMessage; 428 429 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 430 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 431 } 432 } 433 434 template <int Count> 435 void verifyUniformValues (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, const GLfloat* values) 436 { 437 using tcu::TestLog; 438 439 StateQueryMemoryWriteGuard<GLfloat[Count]> state; 440 gl.glGetUniformfv(program, location, state); 441 442 if (!state.verifyValidity(testCtx)) 443 return; 444 445 for (int ndx = 0; ndx < Count; ++ndx) 446 { 447 if (values[ndx] != state[ndx]) 448 { 449 testCtx.getLog() << TestLog::Message << "// ERROR: at index " << ndx << " expected " << values[ndx] << "; got " << state[ndx] << TestLog::EndMessage; 450 451 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 452 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 453 } 454 } 455 } 456 457 template <int N> 458 void verifyUniformMatrixValues (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, const GLfloat* values, bool transpose) 459 { 460 using tcu::TestLog; 461 462 StateQueryMemoryWriteGuard<GLfloat[N*N]> state; 463 gl.glGetUniformfv(program, location, state); 464 465 if (!state.verifyValidity(testCtx)) 466 return; 467 468 for (int y = 0; y < N; ++y) 469 for (int x = 0; x < N; ++x) 470 { 471 const int refIndex = y*N + x; 472 const int stateIndex = transpose ? (x*N + y) : (y*N + x); 473 474 if (values[refIndex] != state[stateIndex]) 475 { 476 testCtx.getLog() << TestLog::Message << "// ERROR: at index [" << y << "][" << x << "] expected " << values[refIndex] << "; got " << state[stateIndex] << TestLog::EndMessage; 477 478 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 479 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value"); 480 } 481 } 482 } 483 484 void requireShaderCompiler (tcu::TestContext& testCtx, glu::CallLogWrapper& gl) 485 { 486 StateQueryMemoryWriteGuard<GLboolean> state; 487 gl.glGetBooleanv(GL_SHADER_COMPILER, &state); 488 489 if (!state.verifyValidity(testCtx) || state != GL_TRUE) 490 throw tcu::NotSupportedError("Test requires SHADER_COMPILER = TRUE"); 491 } 492 493 class ShaderTypeCase : public ApiCase 494 { 495 public: 496 ShaderTypeCase (Context& context, const char* name, const char* description) 497 : ApiCase(context, name, description) 498 { 499 } 500 501 void test (void) 502 { 503 const GLenum shaderTypes[] = {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER}; 504 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(shaderTypes); ++ndx) 505 { 506 const GLuint shader = glCreateShader(shaderTypes[ndx]); 507 verifyShaderParam(m_testCtx, *this, shader, GL_SHADER_TYPE, shaderTypes[ndx]); 508 glDeleteShader(shader); 509 } 510 } 511 }; 512 513 class ShaderCompileStatusCase : public ApiCase 514 { 515 public: 516 ShaderCompileStatusCase (Context& context, const char* name, const char* description) 517 : ApiCase(context, name, description) 518 { 519 } 520 521 void test (void) 522 { 523 requireShaderCompiler(m_testCtx, *this); 524 525 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 526 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 527 528 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_FALSE); 529 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_FALSE); 530 531 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL); 532 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL); 533 534 glCompileShader(shaderVert); 535 glCompileShader(shaderFrag); 536 expectError(GL_NO_ERROR); 537 538 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE); 539 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE); 540 541 glDeleteShader(shaderVert); 542 glDeleteShader(shaderFrag); 543 expectError(GL_NO_ERROR); 544 } 545 }; 546 547 class ShaderInfoLogCase : public ApiCase 548 { 549 public: 550 ShaderInfoLogCase (Context& context, const char* name, const char* description) 551 : ApiCase(context, name, description) 552 { 553 } 554 555 void test (void) 556 { 557 requireShaderCompiler(m_testCtx, *this); 558 559 using tcu::TestLog; 560 561 // INFO_LOG_LENGTH is 0 by default and it includes null-terminator 562 const GLuint shader = glCreateShader(GL_VERTEX_SHADER); 563 verifyShaderParam(m_testCtx, *this, shader, GL_INFO_LOG_LENGTH, 0); 564 565 glShaderSource(shader, 1, &brokenShader, DE_NULL); 566 glCompileShader(shader); 567 expectError(GL_NO_ERROR); 568 569 // check the log length 570 StateQueryMemoryWriteGuard<GLint> logLength; 571 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); 572 if (!logLength.verifyValidity(m_testCtx)) 573 { 574 glDeleteShader(shader); 575 return; 576 } 577 if (logLength == 0) 578 { 579 glDeleteShader(shader); 580 return; 581 } 582 583 // check normal case 584 { 585 char buffer[2048] = {'x'}; // non-zero initialization 586 587 GLint written = 0; // written does not include null terminator 588 glGetShaderInfoLog(shader, DE_LENGTH_OF_ARRAY(buffer), &written, buffer); 589 590 // check lengths are consistent 591 if (logLength <= DE_LENGTH_OF_ARRAY(buffer)) 592 { 593 if (written != logLength-1) 594 { 595 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << logLength-1 << "; got " << written << TestLog::EndMessage; 596 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 597 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length"); 598 } 599 } 600 601 // check null-terminator, either at end of buffer or at buffer[written] 602 const char* terminator = &buffer[DE_LENGTH_OF_ARRAY(buffer) - 1]; 603 if (logLength < DE_LENGTH_OF_ARRAY(buffer)) 604 terminator = &buffer[written]; 605 606 if (*terminator != '\0') 607 { 608 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator, got " << (int)*terminator << TestLog::EndMessage; 609 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 610 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log terminator"); 611 } 612 } 613 614 // check with too small buffer 615 { 616 char buffer[2048] = {'x'}; // non-zero initialization 617 618 // check string always ends with \0, even with small buffers 619 GLint written = 0; 620 glGetShaderInfoLog(shader, 1, &written, buffer); 621 if (written != 0) 622 { 623 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length 0; got " << written << TestLog::EndMessage; 624 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 625 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length"); 626 } 627 if (buffer[0] != '\0') 628 { 629 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator, got " << (int)buffer[0] << TestLog::EndMessage; 630 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 631 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log terminator"); 632 } 633 } 634 635 glDeleteShader(shader); 636 expectError(GL_NO_ERROR); 637 } 638 }; 639 640 class ShaderSourceCase : public ApiCase 641 { 642 public: 643 ShaderSourceCase (Context& context, const char* name, const char* description) 644 : ApiCase(context, name, description) 645 { 646 } 647 648 void test (void) 649 { 650 requireShaderCompiler(m_testCtx, *this); 651 652 using tcu::TestLog; 653 654 // SHADER_SOURCE_LENGTH does include 0-terminator 655 const GLuint shader = glCreateShader(GL_VERTEX_SHADER); 656 verifyShaderParam(m_testCtx, *this, shader, GL_SHADER_SOURCE_LENGTH, 0); 657 658 // check the SHADER_SOURCE_LENGTH 659 { 660 glShaderSource(shader, 1, &brokenShader, DE_NULL); 661 expectError(GL_NO_ERROR); 662 663 StateQueryMemoryWriteGuard<GLint> sourceLength; 664 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength); 665 666 sourceLength.verifyValidity(m_testCtx); 667 668 const GLint referenceLength = (GLint)std::string(brokenShader).length() + 1; // including the null terminator 669 if (sourceLength != referenceLength) 670 { 671 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << referenceLength << "; got " << sourceLength << TestLog::EndMessage; 672 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 673 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length"); 674 } 675 } 676 677 // check the concat source SHADER_SOURCE_LENGTH 678 { 679 const char* shaders[] = {brokenShader, brokenShader}; 680 glShaderSource(shader, 2, shaders, DE_NULL); 681 expectError(GL_NO_ERROR); 682 683 StateQueryMemoryWriteGuard<GLint> sourceLength; 684 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength); 685 686 sourceLength.verifyValidity(m_testCtx); 687 688 const GLint referenceLength = 2 * (GLint)std::string(brokenShader).length() + 1; // including the null terminator 689 if (sourceLength != referenceLength) 690 { 691 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << referenceLength << "; got " << sourceLength << TestLog::EndMessage; 692 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 693 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length"); 694 } 695 } 696 697 // check the string length 698 { 699 char buffer[2048] = {'x'}; 700 DE_ASSERT(DE_LENGTH_OF_ARRAY(buffer) > 2 * (int)std::string(brokenShader).length()); 701 702 GLint written = 0; // not inluding null-terminator 703 glGetShaderSource(shader, DE_LENGTH_OF_ARRAY(buffer), &written, buffer); 704 705 const GLint referenceLength = 2 * (GLint)std::string(brokenShader).length(); 706 if (written != referenceLength) 707 { 708 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length " << referenceLength << "; got " << written << TestLog::EndMessage; 709 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 710 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length"); 711 } 712 // check null pointer at 713 else 714 { 715 if (buffer[referenceLength] != '\0') 716 { 717 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator at " << referenceLength << TestLog::EndMessage; 718 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 719 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "did not get a null terminator"); 720 } 721 } 722 } 723 724 // check with small buffer 725 { 726 char buffer[2048] = {'x'}; 727 728 GLint written = 0; 729 glGetShaderSource(shader, 1, &written, buffer); 730 731 if (written != 0) 732 { 733 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length 0; got " << written << TestLog::EndMessage; 734 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 735 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length"); 736 } 737 if (buffer[0] != '\0') 738 { 739 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator; got=" << int(buffer[0]) << ", char=" << buffer[0] << TestLog::EndMessage; 740 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 741 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid terminator"); 742 } 743 } 744 745 glDeleteShader(shader); 746 expectError(GL_NO_ERROR); 747 } 748 }; 749 750 class DeleteStatusCase : public ApiCase 751 { 752 public: 753 DeleteStatusCase (Context& context, const char* name, const char* description) 754 : ApiCase(context, name, description) 755 { 756 } 757 758 void test (void) 759 { 760 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 761 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 762 763 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL); 764 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL); 765 766 glCompileShader(shaderVert); 767 glCompileShader(shaderFrag); 768 expectError(GL_NO_ERROR); 769 770 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE); 771 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE); 772 773 GLuint shaderProg = glCreateProgram(); 774 glAttachShader(shaderProg, shaderVert); 775 glAttachShader(shaderProg, shaderFrag); 776 glLinkProgram(shaderProg); 777 expectError(GL_NO_ERROR); 778 779 verifyProgramParam (m_testCtx, *this, shaderProg, GL_LINK_STATUS, GL_TRUE); 780 781 verifyShaderParam (m_testCtx, *this, shaderVert, GL_DELETE_STATUS, GL_FALSE); 782 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_DELETE_STATUS, GL_FALSE); 783 verifyProgramParam (m_testCtx, *this, shaderProg, GL_DELETE_STATUS, GL_FALSE); 784 expectError(GL_NO_ERROR); 785 786 glUseProgram(shaderProg); 787 788 glDeleteShader(shaderVert); 789 glDeleteShader(shaderFrag); 790 glDeleteProgram(shaderProg); 791 expectError(GL_NO_ERROR); 792 793 verifyShaderParam (m_testCtx, *this, shaderVert, GL_DELETE_STATUS, GL_TRUE); 794 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_DELETE_STATUS, GL_TRUE); 795 verifyProgramParam (m_testCtx, *this, shaderProg, GL_DELETE_STATUS, GL_TRUE); 796 expectError(GL_NO_ERROR); 797 798 glUseProgram(0); 799 expectError(GL_NO_ERROR); 800 } 801 }; 802 803 class CurrentVertexAttribInitialCase : public ApiCase 804 { 805 public: 806 CurrentVertexAttribInitialCase (Context& context, const char* name, const char* description) 807 : ApiCase(context, name, description) 808 { 809 } 810 811 void test (void) 812 { 813 using tcu::TestLog; 814 815 int attribute_count = 16; 816 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count); 817 818 // initial 819 820 for (int index = 0; index < attribute_count; ++index) 821 { 822 StateQueryMemoryWriteGuard<GLfloat[4]> attribValue; 823 glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue); 824 attribValue.verifyValidity(m_testCtx); 825 826 if (attribValue[0] != 0.0f || attribValue[1] != 0.0f || attribValue[2] != 0.0f || attribValue[3] != 1.0f) 827 { 828 m_testCtx.getLog() << TestLog::Message 829 << "// ERROR: Expected [0, 0, 0, 1];" 830 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << "," << attribValue[3] << "]" 831 << TestLog::EndMessage; 832 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 833 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value"); 834 } 835 } 836 } 837 }; 838 839 class CurrentVertexAttribFloatCase : public ApiCase 840 { 841 public: 842 CurrentVertexAttribFloatCase (Context& context, const char* name, const char* description) 843 : ApiCase(context, name, description) 844 { 845 } 846 847 void test (void) 848 { 849 using tcu::TestLog; 850 851 de::Random rnd(0xabcdef); 852 853 int attribute_count = 16; 854 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count); 855 856 // test write float/read float 857 858 for (int index = 0; index < attribute_count; ++index) 859 { 860 const GLfloat x = rnd.getFloat(-64000, 64000); 861 const GLfloat y = rnd.getFloat(-64000, 64000); 862 const GLfloat z = rnd.getFloat(-64000, 64000); 863 const GLfloat w = rnd.getFloat(-64000, 64000); 864 865 glVertexAttrib4f(index, x, y, z, w); 866 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w); 867 } 868 for (int index = 0; index < attribute_count; ++index) 869 { 870 const GLfloat x = rnd.getFloat(-64000, 64000); 871 const GLfloat y = rnd.getFloat(-64000, 64000); 872 const GLfloat z = rnd.getFloat(-64000, 64000); 873 const GLfloat w = 1.0f; 874 875 glVertexAttrib3f(index, x, y, z); 876 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w); 877 } 878 for (int index = 0; index < attribute_count; ++index) 879 { 880 const GLfloat x = rnd.getFloat(-64000, 64000); 881 const GLfloat y = rnd.getFloat(-64000, 64000); 882 const GLfloat z = 0.0f; 883 const GLfloat w = 1.0f; 884 885 glVertexAttrib2f(index, x, y); 886 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w); 887 } 888 for (int index = 0; index < attribute_count; ++index) 889 { 890 const GLfloat x = rnd.getFloat(-64000, 64000); 891 const GLfloat y = 0.0f; 892 const GLfloat z = 0.0f; 893 const GLfloat w = 1.0f; 894 895 glVertexAttrib1f(index, x); 896 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w); 897 } 898 } 899 }; 900 901 class CurrentVertexAttribConversionCase : public ApiCase 902 { 903 public: 904 CurrentVertexAttribConversionCase (Context& context, const char* name, const char* description) 905 : ApiCase(context, name, description) 906 { 907 } 908 909 void test (void) 910 { 911 using tcu::TestLog; 912 913 de::Random rnd(0xabcdef); 914 915 int attribute_count = 16; 916 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count); 917 918 // test write float/read float 919 920 for (int index = 0; index < attribute_count; ++index) 921 { 922 const GLfloat x = rnd.getFloat(-64000, 64000); 923 const GLfloat y = rnd.getFloat(-64000, 64000); 924 const GLfloat z = rnd.getFloat(-64000, 64000); 925 const GLfloat w = rnd.getFloat(-64000, 64000); 926 927 glVertexAttrib4f(index, x, y, z, w); 928 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w); 929 } 930 for (int index = 0; index < attribute_count; ++index) 931 { 932 const GLfloat x = rnd.getFloat(-64000, 64000); 933 const GLfloat y = rnd.getFloat(-64000, 64000); 934 const GLfloat z = rnd.getFloat(-64000, 64000); 935 const GLfloat w = 1.0f; 936 937 glVertexAttrib3f(index, x, y, z); 938 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w); 939 } 940 for (int index = 0; index < attribute_count; ++index) 941 { 942 const GLfloat x = rnd.getFloat(-64000, 64000); 943 const GLfloat y = rnd.getFloat(-64000, 64000); 944 const GLfloat z = 0.0f; 945 const GLfloat w = 1.0f; 946 947 glVertexAttrib2f(index, x, y); 948 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w); 949 } 950 for (int index = 0; index < attribute_count; ++index) 951 { 952 const GLfloat x = rnd.getFloat(-64000, 64000); 953 const GLfloat y = 0.0f; 954 const GLfloat z = 0.0f; 955 const GLfloat w = 1.0f; 956 957 glVertexAttrib1f(index, x); 958 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w); 959 } 960 } 961 }; 962 963 class ProgramInfoLogCase : public ApiCase 964 { 965 public: 966 ProgramInfoLogCase (Context& context, const char* name, const char* description) 967 : ApiCase(context, name, description) 968 { 969 } 970 971 void test (void) 972 { 973 using tcu::TestLog; 974 975 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 976 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 977 978 glShaderSource(shaderVert, 1, &brokenShader, DE_NULL); 979 glShaderSource(shaderFrag, 1, &brokenShader, DE_NULL); 980 981 glCompileShader(shaderVert); 982 glCompileShader(shaderFrag); 983 expectError(GL_NO_ERROR); 984 985 GLuint program = glCreateProgram(); 986 glAttachShader(program, shaderVert); 987 glAttachShader(program, shaderFrag); 988 glLinkProgram(program); 989 990 // check INFO_LOG_LENGTH == GetProgramInfoLog len 991 { 992 char buffer[2048] = {'x'}; 993 994 GLint written = 0; 995 glGetProgramInfoLog(program, DE_LENGTH_OF_ARRAY(buffer), &written, buffer); 996 997 StateQueryMemoryWriteGuard<GLint> logLength; 998 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); 999 logLength.verifyValidity(m_testCtx); 1000 1001 if (logLength != 0 && written+1 != logLength) // INFO_LOG_LENGTH contains 0-terminator 1002 { 1003 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected INFO_LOG_LENGTH " << written+1 << "; got " << logLength << TestLog::EndMessage; 1004 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1005 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length"); 1006 } 1007 } 1008 1009 // check GetProgramInfoLog works with too small buffer 1010 { 1011 char buffer[2048] = {'x'}; 1012 1013 GLint written = 0; 1014 glGetProgramInfoLog(program, 1, &written, buffer); 1015 1016 if (written != 0) 1017 { 1018 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length 0; got " << written << TestLog::EndMessage; 1019 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1020 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length"); 1021 } 1022 } 1023 1024 glDeleteShader(shaderVert); 1025 glDeleteShader(shaderFrag); 1026 glDeleteProgram(program); 1027 expectError(GL_NO_ERROR); 1028 } 1029 }; 1030 1031 class ProgramValidateStatusCase : public ApiCase 1032 { 1033 public: 1034 ProgramValidateStatusCase (Context& context, const char* name, const char* description) 1035 : ApiCase(context, name, description) 1036 { 1037 } 1038 1039 void test (void) 1040 { 1041 // test validate ok 1042 { 1043 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1044 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1045 1046 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL); 1047 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL); 1048 1049 glCompileShader(shaderVert); 1050 glCompileShader(shaderFrag); 1051 expectError(GL_NO_ERROR); 1052 1053 GLuint program = glCreateProgram(); 1054 glAttachShader(program, shaderVert); 1055 glAttachShader(program, shaderFrag); 1056 glLinkProgram(program); 1057 expectError(GL_NO_ERROR); 1058 1059 verifyShaderParam (m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE); 1060 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE); 1061 verifyProgramParam (m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE); 1062 1063 glValidateProgram(program); 1064 verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_TRUE); 1065 1066 glDeleteShader(shaderVert); 1067 glDeleteShader(shaderFrag); 1068 glDeleteProgram(program); 1069 expectError(GL_NO_ERROR); 1070 } 1071 1072 // test with broken shader 1073 { 1074 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1075 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1076 1077 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL); 1078 glShaderSource(shaderFrag, 1, &brokenShader, DE_NULL); 1079 1080 glCompileShader(shaderVert); 1081 glCompileShader(shaderFrag); 1082 expectError(GL_NO_ERROR); 1083 1084 GLuint program = glCreateProgram(); 1085 glAttachShader(program, shaderVert); 1086 glAttachShader(program, shaderFrag); 1087 glLinkProgram(program); 1088 expectError(GL_NO_ERROR); 1089 1090 verifyShaderParam (m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE); 1091 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_FALSE); 1092 verifyProgramParam (m_testCtx, *this, program, GL_LINK_STATUS, GL_FALSE); 1093 1094 glValidateProgram(program); 1095 verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_FALSE); 1096 1097 glDeleteShader(shaderVert); 1098 glDeleteShader(shaderFrag); 1099 glDeleteProgram(program); 1100 expectError(GL_NO_ERROR); 1101 } 1102 } 1103 }; 1104 1105 class ProgramAttachedShadersCase : public ApiCase 1106 { 1107 public: 1108 ProgramAttachedShadersCase (Context& context, const char* name, const char* description) 1109 : ApiCase(context, name, description) 1110 { 1111 } 1112 1113 void test (void) 1114 { 1115 using tcu::TestLog; 1116 1117 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1118 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1119 1120 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL); 1121 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL); 1122 1123 glCompileShader(shaderVert); 1124 glCompileShader(shaderFrag); 1125 expectError(GL_NO_ERROR); 1126 1127 // check ATTACHED_SHADERS 1128 1129 GLuint program = glCreateProgram(); 1130 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 0); 1131 expectError(GL_NO_ERROR); 1132 1133 glAttachShader(program, shaderVert); 1134 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 1); 1135 expectError(GL_NO_ERROR); 1136 1137 glAttachShader(program, shaderFrag); 1138 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 2); 1139 expectError(GL_NO_ERROR); 1140 1141 // check GetAttachedShaders 1142 { 1143 GLuint shaders[2] = {0, 0}; 1144 GLint count = 0; 1145 glGetAttachedShaders(program, DE_LENGTH_OF_ARRAY(shaders), &count, shaders); 1146 1147 if (count != 2) 1148 { 1149 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 2; got " << count << TestLog::EndMessage; 1150 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1151 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count"); 1152 } 1153 // shaders are the attached shaders? 1154 if (!((shaders[0] == shaderVert && shaders[1] == shaderFrag) || 1155 (shaders[0] == shaderFrag && shaders[1] == shaderVert))) 1156 { 1157 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected {" << shaderVert << ", " << shaderFrag << "}; got {" << shaders[0] << ", " << shaders[1] << "}" << TestLog::EndMessage; 1158 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1159 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count"); 1160 } 1161 } 1162 1163 // check GetAttachedShaders with too small buffer 1164 { 1165 GLuint shaders[2] = {0, 0}; 1166 GLint count = 0; 1167 1168 glGetAttachedShaders(program, 0, &count, shaders); 1169 if (count != 0) 1170 { 1171 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0; got " << count << TestLog::EndMessage; 1172 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1173 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count"); 1174 } 1175 1176 count = 0; 1177 glGetAttachedShaders(program, 1, &count, shaders); 1178 if (count != 1) 1179 { 1180 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 1; got " << count << TestLog::EndMessage; 1181 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1182 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count"); 1183 } 1184 } 1185 1186 glDeleteShader(shaderVert); 1187 glDeleteShader(shaderFrag); 1188 glDeleteProgram(program); 1189 expectError(GL_NO_ERROR); 1190 } 1191 }; 1192 1193 class ProgramActiveUniformNameCase : public ApiCase 1194 { 1195 public: 1196 ProgramActiveUniformNameCase (Context& context, const char* name, const char* description) 1197 : ApiCase(context, name, description) 1198 { 1199 } 1200 1201 void test (void) 1202 { 1203 using tcu::TestLog; 1204 1205 static const char* testVertSource = 1206 "uniform highp float uniformNameWithLength23;\n" 1207 "uniform highp vec2 uniformVec2;\n" 1208 "uniform highp mat4 uniformMat4;\n" 1209 "void main (void)\n" 1210 "{\n" 1211 " gl_Position = vec4(0.0) + vec4(uniformNameWithLength23) + vec4(uniformVec2.x) + vec4(uniformMat4[2][3]);\n" 1212 "}\n\0"; 1213 static const char* testFragSource = 1214 1215 "void main (void)\n" 1216 "{\n" 1217 " gl_FragColor = vec4(0.0);\n" 1218 "}\n\0"; 1219 1220 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1221 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1222 1223 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); 1224 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); 1225 1226 glCompileShader(shaderVert); 1227 glCompileShader(shaderFrag); 1228 expectError(GL_NO_ERROR); 1229 1230 GLuint program = glCreateProgram(); 1231 glAttachShader(program, shaderVert); 1232 glAttachShader(program, shaderFrag); 1233 glLinkProgram(program); 1234 expectError(GL_NO_ERROR); 1235 1236 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORMS, 3); 1237 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, (GLint)std::string("uniformNameWithLength23").length() + 1); // including a null terminator 1238 expectError(GL_NO_ERROR); 1239 1240 const char* uniformNames[] = 1241 { 1242 "uniformNameWithLength23", 1243 "uniformVec2", 1244 "uniformMat4" 1245 }; 1246 1247 // check names 1248 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformNames); ++ndx) 1249 { 1250 char buffer[2048] = {'x'}; 1251 char* bufferEnd = (buffer + 1); 1252 1253 GLint written = 0; // null terminator not included 1254 GLint size = 0; 1255 GLenum type = 0; 1256 glGetActiveUniform(program, ndx, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer); 1257 1258 if (written < DE_LENGTH_OF_ARRAY(buffer)) 1259 bufferEnd = &buffer[written]; 1260 1261 // find matching uniform 1262 { 1263 const std::string uniformName(buffer, bufferEnd); 1264 bool found = false; 1265 1266 for (int uniformNdx = 0; uniformNdx < DE_LENGTH_OF_ARRAY(uniformNames); ++uniformNdx) 1267 { 1268 if (uniformName == uniformNames[uniformNdx]) 1269 { 1270 found = true; 1271 break; 1272 } 1273 } 1274 1275 if (!found) 1276 { 1277 m_testCtx.getLog() << TestLog::Message << "// ERROR: Got unknown uniform name: " << uniformName << TestLog::EndMessage; 1278 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1279 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name"); 1280 } 1281 } 1282 1283 // and with too small buffer 1284 written = 0; 1285 glGetActiveUniform(program, ndx, 1, &written, &size, &type, buffer); 1286 1287 if (written != 0) 1288 { 1289 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0 got " << written << TestLog::EndMessage; 1290 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1291 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name length"); 1292 } 1293 } 1294 1295 1296 glDeleteShader(shaderVert); 1297 glDeleteShader(shaderFrag); 1298 glDeleteProgram(program); 1299 expectError(GL_NO_ERROR); 1300 } 1301 }; 1302 1303 class ProgramUniformCase : public ApiCase 1304 { 1305 public: 1306 ProgramUniformCase (Context& context, const char* name, const char* description) 1307 : ApiCase(context, name, description) 1308 { 1309 } 1310 1311 void test (void) 1312 { 1313 const struct UniformType 1314 { 1315 const char* declaration; 1316 const char* postDeclaration; 1317 const char* precision; 1318 const char* layout; 1319 const char* getter; 1320 GLenum type; 1321 GLint size; 1322 GLint isRowMajor; 1323 } uniformTypes[] = 1324 { 1325 { "float", "", "highp", "", "uniformValue", GL_FLOAT, 1, GL_FALSE }, 1326 { "float", "[2]", "highp", "", "uniformValue[1]", GL_FLOAT, 2, GL_FALSE }, 1327 { "vec2", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC2, 1, GL_FALSE }, 1328 { "vec3", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC3, 1, GL_FALSE }, 1329 { "vec4", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC4, 1, GL_FALSE }, 1330 { "int", "", "highp", "", "float(uniformValue)", GL_INT, 1, GL_FALSE }, 1331 { "ivec2", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC2, 1, GL_FALSE }, 1332 { "ivec3", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC3, 1, GL_FALSE }, 1333 { "ivec4", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC4, 1, GL_FALSE }, 1334 { "bool", "", "", "", "float(uniformValue)", GL_BOOL, 1, GL_FALSE }, 1335 { "bvec2", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC2, 1, GL_FALSE }, 1336 { "bvec3", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC3, 1, GL_FALSE }, 1337 { "bvec4", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC4, 1, GL_FALSE }, 1338 { "mat2", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT2, 1, GL_FALSE }, 1339 { "mat3", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT3, 1, GL_FALSE }, 1340 { "mat4", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT4, 1, GL_FALSE }, 1341 { "sampler2D", "", "highp", "", "float(texture2D(uniformValue, vec2(0.0, 0.0)).r)", GL_SAMPLER_2D, 1, GL_FALSE }, 1342 { "samplerCube", "", "highp", "", "float(textureCube(uniformValue, vec3(0.0, 0.0, 0.0)).r)", GL_SAMPLER_CUBE, 1, GL_FALSE }, 1343 }; 1344 1345 static const char* vertSource = 1346 "void main (void)\n" 1347 "{\n" 1348 " gl_Position = vec4(0.0);\n" 1349 "}\n\0"; 1350 1351 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1352 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1353 GLuint program = glCreateProgram(); 1354 1355 glAttachShader(program, shaderVert); 1356 glAttachShader(program, shaderFrag); 1357 1358 glShaderSource(shaderVert, 1, &vertSource, DE_NULL); 1359 glCompileShader(shaderVert); 1360 expectError(GL_NO_ERROR); 1361 1362 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformTypes); ++ndx) 1363 { 1364 tcu::ScopedLogSection(m_log, uniformTypes[ndx].declaration, std::string("Verify type of ") + uniformTypes[ndx].declaration + " variable" + uniformTypes[ndx].postDeclaration ); 1365 1366 // gen fragment shader 1367 1368 std::ostringstream frag; 1369 frag << uniformTypes[ndx].layout << "uniform " << uniformTypes[ndx].precision << " " << uniformTypes[ndx].declaration << " uniformValue" << uniformTypes[ndx].postDeclaration << ";\n"; 1370 frag << "void main (void)\n"; 1371 frag << "{\n"; 1372 frag << " gl_FragColor = vec4(" << uniformTypes[ndx].getter << ");\n"; 1373 frag << "}\n"; 1374 1375 { 1376 std::string fragmentSource = frag.str(); 1377 const char* fragmentSourceCStr = fragmentSource.c_str(); 1378 glShaderSource(shaderFrag, 1, &fragmentSourceCStr, DE_NULL); 1379 } 1380 1381 // compile & link 1382 1383 glCompileShader(shaderFrag); 1384 glLinkProgram(program); 1385 1386 // test 1387 if (verifyProgramParam(m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE)) 1388 { 1389 const GLint index = 0; // first and only active uniform 1390 1391 char buffer[] = "not written to"; // not written to 1392 GLint written = 0; 1393 GLint size = 0; 1394 GLenum type = 0; 1395 glGetActiveUniform(program, index, 0, &written, &size, &type, buffer); 1396 1397 checkIntEquals(m_testCtx, type, uniformTypes[ndx].type); 1398 checkIntEquals(m_testCtx, size, uniformTypes[ndx].size); 1399 } 1400 } 1401 1402 glDeleteShader(shaderVert); 1403 glDeleteShader(shaderFrag); 1404 glDeleteProgram(program); 1405 expectError(GL_NO_ERROR); 1406 } 1407 }; 1408 1409 class ActiveAttributesCase : public ApiCase 1410 { 1411 public: 1412 ActiveAttributesCase (Context& context, const char* name, const char* description) 1413 : ApiCase(context, name, description) 1414 { 1415 } 1416 1417 void test (void) 1418 { 1419 using tcu::TestLog; 1420 1421 static const char* testVertSource = 1422 "attribute highp vec2 longInputAttributeName;\n" 1423 "attribute highp vec2 shortName;\n" 1424 "void main (void)\n" 1425 "{\n" 1426 " gl_Position = longInputAttributeName.yxxy + shortName.xyxy;\n" 1427 "}\n\0"; 1428 static const char* testFragSource = 1429 "void main (void)\n" 1430 "{\n" 1431 " gl_FragColor = vec4(0.0);\n" 1432 "}\n\0"; 1433 1434 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); 1435 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); 1436 1437 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); 1438 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); 1439 1440 glCompileShader(shaderVert); 1441 glCompileShader(shaderFrag); 1442 expectError(GL_NO_ERROR); 1443 1444 GLuint program = glCreateProgram(); 1445 glAttachShader(program, shaderVert); 1446 glAttachShader(program, shaderFrag); 1447 glLinkProgram(program); 1448 expectError(GL_NO_ERROR); 1449 1450 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTES, 2); 1451 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, (GLint)std::string("longInputAttributeName").length() + 1); // does include null-terminator 1452 1453 // check names 1454 for (int attributeNdx = 0; attributeNdx < 2; ++attributeNdx) 1455 { 1456 char buffer[2048] = {'x'}; 1457 1458 GLint written = 0; 1459 GLint size = 0; 1460 GLenum type = 0; 1461 glGetActiveAttrib(program, attributeNdx, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer); 1462 expectError(GL_NO_ERROR); 1463 1464 if (deStringBeginsWith(buffer, "longInputAttributeName")) 1465 { 1466 checkIntEquals(m_testCtx, written, (GLint)std::string("longInputAttributeName").length()); // does NOT include null-terminator 1467 } 1468 else if (deStringBeginsWith(buffer, "shortName")) 1469 { 1470 checkIntEquals(m_testCtx, written, (GLint)std::string("shortName").length()); // does NOT include null-terminator 1471 } 1472 else 1473 { 1474 m_testCtx.getLog() << TestLog::Message << "// ERROR: Got unexpected attribute name." << TestLog::EndMessage; 1475 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1476 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected name"); 1477 } 1478 } 1479 1480 // and with too short buffer 1481 { 1482 char buffer[2048] = {'x'}; 1483 1484 GLint written = 0; 1485 GLint size = 0; 1486 GLenum type = 0; 1487 1488 glGetActiveAttrib(program, 0, 1, &written, &size, &type, buffer); 1489 expectError(GL_NO_ERROR); 1490 checkIntEquals(m_testCtx, written, 0); 1491 } 1492 1493 glDeleteShader(shaderVert); 1494 glDeleteShader(shaderFrag); 1495 glDeleteProgram(program); 1496 expectError(GL_NO_ERROR); 1497 } 1498 }; 1499 1500 struct PointerData 1501 { 1502 GLint size; 1503 GLenum type; 1504 GLint stride; 1505 GLboolean normalized; 1506 void* pointer; 1507 }; 1508 1509 class VertexAttributeSizeCase : public ApiCase 1510 { 1511 public: 1512 VertexAttributeSizeCase (Context& context, const char* name, const char* description) 1513 : ApiCase(context, name, description) 1514 { 1515 } 1516 1517 void test (void) 1518 { 1519 GLfloat vertexData[4] = {0.0f}; // never accessed 1520 1521 // test VertexAttribPointer 1522 const PointerData pointers[] = 1523 { 1524 // size test 1525 { 4, GL_FLOAT, 0, GL_FALSE, vertexData }, 1526 { 3, GL_FLOAT, 0, GL_FALSE, vertexData }, 1527 { 2, GL_FLOAT, 0, GL_FALSE, vertexData }, 1528 { 1, GL_FLOAT, 0, GL_FALSE, vertexData }, 1529 { 4, GL_SHORT, 0, GL_FALSE, vertexData }, 1530 { 3, GL_SHORT, 0, GL_FALSE, vertexData }, 1531 { 2, GL_SHORT, 0, GL_FALSE, vertexData }, 1532 { 1, GL_SHORT, 0, GL_FALSE, vertexData }, 1533 }; 1534 1535 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 1536 { 1537 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer); 1538 expectError(GL_NO_ERROR); 1539 1540 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[ndx].size); 1541 } 1542 } 1543 }; 1544 1545 class VertexAttributeTypeCase : public ApiCase 1546 { 1547 public: 1548 VertexAttributeTypeCase (Context& context, const char* name, const char* description) 1549 : ApiCase(context, name, description) 1550 { 1551 } 1552 1553 void test (void) 1554 { 1555 GLfloat vertexData[4] = {0.0f}; // never accessed 1556 1557 const PointerData pointers[] = 1558 { 1559 { 1, GL_BYTE, 0, GL_FALSE, vertexData }, 1560 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData }, 1561 { 1, GL_SHORT, 0, GL_FALSE, vertexData }, 1562 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData }, 1563 { 1, GL_FIXED, 0, GL_FALSE, vertexData }, 1564 { 1, GL_FLOAT, 0, GL_FALSE, vertexData }, 1565 }; 1566 1567 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 1568 { 1569 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer); 1570 expectError(GL_NO_ERROR); 1571 1572 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, pointers[ndx].type); 1573 } 1574 } 1575 }; 1576 1577 class VertexAttributeStrideCase : public ApiCase 1578 { 1579 public: 1580 VertexAttributeStrideCase (Context& context, const char* name, const char* description) 1581 : ApiCase(context, name, description) 1582 { 1583 } 1584 1585 void test (void) 1586 { 1587 GLfloat vertexData[4] = {0.0f}; // never accessed 1588 1589 struct StridePointerData 1590 { 1591 GLint size; 1592 GLenum type; 1593 GLint stride; 1594 void* pointer; 1595 }; 1596 1597 // test VertexAttribPointer 1598 { 1599 const StridePointerData pointers[] = 1600 { 1601 { 1, GL_FLOAT, 0, vertexData }, 1602 { 1, GL_FLOAT, 1, vertexData }, 1603 { 1, GL_FLOAT, 4, vertexData }, 1604 { 1, GL_SHORT, 0, vertexData }, 1605 { 1, GL_SHORT, 1, vertexData }, 1606 { 1, GL_SHORT, 4, vertexData }, 1607 { 1, GL_FIXED, 0, vertexData }, 1608 { 1, GL_FIXED, 1, vertexData }, 1609 { 1, GL_FIXED, 4, vertexData }, 1610 { 1, GL_BYTE, 0, vertexData }, 1611 { 1, GL_UNSIGNED_SHORT, 1, vertexData }, 1612 { 1, GL_UNSIGNED_SHORT, 4, vertexData }, 1613 { 4, GL_UNSIGNED_BYTE, 0, vertexData }, 1614 { 4, GL_UNSIGNED_BYTE, 1, vertexData }, 1615 { 4, GL_UNSIGNED_BYTE, 4, vertexData }, 1616 }; 1617 1618 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 1619 { 1620 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, GL_FALSE, pointers[ndx].stride, pointers[ndx].pointer); 1621 expectError(GL_NO_ERROR); 1622 1623 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, pointers[ndx].stride); 1624 } 1625 } 1626 } 1627 }; 1628 1629 class VertexAttributeNormalizedCase : public ApiCase 1630 { 1631 public: 1632 VertexAttributeNormalizedCase (Context& context, const char* name, const char* description) 1633 : ApiCase(context, name, description) 1634 { 1635 } 1636 1637 void test (void) 1638 { 1639 GLfloat vertexData[4] = {0.0f}; // never accessed 1640 1641 // test VertexAttribPointer 1642 { 1643 const PointerData pointers[] = 1644 { 1645 { 1, GL_BYTE, 0, GL_FALSE, vertexData }, 1646 { 1, GL_SHORT, 0, GL_FALSE, vertexData }, 1647 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData }, 1648 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData }, 1649 { 1, GL_BYTE, 0, GL_TRUE, vertexData }, 1650 { 1, GL_SHORT, 0, GL_TRUE, vertexData }, 1651 { 1, GL_UNSIGNED_BYTE, 0, GL_TRUE, vertexData }, 1652 { 1, GL_UNSIGNED_SHORT, 0, GL_TRUE, vertexData }, 1653 }; 1654 1655 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 1656 { 1657 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer); 1658 expectError(GL_NO_ERROR); 1659 1660 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, pointers[ndx].normalized); 1661 } 1662 } 1663 } 1664 }; 1665 1666 class VertexAttributeEnabledCase : public ApiCase 1667 { 1668 public: 1669 VertexAttributeEnabledCase (Context& context, const char* name, const char* description) 1670 : ApiCase(context, name, description) 1671 { 1672 } 1673 1674 void test (void) 1675 { 1676 // VERTEX_ATTRIB_ARRAY_ENABLED 1677 1678 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE); 1679 glEnableVertexAttribArray(0); 1680 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_TRUE); 1681 glDisableVertexAttribArray(0); 1682 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE); 1683 } 1684 }; 1685 1686 class VertexAttributeBufferBindingCase : public ApiCase 1687 { 1688 public: 1689 VertexAttributeBufferBindingCase (Context& context, const char* name, const char* description) 1690 : ApiCase(context, name, description) 1691 { 1692 } 1693 1694 void test (void) 1695 { 1696 // initial 1697 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, 0); 1698 1699 GLuint bufferID; 1700 glGenBuffers(1, &bufferID); 1701 glBindBuffer(GL_ARRAY_BUFFER, bufferID); 1702 expectError(GL_NO_ERROR); 1703 1704 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL); 1705 expectError(GL_NO_ERROR); 1706 1707 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufferID); 1708 1709 glDeleteBuffers(1, &bufferID); 1710 expectError(GL_NO_ERROR); 1711 } 1712 }; 1713 1714 class VertexAttributePointerCase : public ApiCase 1715 { 1716 public: 1717 VertexAttributePointerCase (Context& context, const char* name, const char* description) 1718 : ApiCase(context, name, description) 1719 { 1720 } 1721 1722 void test (void) 1723 { 1724 StateQueryMemoryWriteGuard<GLvoid*> initialState; 1725 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &initialState); 1726 initialState.verifyValidity(m_testCtx); 1727 checkPointerEquals(m_testCtx, initialState, 0); 1728 1729 GLfloat vertexData[4] = {0.0f}; // never accessed 1730 const PointerData pointers[] = 1731 { 1732 { 1, GL_BYTE, 0, GL_FALSE, &vertexData[2] }, 1733 { 1, GL_SHORT, 0, GL_FALSE, &vertexData[1] }, 1734 { 1, GL_FIXED, 0, GL_FALSE, &vertexData[2] }, 1735 { 1, GL_FIXED, 0, GL_FALSE, &vertexData[1] }, 1736 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[0] }, 1737 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[3] }, 1738 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[2] }, 1739 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, &vertexData[0] }, 1740 { 4, GL_UNSIGNED_SHORT, 0, GL_FALSE, &vertexData[1] }, 1741 { 4, GL_UNSIGNED_SHORT, 0, GL_FALSE, &vertexData[2] }, 1742 }; 1743 1744 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx) 1745 { 1746 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer); 1747 expectError(GL_NO_ERROR); 1748 1749 StateQueryMemoryWriteGuard<GLvoid*> state; 1750 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state); 1751 state.verifyValidity(m_testCtx); 1752 checkPointerEquals(m_testCtx, state, pointers[ndx].pointer); 1753 } 1754 } 1755 }; 1756 1757 class UniformValueFloatCase : public ApiCase 1758 { 1759 public: 1760 UniformValueFloatCase (Context& context, const char* name, const char* description) 1761 : ApiCase(context, name, description) 1762 { 1763 } 1764 1765 void test (void) 1766 { 1767 static const char* testVertSource = 1768 "uniform highp float floatUniform;\n" 1769 "uniform highp vec2 float2Uniform;\n" 1770 "uniform highp vec3 float3Uniform;\n" 1771 "uniform highp vec4 float4Uniform;\n" 1772 "void main (void)\n" 1773 "{\n" 1774 " gl_Position = vec4(floatUniform + float2Uniform.x + float3Uniform.x + float4Uniform.x);\n" 1775 "}\n"; 1776 static const char* testFragSource = 1777 1778 "void main (void)\n" 1779 "{\n" 1780 " gl_FragColor = vec4(0.0);\n" 1781 "}\n"; 1782 1783 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource)); 1784 if (!program.isOk()) 1785 { 1786 m_log << program; 1787 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader"); 1788 return; 1789 } 1790 1791 glUseProgram(program.getProgram()); 1792 expectError(GL_NO_ERROR); 1793 1794 GLint location; 1795 1796 location = glGetUniformLocation(program.getProgram(), "floatUniform"); 1797 glUniform1f(location, 1.0f); 1798 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), location, 1.0f); 1799 1800 location = glGetUniformLocation(program.getProgram(), "float2Uniform"); 1801 glUniform2f(location, 1.0f, 2.0f); 1802 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), location, 1.0f, 2.0f); 1803 1804 location = glGetUniformLocation(program.getProgram(), "float3Uniform"); 1805 glUniform3f(location, 1.0f, 2.0f, 3.0f); 1806 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), location, 1.0f, 2.0f, 3.0f); 1807 1808 location = glGetUniformLocation(program.getProgram(), "float4Uniform"); 1809 glUniform4f(location, 1.0f, 2.0f, 3.0f, 4.0f); 1810 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), location, 1.0f, 2.0f, 3.0f, 4.0f); 1811 1812 glUseProgram(0); 1813 expectError(GL_NO_ERROR); 1814 } 1815 }; 1816 1817 class UniformValueIntCase : public ApiCase 1818 { 1819 public: 1820 UniformValueIntCase (Context& context, const char* name, const char* description) 1821 : ApiCase(context, name, description) 1822 { 1823 } 1824 1825 void test (void) 1826 { 1827 static const char* testVertSource = 1828 "uniform highp int intUniform;\n" 1829 "uniform highp ivec2 int2Uniform;\n" 1830 "uniform highp ivec3 int3Uniform;\n" 1831 "uniform highp ivec4 int4Uniform;\n" 1832 "void main (void)\n" 1833 "{\n" 1834 " gl_Position = vec4(float(intUniform + int2Uniform.x + int3Uniform.x + int4Uniform.x));\n" 1835 "}\n"; 1836 static const char* testFragSource = 1837 "void main (void)\n" 1838 "{\n" 1839 " gl_FragColor = vec4(0.0);\n" 1840 "}\n"; 1841 1842 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource)); 1843 if (!program.isOk()) 1844 { 1845 m_log << program; 1846 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader"); 1847 return; 1848 } 1849 1850 glUseProgram(program.getProgram()); 1851 expectError(GL_NO_ERROR); 1852 1853 GLint location; 1854 1855 location = glGetUniformLocation(program.getProgram(), "intUniform"); 1856 glUniform1i(location, 1); 1857 verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1); 1858 1859 location = glGetUniformLocation(program.getProgram(), "int2Uniform"); 1860 glUniform2i(location, 1, 2); 1861 verifyUniformValue2i(m_testCtx, *this, program.getProgram(), location, 1, 2); 1862 1863 location = glGetUniformLocation(program.getProgram(), "int3Uniform"); 1864 glUniform3i(location, 1, 2, 3); 1865 verifyUniformValue3i(m_testCtx, *this, program.getProgram(), location, 1, 2, 3); 1866 1867 location = glGetUniformLocation(program.getProgram(), "int4Uniform"); 1868 glUniform4i(location, 1, 2, 3, 4); 1869 verifyUniformValue4i(m_testCtx, *this, program.getProgram(), location, 1, 2, 3, 4); 1870 1871 glUseProgram(0); 1872 expectError(GL_NO_ERROR); 1873 } 1874 }; 1875 1876 class UniformValueBooleanCase : public ApiCase 1877 { 1878 public: 1879 UniformValueBooleanCase (Context& context, const char* name, const char* description) 1880 : ApiCase(context, name, description) 1881 { 1882 } 1883 1884 void test (void) 1885 { 1886 static const char* testVertSource = 1887 "uniform bool boolUniform;\n" 1888 "uniform bvec2 bool2Uniform;\n" 1889 "uniform bvec3 bool3Uniform;\n" 1890 "uniform bvec4 bool4Uniform;\n" 1891 "void main (void)\n" 1892 "{\n" 1893 " gl_Position = vec4(float(boolUniform) + float(bool2Uniform.x) + float(bool3Uniform.x) + float(bool4Uniform.x));\n" 1894 "}\n"; 1895 static const char* testFragSource = 1896 "void main (void)\n" 1897 "{\n" 1898 " gl_FragColor = vec4(0.0);\n" 1899 "}\n"; 1900 1901 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource)); 1902 if (!program.isOk()) 1903 { 1904 m_log << program; 1905 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader"); 1906 return; 1907 } 1908 1909 glUseProgram(program.getProgram()); 1910 expectError(GL_NO_ERROR); 1911 1912 GLint location; 1913 1914 // int conversion 1915 1916 location = glGetUniformLocation(program.getProgram(), "boolUniform"); 1917 glUniform1i(location, 1); 1918 verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1); 1919 1920 location = glGetUniformLocation(program.getProgram(), "bool2Uniform"); 1921 glUniform2i(location, 1, 2); 1922 verifyUniformValue2i(m_testCtx, *this, program.getProgram(), location, 1, 1); 1923 1924 location = glGetUniformLocation(program.getProgram(), "bool3Uniform"); 1925 glUniform3i(location, 0, 1, 2); 1926 verifyUniformValue3i(m_testCtx, *this, program.getProgram(), location, 0, 1, 1); 1927 1928 location = glGetUniformLocation(program.getProgram(), "bool4Uniform"); 1929 glUniform4i(location, 1, 0, 1, -1); 1930 verifyUniformValue4i(m_testCtx, *this, program.getProgram(), location, 1, 0, 1, 1); 1931 1932 // float conversion 1933 1934 location = glGetUniformLocation(program.getProgram(), "boolUniform"); 1935 glUniform1f(location, 1.0f); 1936 verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1); 1937 1938 location = glGetUniformLocation(program.getProgram(), "bool2Uniform"); 1939 glUniform2f(location, 1.0f, 0.1f); 1940 verifyUniformValue2i(m_testCtx, *this, program.getProgram(), location, 1, 1); 1941 1942 location = glGetUniformLocation(program.getProgram(), "bool3Uniform"); 1943 glUniform3f(location, 0.0f, 0.1f, -0.1f); 1944 verifyUniformValue3i(m_testCtx, *this, program.getProgram(), location, 0, 1, 1); 1945 1946 location = glGetUniformLocation(program.getProgram(), "bool4Uniform"); 1947 glUniform4f(location, 1.0f, 0.0f, 0.1f, -0.9f); 1948 verifyUniformValue4i(m_testCtx, *this, program.getProgram(), location, 1, 0, 1, 1); 1949 1950 glUseProgram(0); 1951 expectError(GL_NO_ERROR); 1952 } 1953 }; 1954 1955 class UniformValueSamplerCase : public ApiCase 1956 { 1957 public: 1958 UniformValueSamplerCase (Context& context, const char* name, const char* description) 1959 : ApiCase(context, name, description) 1960 { 1961 } 1962 1963 void test (void) 1964 { 1965 static const char* testVertSource = 1966 "void main (void)\n" 1967 "{\n" 1968 " gl_Position = vec4(0.0);\n" 1969 "}\n"; 1970 static const char* testFragSource = 1971 "uniform highp sampler2D uniformSampler;\n" 1972 1973 "void main (void)\n" 1974 "{\n" 1975 " gl_FragColor = vec4(texture2D(uniformSampler, vec2(0.0, 0.0)).x);\n" 1976 "}\n"; 1977 1978 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource)); 1979 if (!program.isOk()) 1980 { 1981 m_log << program; 1982 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader"); 1983 return; 1984 } 1985 1986 glUseProgram(program.getProgram()); 1987 expectError(GL_NO_ERROR); 1988 1989 GLint location; 1990 1991 location = glGetUniformLocation(program.getProgram(), "uniformSampler"); 1992 glUniform1i(location, 1); 1993 verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1); 1994 1995 glUseProgram(0); 1996 expectError(GL_NO_ERROR); 1997 } 1998 }; 1999 2000 class UniformValueArrayCase : public ApiCase 2001 { 2002 public: 2003 UniformValueArrayCase (Context& context, const char* name, const char* description) 2004 : ApiCase(context, name, description) 2005 { 2006 } 2007 2008 void test (void) 2009 { 2010 static const char* testVertSource = 2011 "uniform highp float arrayUniform[5];" 2012 "uniform highp vec2 array2Uniform[5];" 2013 "uniform highp vec3 array3Uniform[5];" 2014 "uniform highp vec4 array4Uniform[5];" 2015 "void main (void)\n" 2016 "{\n" 2017 " gl_Position = \n" 2018 " + vec4(arrayUniform[0] + arrayUniform[1] + arrayUniform[2] + arrayUniform[3] + arrayUniform[4])\n" 2019 " + vec4(array2Uniform[0].x + array2Uniform[1].x + array2Uniform[2].x + array2Uniform[3].x + array2Uniform[4].x)\n" 2020 " + vec4(array3Uniform[0].x + array3Uniform[1].x + array3Uniform[2].x + array3Uniform[3].x + array3Uniform[4].x)\n" 2021 " + vec4(array4Uniform[0].x + array4Uniform[1].x + array4Uniform[2].x + array4Uniform[3].x + array4Uniform[4].x);\n" 2022 "}\n"; 2023 static const char* testFragSource = 2024 2025 "void main (void)\n" 2026 "{\n" 2027 " gl_FragColor = vec4(0.0);\n" 2028 "}\n"; 2029 2030 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource)); 2031 if (!program.isOk()) 2032 { 2033 m_log << program; 2034 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader"); 2035 return; 2036 } 2037 2038 glUseProgram(program.getProgram()); 2039 expectError(GL_NO_ERROR); 2040 2041 GLint location; 2042 2043 float uniformValue[5 * 4] = 2044 { 2045 -1.0f, 0.1f, 4.0f, 800.0f, 2046 13.0f, 55.0f, 12.0f, 91.0f, 2047 -55.1f, 1.1f, 98.0f, 19.0f, 2048 41.0f, 65.0f, 4.0f, 12.2f, 2049 95.0f, 77.0f, 32.0f, 48.0f 2050 }; 2051 2052 location = glGetUniformLocation(program.getProgram(), "arrayUniform"); 2053 glUniform1fv(location, 5, uniformValue); 2054 expectError(GL_NO_ERROR); 2055 2056 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[0]"), uniformValue[0]); 2057 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[1]"), uniformValue[1]); 2058 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[2]"), uniformValue[2]); 2059 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[3]"), uniformValue[3]); 2060 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[4]"), uniformValue[4]); 2061 expectError(GL_NO_ERROR); 2062 2063 location = glGetUniformLocation(program.getProgram(),"array2Uniform"); 2064 glUniform2fv(location, 5, uniformValue); 2065 expectError(GL_NO_ERROR); 2066 2067 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[0]"), uniformValue[2 * 0], uniformValue[(2 * 0) + 1]); 2068 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[1]"), uniformValue[2 * 1], uniformValue[(2 * 1) + 1]); 2069 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[2]"), uniformValue[2 * 2], uniformValue[(2 * 2) + 1]); 2070 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[3]"), uniformValue[2 * 3], uniformValue[(2 * 3) + 1]); 2071 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[4]"), uniformValue[2 * 4], uniformValue[(2 * 4) + 1]); 2072 expectError(GL_NO_ERROR); 2073 2074 location = glGetUniformLocation(program.getProgram(),"array3Uniform"); 2075 glUniform3fv(location, 5, uniformValue); 2076 expectError(GL_NO_ERROR); 2077 2078 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[0]"), uniformValue[3 * 0], uniformValue[(3 * 0) + 1], uniformValue[(3 * 0) + 2]); 2079 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[1]"), uniformValue[3 * 1], uniformValue[(3 * 1) + 1], uniformValue[(3 * 1) + 2]); 2080 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[2]"), uniformValue[3 * 2], uniformValue[(3 * 2) + 1], uniformValue[(3 * 2) + 2]); 2081 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[3]"), uniformValue[3 * 3], uniformValue[(3 * 3) + 1], uniformValue[(3 * 3) + 2]); 2082 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[4]"), uniformValue[3 * 4], uniformValue[(3 * 4) + 1], uniformValue[(3 * 4) + 2]); 2083 expectError(GL_NO_ERROR); 2084 2085 location = glGetUniformLocation(program.getProgram(),"array4Uniform"); 2086 glUniform4fv(location, 5, uniformValue); 2087 expectError(GL_NO_ERROR); 2088 2089 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[0]"), uniformValue[4 * 0], uniformValue[(4 * 0) + 1], uniformValue[(4 * 0) + 2], uniformValue[(4 * 0) + 3]); 2090 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[1]"), uniformValue[4 * 1], uniformValue[(4 * 1) + 1], uniformValue[(4 * 1) + 2], uniformValue[(4 * 1) + 3]); 2091 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[2]"), uniformValue[4 * 2], uniformValue[(4 * 2) + 1], uniformValue[(4 * 2) + 2], uniformValue[(4 * 2) + 3]); 2092 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[3]"), uniformValue[4 * 3], uniformValue[(4 * 3) + 1], uniformValue[(4 * 3) + 2], uniformValue[(4 * 3) + 3]); 2093 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[4]"), uniformValue[4 * 4], uniformValue[(4 * 4) + 1], uniformValue[(4 * 4) + 2], uniformValue[(4 * 4) + 3]); 2094 expectError(GL_NO_ERROR); 2095 2096 glUseProgram(0); 2097 expectError(GL_NO_ERROR); 2098 } 2099 }; 2100 2101 class UniformValueMatrixCase : public ApiCase 2102 { 2103 public: 2104 UniformValueMatrixCase (Context& context, const char* name, const char* description) 2105 : ApiCase(context, name, description) 2106 { 2107 } 2108 2109 void test (void) 2110 { 2111 static const char* testVertSource = 2112 "uniform highp mat2 mat2Uniform;" 2113 "uniform highp mat3 mat3Uniform;" 2114 "uniform highp mat4 mat4Uniform;" 2115 "void main (void)\n" 2116 "{\n" 2117 " gl_Position = vec4(mat2Uniform[0][0] + mat3Uniform[0][0] + mat4Uniform[0][0]);\n" 2118 "}\n"; 2119 static const char* testFragSource = 2120 2121 "void main (void)\n" 2122 "{\n" 2123 " gl_FragColor = vec4(0.0);\n" 2124 "}\n"; 2125 2126 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource)); 2127 if (!program.isOk()) 2128 { 2129 m_log << program; 2130 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader"); 2131 return; 2132 } 2133 2134 glUseProgram(program.getProgram()); 2135 expectError(GL_NO_ERROR); 2136 2137 GLint location; 2138 2139 float matrixValues[4 * 4] = 2140 { 2141 -1.0f, 0.1f, 4.0f, 800.0f, 2142 13.0f, 55.0f, 12.0f, 91.0f, 2143 -55.1f, 1.1f, 98.0f, 19.0f, 2144 41.0f, 65.0f, 4.0f, 12.2f, 2145 }; 2146 2147 // the values of the matrix are returned in column major order but they can be given in either order 2148 2149 location = glGetUniformLocation(program.getProgram(), "mat2Uniform"); 2150 glUniformMatrix2fv(location, 1, GL_FALSE, matrixValues); 2151 verifyUniformMatrixValues<2>(m_testCtx, *this, program.getProgram(), location, matrixValues, false); 2152 2153 location = glGetUniformLocation(program.getProgram(), "mat3Uniform"); 2154 glUniformMatrix3fv(location, 1, GL_FALSE, matrixValues); 2155 verifyUniformMatrixValues<3>(m_testCtx, *this, program.getProgram(), location, matrixValues, false); 2156 2157 location = glGetUniformLocation(program.getProgram(), "mat4Uniform"); 2158 glUniformMatrix4fv(location, 1, GL_FALSE, matrixValues); 2159 verifyUniformMatrixValues<4>(m_testCtx, *this, program.getProgram(), location, matrixValues, false); 2160 2161 glUseProgram(0); 2162 expectError(GL_NO_ERROR); 2163 } 2164 }; 2165 2166 class PrecisionFormatCase : public ApiCase 2167 { 2168 public: 2169 struct RequiredFormat 2170 { 2171 int negativeRange; 2172 int positiveRange; 2173 int precision; 2174 }; 2175 2176 PrecisionFormatCase (Context& context, const char* name, const char* description, glw::GLenum shaderType, glw::GLenum precisionType) 2177 : ApiCase (context, name, description) 2178 , m_shaderType (shaderType) 2179 , m_precisionType (precisionType) 2180 { 2181 } 2182 2183 private: 2184 void test (void) 2185 { 2186 const RequiredFormat expected = getRequiredFormat(); 2187 bool error = false; 2188 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLboolean> shaderCompiler; 2189 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint[2]> range; 2190 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint> precision; 2191 2192 // requires SHADER_COMPILER = true 2193 glGetBooleanv(GL_SHADER_COMPILER, &shaderCompiler); 2194 expectError(GL_NO_ERROR); 2195 2196 if (!shaderCompiler.verifyValidity(m_testCtx)) 2197 return; 2198 if (shaderCompiler != GL_TRUE) 2199 throw tcu::NotSupportedError("SHADER_COMPILER = TRUE required"); 2200 2201 // query values 2202 glGetShaderPrecisionFormat(m_shaderType, m_precisionType, range, &precision); 2203 expectError(GL_NO_ERROR); 2204 2205 if (!range.verifyValidity(m_testCtx)) 2206 return; 2207 if (!precision.verifyValidity(m_testCtx)) 2208 return; 2209 2210 m_log 2211 << tcu::TestLog::Message 2212 << "range[0] = " << range[0] << "\n" 2213 << "range[1] = " << range[1] << "\n" 2214 << "precision = " << precision 2215 << tcu::TestLog::EndMessage; 2216 2217 // special case for highp and fragment shader 2218 2219 if (m_shaderType == GL_FRAGMENT_SHADER && (m_precisionType == GL_HIGH_FLOAT || m_precisionType == GL_HIGH_INT)) 2220 { 2221 // not supported is a valid return value 2222 if (range[0] == 0 && range[1] == 0 && precision == 0) 2223 return; 2224 } 2225 2226 // verify the returned values 2227 2228 if (range[0] < expected.negativeRange) 2229 { 2230 m_log << tcu::TestLog::Message << "// ERROR: Invalid range[0], expected greater or equal to " << expected.negativeRange << tcu::TestLog::EndMessage; 2231 error = true; 2232 } 2233 2234 if (range[1] < expected.positiveRange) 2235 { 2236 m_log << tcu::TestLog::Message << "// ERROR: Invalid range[1], expected greater or equal to " << expected.positiveRange << tcu::TestLog::EndMessage; 2237 error = true; 2238 } 2239 2240 if (precision < expected.precision) 2241 { 2242 m_log << tcu::TestLog::Message << "// ERROR: Invalid precision, expected greater or equal to " << expected.precision << tcu::TestLog::EndMessage; 2243 error = true; 2244 } 2245 2246 if (error) 2247 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid precision/range"); 2248 } 2249 2250 RequiredFormat getRequiredFormat (void) const 2251 { 2252 // Precisions for different types. 2253 // For example highp float: range: (-2^62, 2^62) => min = -2^62 + e, max = 2^62 - e 2254 const RequiredFormat requirements[] = 2255 { 2256 { 0, 0, 8 }, //!< lowp float 2257 { 13, 13, 10 }, //!< mediump float 2258 { 61, 61, 16 }, //!< highp float 2259 { 7, 7, 0 }, //!< lowp int 2260 { 9, 9, 0 }, //!< mediump int 2261 { 15, 15, 0 }, //!< highp int 2262 }; 2263 const int ndx = (int)m_precisionType - (int)GL_LOW_FLOAT; 2264 2265 DE_ASSERT(ndx >= 0); 2266 DE_ASSERT(ndx < DE_LENGTH_OF_ARRAY(requirements)); 2267 return requirements[ndx]; 2268 } 2269 2270 const glw::GLenum m_shaderType; 2271 const glw::GLenum m_precisionType; 2272 }; 2273 2274 } // anonymous 2275 2276 2277 ShaderStateQueryTests::ShaderStateQueryTests (Context& context) 2278 : TestCaseGroup(context, "shader", "Shader State Query tests") 2279 { 2280 } 2281 2282 void ShaderStateQueryTests::init (void) 2283 { 2284 // shader 2285 addChild(new ShaderTypeCase (m_context, "shader_type", "SHADER_TYPE")); 2286 addChild(new ShaderCompileStatusCase (m_context, "shader_compile_status", "COMPILE_STATUS")); 2287 addChild(new ShaderInfoLogCase (m_context, "shader_info_log_length", "INFO_LOG_LENGTH")); 2288 addChild(new ShaderSourceCase (m_context, "shader_source_length", "SHADER_SOURCE_LENGTH")); 2289 2290 // shader and program 2291 addChild(new DeleteStatusCase (m_context, "delete_status", "DELETE_STATUS")); 2292 2293 // vertex-attrib 2294 addChild(new CurrentVertexAttribInitialCase (m_context, "current_vertex_attrib_initial", "CURRENT_VERTEX_ATTRIB")); 2295 addChild(new CurrentVertexAttribFloatCase (m_context, "current_vertex_attrib_float", "CURRENT_VERTEX_ATTRIB")); 2296 addChild(new CurrentVertexAttribConversionCase (m_context, "current_vertex_attrib_float_to_int", "CURRENT_VERTEX_ATTRIB")); 2297 2298 // program 2299 addChild(new ProgramInfoLogCase (m_context, "program_info_log_length", "INFO_LOG_LENGTH")); 2300 addChild(new ProgramValidateStatusCase (m_context, "program_validate_status", "VALIDATE_STATUS")); 2301 addChild(new ProgramAttachedShadersCase (m_context, "program_attached_shaders", "ATTACHED_SHADERS")); 2302 2303 addChild(new ProgramActiveUniformNameCase (m_context, "program_active_uniform_name", "ACTIVE_UNIFORMS and ACTIVE_UNIFORM_MAX_LENGTH")); 2304 addChild(new ProgramUniformCase (m_context, "program_active_uniform_types", "UNIFORM_TYPE and UNIFORM_SIZE")); 2305 2306 // attribute related 2307 addChild(new ActiveAttributesCase (m_context, "active_attributes", "ACTIVE_ATTRIBUTES and ACTIVE_ATTRIBUTE_MAX_LENGTH")); 2308 addChild(new VertexAttributeSizeCase (m_context, "vertex_attrib_size", "VERTEX_ATTRIB_ARRAY_SIZE")); 2309 addChild(new VertexAttributeTypeCase (m_context, "vertex_attrib_type", "VERTEX_ATTRIB_ARRAY_TYPE")); 2310 addChild(new VertexAttributeStrideCase (m_context, "vertex_attrib_stride", "VERTEX_ATTRIB_ARRAY_STRIDE")); 2311 addChild(new VertexAttributeNormalizedCase (m_context, "vertex_attrib_normalized", "VERTEX_ATTRIB_ARRAY_NORMALIZED")); 2312 addChild(new VertexAttributeEnabledCase (m_context, "vertex_attrib_array_enabled", "VERTEX_ATTRIB_ARRAY_ENABLED")); 2313 addChild(new VertexAttributeBufferBindingCase (m_context, "vertex_attrib_array_buffer_binding", "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING")); 2314 addChild(new VertexAttributePointerCase (m_context, "vertex_attrib_pointerv", "GetVertexAttribPointerv")); 2315 2316 // uniform values 2317 addChild(new UniformValueFloatCase (m_context, "uniform_value_float", "GetUniform*")); 2318 addChild(new UniformValueIntCase (m_context, "uniform_value_int", "GetUniform*")); 2319 addChild(new UniformValueBooleanCase (m_context, "uniform_value_boolean", "GetUniform*")); 2320 addChild(new UniformValueSamplerCase (m_context, "uniform_value_sampler", "GetUniform*")); 2321 addChild(new UniformValueArrayCase (m_context, "uniform_value_array", "GetUniform*")); 2322 addChild(new UniformValueMatrixCase (m_context, "uniform_value_matrix", "GetUniform*")); 2323 2324 // precision format query 2325 addChild(new PrecisionFormatCase (m_context, "precision_vertex_lowp_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_LOW_FLOAT)); 2326 addChild(new PrecisionFormatCase (m_context, "precision_vertex_mediump_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_MEDIUM_FLOAT)); 2327 addChild(new PrecisionFormatCase (m_context, "precision_vertex_highp_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_HIGH_FLOAT)); 2328 addChild(new PrecisionFormatCase (m_context, "precision_vertex_lowp_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_LOW_INT)); 2329 addChild(new PrecisionFormatCase (m_context, "precision_vertex_mediump_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_MEDIUM_INT)); 2330 addChild(new PrecisionFormatCase (m_context, "precision_vertex_highp_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_HIGH_INT)); 2331 addChild(new PrecisionFormatCase (m_context, "precision_fragment_lowp_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_LOW_FLOAT)); 2332 addChild(new PrecisionFormatCase (m_context, "precision_fragment_mediump_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT)); 2333 addChild(new PrecisionFormatCase (m_context, "precision_fragment_highp_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_HIGH_FLOAT)); 2334 addChild(new PrecisionFormatCase (m_context, "precision_fragment_lowp_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_LOW_INT)); 2335 addChild(new PrecisionFormatCase (m_context, "precision_fragment_mediump_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_MEDIUM_INT)); 2336 addChild(new PrecisionFormatCase (m_context, "precision_fragment_highp_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_HIGH_INT)); 2337 } 2338 2339 } // Functional 2340 } // gles2 2341 } // deqp 2342