Home | History | Annotate | Download | only in functional
      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 	enum BuildErrorType
   1193 	{
   1194 		BUILDERROR_COMPILE = 0,
   1195 		BUILDERROR_LINK
   1196 	};
   1197 
   1198 	ProgramInfoLogCase (Context& context, const char* name, const char* description, BuildErrorType buildErrorType)
   1199 		: ApiCase			(context, name, description)
   1200 		, m_buildErrorType	(buildErrorType)
   1201 	{
   1202 	}
   1203 
   1204 	void test (void)
   1205 	{
   1206 		using tcu::TestLog;
   1207 
   1208 		enum
   1209 		{
   1210 			BUF_SIZE = 2048
   1211 		};
   1212 
   1213 		static const char* const linkErrorVtxSource = "#version 300 es\n"
   1214 													  "in highp vec4 a_pos;\n"
   1215 													  "uniform highp vec4 u_uniform;\n"
   1216 													  "void main ()\n"
   1217 													  "{\n"
   1218 													  "	gl_Position = a_pos + u_uniform;\n"
   1219 													  "}\n";
   1220 		static const char* const linkErrorFrgSource = "#version 300 es\n"
   1221 													  "in highp vec4 v_missingVar;\n"
   1222 													  "uniform highp int u_uniform;\n"
   1223 													  "layout(location = 0) out mediump vec4 fragColor;\n"
   1224 													  "void main ()\n"
   1225 													  "{\n"
   1226 													  "	fragColor = v_missingVar + vec4(float(u_uniform));\n"
   1227 													  "}\n";
   1228 
   1229 		const char* vtxSource = (m_buildErrorType == BUILDERROR_COMPILE) ? (brokenShader) : (linkErrorVtxSource);
   1230 		const char* frgSource = (m_buildErrorType == BUILDERROR_COMPILE) ? (brokenShader) : (linkErrorFrgSource);
   1231 
   1232 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   1233 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   1234 
   1235 		glShaderSource(shaderVert, 1, &vtxSource, DE_NULL);
   1236 		glShaderSource(shaderFrag, 1, &frgSource, DE_NULL);
   1237 
   1238 		glCompileShader(shaderVert);
   1239 		glCompileShader(shaderFrag);
   1240 		expectError(GL_NO_ERROR);
   1241 
   1242 		GLuint program = glCreateProgram();
   1243 		glAttachShader(program, shaderVert);
   1244 		glAttachShader(program, shaderFrag);
   1245 		glLinkProgram(program);
   1246 
   1247 		StateQueryMemoryWriteGuard<GLint> logLength;
   1248 		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
   1249 		logLength.verifyValidity(m_testCtx);
   1250 
   1251 		// check INFO_LOG_LENGTH == GetProgramInfoLog len
   1252 		{
   1253 			const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "QueryLarge", "Query to large buffer");
   1254 			char						buffer[BUF_SIZE]	= {'x'};
   1255 			GLint						written				= 0;
   1256 
   1257 			glGetProgramInfoLog(program, BUF_SIZE, &written, buffer);
   1258 
   1259 			if (logLength != 0 && written+1 != logLength) // INFO_LOG_LENGTH contains 0-terminator
   1260 			{
   1261 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected INFO_LOG_LENGTH " << written+1 << "; got " << logLength << TestLog::EndMessage;
   1262 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1263 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
   1264 			}
   1265 			else if (logLength != 0 && buffer[written] != '\0')
   1266 			{
   1267 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator at index " << written << TestLog::EndMessage;
   1268 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1269 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing null terminator");
   1270 			}
   1271 		}
   1272 
   1273 		// check query to just correct sized buffer
   1274 		if (BUF_SIZE > logLength)
   1275 		{
   1276 			const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "QueryAll", "Query all to exactly right sized buffer");
   1277 			char						buffer[BUF_SIZE]	= {'x'};
   1278 			GLint						written				= 0;
   1279 
   1280 			glGetProgramInfoLog(program, logLength, &written, buffer);
   1281 
   1282 			if (logLength != 0 && written+1 != logLength) // INFO_LOG_LENGTH contains 0-terminator
   1283 			{
   1284 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected INFO_LOG_LENGTH " << written+1 << "; got " << logLength << TestLog::EndMessage;
   1285 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1286 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
   1287 			}
   1288 			else if (logLength != 0 && buffer[written] != '\0')
   1289 			{
   1290 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator at index " << written << TestLog::EndMessage;
   1291 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1292 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing null terminator");
   1293 			}
   1294 		}
   1295 
   1296 		// check GetProgramInfoLog works with too small buffer
   1297 		{
   1298 			const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "QueryNone", "Query none");
   1299 			char						buffer[BUF_SIZE]	= {'x'};
   1300 			GLint						written				= 0;
   1301 
   1302 			glGetProgramInfoLog(program, 1, &written, buffer);
   1303 
   1304 			if (written != 0)
   1305 			{
   1306 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length 0; got " << written << TestLog::EndMessage;
   1307 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1308 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
   1309 			}
   1310 		}
   1311 
   1312 		glDeleteShader(shaderVert);
   1313 		glDeleteShader(shaderFrag);
   1314 		glDeleteProgram(program);
   1315 		expectError(GL_NO_ERROR);
   1316 	}
   1317 
   1318 	const BuildErrorType m_buildErrorType;
   1319 };
   1320 
   1321 class ProgramValidateStatusCase : public ApiCase
   1322 {
   1323 public:
   1324 	ProgramValidateStatusCase (Context& context, const char* name, const char* description)
   1325 		: ApiCase(context, name, description)
   1326 	{
   1327 	}
   1328 
   1329 	void test (void)
   1330 	{
   1331 		// test validate ok
   1332 		{
   1333 			GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   1334 			GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   1335 
   1336 			glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
   1337 			glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
   1338 
   1339 			glCompileShader(shaderVert);
   1340 			glCompileShader(shaderFrag);
   1341 			expectError(GL_NO_ERROR);
   1342 
   1343 			GLuint program = glCreateProgram();
   1344 			glAttachShader(program, shaderVert);
   1345 			glAttachShader(program, shaderFrag);
   1346 			glLinkProgram(program);
   1347 			expectError(GL_NO_ERROR);
   1348 
   1349 			verifyShaderParam	(m_testCtx, *this, shaderVert,	GL_COMPILE_STATUS,	GL_TRUE);
   1350 			verifyShaderParam	(m_testCtx, *this, shaderFrag,	GL_COMPILE_STATUS,	GL_TRUE);
   1351 			verifyProgramParam	(m_testCtx, *this, program,		GL_LINK_STATUS,		GL_TRUE);
   1352 
   1353 			glValidateProgram(program);
   1354 			verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_TRUE);
   1355 
   1356 			glDeleteShader(shaderVert);
   1357 			glDeleteShader(shaderFrag);
   1358 			glDeleteProgram(program);
   1359 			expectError(GL_NO_ERROR);
   1360 		}
   1361 
   1362 		// test with broken shader
   1363 		{
   1364 			GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   1365 			GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   1366 
   1367 			glShaderSource(shaderVert, 1, &commonTestVertSource,	DE_NULL);
   1368 			glShaderSource(shaderFrag, 1, &brokenShader,			DE_NULL);
   1369 
   1370 			glCompileShader(shaderVert);
   1371 			glCompileShader(shaderFrag);
   1372 			expectError(GL_NO_ERROR);
   1373 
   1374 			GLuint program = glCreateProgram();
   1375 			glAttachShader(program, shaderVert);
   1376 			glAttachShader(program, shaderFrag);
   1377 			glLinkProgram(program);
   1378 			expectError(GL_NO_ERROR);
   1379 
   1380 			verifyShaderParam	(m_testCtx, *this, shaderVert,	GL_COMPILE_STATUS,	GL_TRUE);
   1381 			verifyShaderParam	(m_testCtx, *this, shaderFrag,	GL_COMPILE_STATUS,	GL_FALSE);
   1382 			verifyProgramParam	(m_testCtx, *this, program,		GL_LINK_STATUS,		GL_FALSE);
   1383 
   1384 			glValidateProgram(program);
   1385 			verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_FALSE);
   1386 
   1387 			glDeleteShader(shaderVert);
   1388 			glDeleteShader(shaderFrag);
   1389 			glDeleteProgram(program);
   1390 			expectError(GL_NO_ERROR);
   1391 		}
   1392 	}
   1393 };
   1394 
   1395 class ProgramAttachedShadersCase : public ApiCase
   1396 {
   1397 public:
   1398 	ProgramAttachedShadersCase (Context& context, const char* name, const char* description)
   1399 		: ApiCase(context, name, description)
   1400 	{
   1401 	}
   1402 
   1403 	void test (void)
   1404 	{
   1405 		using tcu::TestLog;
   1406 
   1407 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   1408 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   1409 
   1410 		glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
   1411 		glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
   1412 
   1413 		glCompileShader(shaderVert);
   1414 		glCompileShader(shaderFrag);
   1415 		expectError(GL_NO_ERROR);
   1416 
   1417 		// check ATTACHED_SHADERS
   1418 
   1419 		GLuint program = glCreateProgram();
   1420 		verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 0);
   1421 		expectError(GL_NO_ERROR);
   1422 
   1423 		glAttachShader(program, shaderVert);
   1424 		verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 1);
   1425 		expectError(GL_NO_ERROR);
   1426 
   1427 		glAttachShader(program, shaderFrag);
   1428 		verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 2);
   1429 		expectError(GL_NO_ERROR);
   1430 
   1431 		// check GetAttachedShaders
   1432 		{
   1433 			GLuint shaders[2] = {0, 0};
   1434 			GLint count = 0;
   1435 			glGetAttachedShaders(program, DE_LENGTH_OF_ARRAY(shaders), &count, shaders);
   1436 
   1437 			if (count != 2)
   1438 			{
   1439 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 2; got " << count << TestLog::EndMessage;
   1440 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1441 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
   1442 			}
   1443 			// shaders are the attached shaders?
   1444 			if (!((shaders[0] == shaderVert && shaders[1] == shaderFrag) ||
   1445 				  (shaders[0] == shaderFrag && shaders[1] == shaderVert)))
   1446 			{
   1447 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected {" << shaderVert << ", " << shaderFrag << "}; got {" << shaders[0] << ", " << shaders[1] << "}" << TestLog::EndMessage;
   1448 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1449 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
   1450 			}
   1451 		}
   1452 
   1453 		// check GetAttachedShaders with too small buffer
   1454 		{
   1455 			GLuint shaders[2] = {0, 0};
   1456 			GLint count = 0;
   1457 
   1458 			glGetAttachedShaders(program, 0, &count, shaders);
   1459 			if (count != 0)
   1460 			{
   1461 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0; got " << count << TestLog::EndMessage;
   1462 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1463 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
   1464 			}
   1465 
   1466 			count = 0;
   1467 			glGetAttachedShaders(program, 1, &count, shaders);
   1468 			if (count != 1)
   1469 			{
   1470 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 1; got " << count << TestLog::EndMessage;
   1471 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1472 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
   1473 			}
   1474 		}
   1475 
   1476 		glDeleteShader(shaderVert);
   1477 		glDeleteShader(shaderFrag);
   1478 		glDeleteProgram(program);
   1479 		expectError(GL_NO_ERROR);
   1480 	}
   1481 };
   1482 
   1483 class ProgramActiveUniformNameCase : public ApiCase
   1484 {
   1485 public:
   1486 	ProgramActiveUniformNameCase (Context& context, const char* name, const char* description)
   1487 		: ApiCase(context, name, description)
   1488 	{
   1489 	}
   1490 
   1491 	void test (void)
   1492 	{
   1493 		using tcu::TestLog;
   1494 
   1495 		static const char* testVertSource =
   1496 			"#version 300 es\n"
   1497 			"uniform highp float uniformNameWithLength23;\n"
   1498 			"uniform highp vec2 uniformVec2;\n"
   1499 			"uniform highp mat4 uniformMat4;\n"
   1500 			"void main (void)\n"
   1501 			"{\n"
   1502 			"	gl_Position = vec4(0.0) + vec4(uniformNameWithLength23) + vec4(uniformVec2.x) + vec4(uniformMat4[2][3]);\n"
   1503 			"}\n\0";
   1504 		static const char* testFragSource =
   1505 			"#version 300 es\n"
   1506 			"layout(location = 0) out mediump vec4 fragColor;"
   1507 			"void main (void)\n"
   1508 			"{\n"
   1509 			"	fragColor = vec4(0.0);\n"
   1510 			"}\n\0";
   1511 
   1512 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   1513 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   1514 
   1515 		glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
   1516 		glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
   1517 
   1518 		glCompileShader(shaderVert);
   1519 		glCompileShader(shaderFrag);
   1520 		expectError(GL_NO_ERROR);
   1521 
   1522 		GLuint program = glCreateProgram();
   1523 		glAttachShader(program, shaderVert);
   1524 		glAttachShader(program, shaderFrag);
   1525 		glLinkProgram(program);
   1526 		expectError(GL_NO_ERROR);
   1527 
   1528 		verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORMS, 3);
   1529 		verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, (GLint)std::string("uniformNameWithLength23").length() + 1); // including a null terminator
   1530 		expectError(GL_NO_ERROR);
   1531 
   1532 		const char* uniformNames[] =
   1533 		{
   1534 			"uniformNameWithLength23",
   1535 			"uniformVec2",
   1536 			"uniformMat4"
   1537 		};
   1538 		StateQueryMemoryWriteGuard<GLuint[DE_LENGTH_OF_ARRAY(uniformNames)]> uniformIndices;
   1539 		glGetUniformIndices(program, DE_LENGTH_OF_ARRAY(uniformNames), uniformNames, uniformIndices);
   1540 		uniformIndices.verifyValidity(m_testCtx);
   1541 
   1542 		// check name lengths
   1543 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformNames); ++ndx)
   1544 		{
   1545 			const GLuint uniformIndex = uniformIndices[ndx];
   1546 
   1547 			StateQueryMemoryWriteGuard<GLint> uniformNameLen;
   1548 			glGetActiveUniformsiv(program, 1, &uniformIndex, GL_UNIFORM_NAME_LENGTH, &uniformNameLen);
   1549 
   1550 			uniformNameLen.verifyValidity(m_testCtx);
   1551 
   1552 			const GLint referenceLength = (GLint)std::string(uniformNames[ndx]).length() + 1;
   1553 			if (referenceLength != uniformNameLen) // uniformNameLen is with null terminator
   1554 			{
   1555 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << referenceLength << "got " << uniformNameLen << TestLog::EndMessage;
   1556 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1557 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name length");
   1558 			}
   1559 		}
   1560 
   1561 		// check names
   1562 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformNames); ++ndx)
   1563 		{
   1564 			char buffer[2048] = {'x'};
   1565 
   1566 			const GLuint uniformIndex = uniformIndices[ndx];
   1567 
   1568 			GLint written = 0; // null terminator not included
   1569 			GLint size = 0;
   1570 			GLenum type = 0;
   1571 			glGetActiveUniform(program, uniformIndex, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer);
   1572 
   1573 			const GLint referenceLength = (GLint)std::string(uniformNames[ndx]).length();
   1574 			if (referenceLength != written)
   1575 			{
   1576 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << referenceLength << "got " << written << TestLog::EndMessage;
   1577 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1578 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name length");
   1579 			}
   1580 
   1581 			// and with too small buffer
   1582 			written = 0;
   1583 			glGetActiveUniform(program, uniformIndex, 1, &written, &size, &type, buffer);
   1584 
   1585 			if (written != 0)
   1586 			{
   1587 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0 got " << written << TestLog::EndMessage;
   1588 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1589 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name length");
   1590 			}
   1591 		}
   1592 
   1593 
   1594 		glDeleteShader(shaderVert);
   1595 		glDeleteShader(shaderFrag);
   1596 		glDeleteProgram(program);
   1597 		expectError(GL_NO_ERROR);
   1598 	}
   1599 };
   1600 
   1601 class ProgramUniformCase : public ApiCase
   1602 {
   1603 public:
   1604 	ProgramUniformCase (Context& context, const char* name, const char* description)
   1605 		: ApiCase(context, name, description)
   1606 	{
   1607 	}
   1608 
   1609 	void test (void)
   1610 	{
   1611 		const struct UniformType
   1612 		{
   1613 			const char* declaration;
   1614 			const char* postDeclaration;
   1615 			const char* precision;
   1616 			const char* layout;
   1617 			const char* getter;
   1618 			GLenum		type;
   1619 			GLint		size;
   1620 			GLint		isRowMajor;
   1621 		} uniformTypes[] =
   1622 		{
   1623 			{ "float",					"",			"highp",	"",						"uniformValue",							GL_FLOAT,							1, GL_FALSE },
   1624 			{ "float[2]",				"",			"highp",	"",						"uniformValue[1]",						GL_FLOAT,							2, GL_FALSE },
   1625 			{ "vec2",					"",			"highp",	"",						"uniformValue.x",						GL_FLOAT_VEC2,						1, GL_FALSE },
   1626 			{ "vec3",					"",			"highp",	"",						"uniformValue.x",						GL_FLOAT_VEC3,						1, GL_FALSE },
   1627 			{ "vec4",					"",			"highp",	"",						"uniformValue.x",						GL_FLOAT_VEC4,						1, GL_FALSE },
   1628 			{ "int",					"",			"highp",	"",						"float(uniformValue)",					GL_INT,								1, GL_FALSE },
   1629 			{ "ivec2",					"",			"highp",	"",						"float(uniformValue.x)",				GL_INT_VEC2,						1, GL_FALSE },
   1630 			{ "ivec3",					"",			"highp",	"",						"float(uniformValue.x)",				GL_INT_VEC3,						1, GL_FALSE },
   1631 			{ "ivec4",					"",			"highp",	"",						"float(uniformValue.x)",				GL_INT_VEC4,						1, GL_FALSE },
   1632 			{ "uint",					"",			"highp",	"",						"float(uniformValue)",					GL_UNSIGNED_INT,					1, GL_FALSE },
   1633 			{ "uvec2",					"",			"highp",	"",						"float(uniformValue.x)",				GL_UNSIGNED_INT_VEC2,				1, GL_FALSE },
   1634 			{ "uvec3",					"",			"highp",	"",						"float(uniformValue.x)",				GL_UNSIGNED_INT_VEC3,				1, GL_FALSE },
   1635 			{ "uvec4",					"",			"highp",	"",						"float(uniformValue.x)",				GL_UNSIGNED_INT_VEC4,				1, GL_FALSE },
   1636 			{ "bool",					"",			"",			"",						"float(uniformValue)",					GL_BOOL,							1, GL_FALSE },
   1637 			{ "bvec2",					"",			"",			"",						"float(uniformValue.x)",				GL_BOOL_VEC2,						1, GL_FALSE },
   1638 			{ "bvec3",					"",			"",			"",						"float(uniformValue.x)",				GL_BOOL_VEC3,						1, GL_FALSE },
   1639 			{ "bvec4",					"",			"",			"",						"float(uniformValue.x)",				GL_BOOL_VEC4,						1, GL_FALSE },
   1640 			{ "mat2",					"",			"highp",	"",						"float(uniformValue[0][0])",			GL_FLOAT_MAT2,						1, GL_FALSE },
   1641 			{ "mat3",					"",			"highp",	"",						"float(uniformValue[0][0])",			GL_FLOAT_MAT3,						1, GL_FALSE },
   1642 			{ "mat4",					"",			"highp",	"",						"float(uniformValue[0][0])",			GL_FLOAT_MAT4,						1, GL_FALSE },
   1643 			{ "mat2x3",					"",			"highp",	"",						"float(uniformValue[0][0])",			GL_FLOAT_MAT2x3,					1, GL_FALSE },
   1644 			{ "mat2x4",					"",			"highp",	"",						"float(uniformValue[0][0])",			GL_FLOAT_MAT2x4,					1, GL_FALSE },
   1645 			{ "mat3x2",					"",			"highp",	"",						"float(uniformValue[0][0])",			GL_FLOAT_MAT3x2,					1, GL_FALSE },
   1646 			{ "mat3x4",					"",			"highp",	"",						"float(uniformValue[0][0])",			GL_FLOAT_MAT3x4,					1, GL_FALSE },
   1647 			{ "mat4x2",					"",			"highp",	"",						"float(uniformValue[0][0])",			GL_FLOAT_MAT4x2,					1, GL_FALSE },
   1648 			{ "mat4x3",					"",			"highp",	"",						"float(uniformValue[0][0])",			GL_FLOAT_MAT4x3,					1, GL_FALSE },
   1649 			{ "sampler2D",				"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_SAMPLER_2D,						1, GL_FALSE },
   1650 			{ "sampler3D",				"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_SAMPLER_3D,						1, GL_FALSE },
   1651 			{ "samplerCube",			"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_SAMPLER_CUBE,					1, GL_FALSE },
   1652 			{ "sampler2DShadow",		"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_SAMPLER_2D_SHADOW,				1, GL_FALSE },
   1653 			{ "sampler2DArray",			"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_SAMPLER_2D_ARRAY,				1, GL_FALSE },
   1654 			{ "sampler2DArrayShadow",	"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_SAMPLER_2D_ARRAY_SHADOW,			1, GL_FALSE },
   1655 			{ "samplerCubeShadow",		"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_SAMPLER_CUBE_SHADOW,				1, GL_FALSE },
   1656 			{ "isampler2D",				"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_INT_SAMPLER_2D,					1, GL_FALSE },
   1657 			{ "isampler3D",				"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_INT_SAMPLER_3D,					1, GL_FALSE },
   1658 			{ "isamplerCube",			"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_INT_SAMPLER_CUBE,				1, GL_FALSE },
   1659 			{ "isampler2DArray",		"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_INT_SAMPLER_2D_ARRAY,			1, GL_FALSE },
   1660 			{ "usampler2D",				"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_UNSIGNED_INT_SAMPLER_2D,			1, GL_FALSE },
   1661 			{ "usampler3D",				"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_UNSIGNED_INT_SAMPLER_3D,			1, GL_FALSE },
   1662 			{ "usamplerCube",			"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_UNSIGNED_INT_SAMPLER_CUBE,		1, GL_FALSE },
   1663 			{ "usampler2DArray",		"",			"highp",	"",						"float(textureSize(uniformValue,0).r)",	GL_UNSIGNED_INT_SAMPLER_2D_ARRAY,	1, GL_FALSE },
   1664 		};
   1665 
   1666 		static const char* vertSource =
   1667 			"#version 300 es\n"
   1668 			"void main (void)\n"
   1669 			"{\n"
   1670 			"	gl_Position = vec4(0.0);\n"
   1671 			"}\n\0";
   1672 
   1673 		GLuint shaderVert	= glCreateShader(GL_VERTEX_SHADER);
   1674 		GLuint shaderFrag	= glCreateShader(GL_FRAGMENT_SHADER);
   1675 		GLuint program		= glCreateProgram();
   1676 
   1677 		glAttachShader(program, shaderVert);
   1678 		glAttachShader(program, shaderFrag);
   1679 
   1680 		glShaderSource(shaderVert, 1, &vertSource, DE_NULL);
   1681 		glCompileShader(shaderVert);
   1682 		expectError(GL_NO_ERROR);
   1683 
   1684 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformTypes); ++ndx)
   1685 		{
   1686 			tcu::ScopedLogSection(m_log, uniformTypes[ndx].declaration, std::string("Verify type of ") + uniformTypes[ndx].declaration + " variable" + uniformTypes[ndx].postDeclaration );
   1687 
   1688 			// gen fragment shader
   1689 
   1690 			std::ostringstream frag;
   1691 			frag << "#version 300 es\n";
   1692 			frag << uniformTypes[ndx].layout << "uniform " << uniformTypes[ndx].precision << " " << uniformTypes[ndx].declaration << " uniformValue" << uniformTypes[ndx].postDeclaration << ";\n";
   1693 			frag << "layout(location = 0) out mediump vec4 fragColor;\n";
   1694 			frag << "void main (void)\n";
   1695 			frag << "{\n";
   1696 			frag << "	fragColor = vec4(" << uniformTypes[ndx].getter << ");\n";
   1697 			frag << "}\n";
   1698 
   1699 			{
   1700 				std::string fragmentSource = frag.str();
   1701 				const char* fragmentSourceCStr = fragmentSource.c_str();
   1702 				glShaderSource(shaderFrag, 1, &fragmentSourceCStr, DE_NULL);
   1703 			}
   1704 
   1705 			// compile & link
   1706 
   1707 			glCompileShader(shaderFrag);
   1708 			glLinkProgram(program);
   1709 
   1710 			// test
   1711 			if (verifyProgramParam(m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE))
   1712 			{
   1713 				const char* uniformNames[] = {"uniformValue"};
   1714 				StateQueryMemoryWriteGuard<GLuint> uniformIndex;
   1715 				glGetUniformIndices(program, 1, uniformNames, &uniformIndex);
   1716 				uniformIndex.verifyValidity(m_testCtx);
   1717 
   1718 				verifyActiveUniformParam(m_testCtx, *this, program, uniformIndex, GL_UNIFORM_TYPE,			uniformTypes[ndx].type);
   1719 				verifyActiveUniformParam(m_testCtx, *this, program, uniformIndex, GL_UNIFORM_SIZE,			uniformTypes[ndx].size);
   1720 				verifyActiveUniformParam(m_testCtx, *this, program, uniformIndex, GL_UNIFORM_IS_ROW_MAJOR,	uniformTypes[ndx].isRowMajor);
   1721 			}
   1722 		}
   1723 
   1724 		glDeleteShader(shaderVert);
   1725 		glDeleteShader(shaderFrag);
   1726 		glDeleteProgram(program);
   1727 		expectError(GL_NO_ERROR);
   1728 	}
   1729 };
   1730 
   1731 class ProgramActiveUniformBlocksCase : public ApiCase
   1732 {
   1733 public:
   1734 	ProgramActiveUniformBlocksCase (Context& context, const char* name, const char* description)
   1735 		: ApiCase(context, name, description)
   1736 	{
   1737 	}
   1738 
   1739 	void test (void)
   1740 	{
   1741 		using tcu::TestLog;
   1742 
   1743 		static const char* testVertSource =
   1744 			"#version 300 es\n"
   1745 			"uniform longlongUniformBlockName {highp vec2 vector2;} longlongUniformInstanceName;\n"
   1746 			"uniform shortUniformBlockName {highp vec2 vector2;highp vec4 vector4;} shortUniformInstanceName;\n"
   1747 			"void main (void)\n"
   1748 			"{\n"
   1749 			"	gl_Position = shortUniformInstanceName.vector4 + vec4(longlongUniformInstanceName.vector2.x) + vec4(shortUniformInstanceName.vector2.x);\n"
   1750 			"}\n\0";
   1751 		static const char* testFragSource =
   1752 			"#version 300 es\n"
   1753 			"uniform longlongUniformBlockName {highp vec2 vector2;} longlongUniformInstanceName;\n"
   1754 			"layout(location = 0) out mediump vec4 fragColor;"
   1755 			"void main (void)\n"
   1756 			"{\n"
   1757 			"	fragColor = vec4(longlongUniformInstanceName.vector2.y);\n"
   1758 			"}\n\0";
   1759 
   1760 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   1761 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   1762 
   1763 		glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
   1764 		glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
   1765 
   1766 		glCompileShader(shaderVert);
   1767 		glCompileShader(shaderFrag);
   1768 		expectError(GL_NO_ERROR);
   1769 
   1770 		GLuint program = glCreateProgram();
   1771 		glAttachShader(program, shaderVert);
   1772 		glAttachShader(program, shaderFrag);
   1773 		glLinkProgram(program);
   1774 		expectError(GL_NO_ERROR);
   1775 
   1776 		verifyShaderParam	(m_testCtx, *this, shaderVert,	GL_COMPILE_STATUS,	GL_TRUE);
   1777 		verifyShaderParam	(m_testCtx, *this, shaderFrag,	GL_COMPILE_STATUS,	GL_TRUE);
   1778 		verifyProgramParam	(m_testCtx, *this, program,		GL_LINK_STATUS,		GL_TRUE);
   1779 
   1780 		verifyProgramParam	(m_testCtx, *this, program,		GL_ACTIVE_UNIFORM_BLOCKS, 2);
   1781 		verifyProgramParam	(m_testCtx, *this, program,		GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, (GLint)std::string("longlongUniformBlockName").length() + 1); // including a null terminator
   1782 		expectError(GL_NO_ERROR);
   1783 
   1784 		GLint longlongUniformBlockIndex	= glGetUniformBlockIndex(program, "longlongUniformBlockName");
   1785 		GLint shortUniformBlockIndex	= glGetUniformBlockIndex(program, "shortUniformBlockName");
   1786 
   1787 		const char* uniformNames[] =
   1788 		{
   1789 			"longlongUniformBlockName.vector2",
   1790 			"shortUniformBlockName.vector2",
   1791 			"shortUniformBlockName.vector4"
   1792 		};
   1793 
   1794 		// test UNIFORM_BLOCK_INDEX
   1795 
   1796 		DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(uniformNames) == 3);
   1797 
   1798 		StateQueryMemoryWriteGuard<GLuint[DE_LENGTH_OF_ARRAY(uniformNames)]> uniformIndices;
   1799 		StateQueryMemoryWriteGuard<GLint[DE_LENGTH_OF_ARRAY(uniformNames)]> uniformsBlockIndices;
   1800 
   1801 		glGetUniformIndices(program, DE_LENGTH_OF_ARRAY(uniformNames), uniformNames, uniformIndices);
   1802 		uniformIndices.verifyValidity(m_testCtx);
   1803 		expectError(GL_NO_ERROR);
   1804 
   1805 		glGetActiveUniformsiv(program, DE_LENGTH_OF_ARRAY(uniformNames), uniformIndices, GL_UNIFORM_BLOCK_INDEX, uniformsBlockIndices);
   1806 		uniformsBlockIndices.verifyValidity(m_testCtx);
   1807 		expectError(GL_NO_ERROR);
   1808 
   1809 		if (uniformsBlockIndices[0] != longlongUniformBlockIndex ||
   1810 			uniformsBlockIndices[1] != shortUniformBlockIndex ||
   1811 			uniformsBlockIndices[2] != shortUniformBlockIndex)
   1812 		{
   1813 			m_testCtx.getLog() << TestLog::Message
   1814 				<< "// ERROR: Expected ["	<< longlongUniformBlockIndex	<< ", " << shortUniformBlockIndex	<< ", " << shortUniformBlockIndex	<< "];"
   1815 				<<	"got ["					<< uniformsBlockIndices[0]		<< ", " << uniformsBlockIndices[1]	<< ", " << uniformsBlockIndices[2]	<< "]" << TestLog::EndMessage;
   1816 			if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1817 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform block index");
   1818 		}
   1819 
   1820 		// test UNIFORM_BLOCK_NAME_LENGTH
   1821 
   1822 		verifyActiveUniformBlockParam(m_testCtx, *this, program, longlongUniformBlockIndex,	GL_UNIFORM_BLOCK_NAME_LENGTH, (GLint)std::string("longlongUniformBlockName").length() + 1); // including null-terminator
   1823 		verifyActiveUniformBlockParam(m_testCtx, *this, program, shortUniformBlockIndex,	GL_UNIFORM_BLOCK_NAME_LENGTH, (GLint)std::string("shortUniformBlockName").length() + 1); // including null-terminator
   1824 		expectError(GL_NO_ERROR);
   1825 
   1826 		// test UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER & UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER
   1827 
   1828 		verifyActiveUniformBlockParam(m_testCtx, *this, program, longlongUniformBlockIndex,	GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER,	GL_TRUE);
   1829 		verifyActiveUniformBlockParam(m_testCtx, *this, program, longlongUniformBlockIndex,	GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER,	GL_TRUE);
   1830 		verifyActiveUniformBlockParam(m_testCtx, *this, program, shortUniformBlockIndex,	GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER,	GL_TRUE);
   1831 		verifyActiveUniformBlockParam(m_testCtx, *this, program, shortUniformBlockIndex,	GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER,	GL_FALSE);
   1832 		expectError(GL_NO_ERROR);
   1833 
   1834 		// test UNIFORM_BLOCK_ACTIVE_UNIFORMS
   1835 
   1836 		verifyActiveUniformBlockParam(m_testCtx, *this, program, longlongUniformBlockIndex,	GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS,	1);
   1837 		verifyActiveUniformBlockParam(m_testCtx, *this, program, shortUniformBlockIndex,	GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS,	2);
   1838 		expectError(GL_NO_ERROR);
   1839 
   1840 		// test UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES
   1841 
   1842 		{
   1843 			StateQueryMemoryWriteGuard<GLint> longlongUniformBlockUniforms;
   1844 			glGetActiveUniformBlockiv(program, longlongUniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &longlongUniformBlockUniforms);
   1845 			longlongUniformBlockUniforms.verifyValidity(m_testCtx);
   1846 
   1847 			if (longlongUniformBlockUniforms == 2)
   1848 			{
   1849 				StateQueryMemoryWriteGuard<GLint[2]> longlongUniformBlockUniformIndices;
   1850 				glGetActiveUniformBlockiv(program, longlongUniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, longlongUniformBlockUniformIndices);
   1851 				longlongUniformBlockUniformIndices.verifyValidity(m_testCtx);
   1852 
   1853 				if ((GLuint(longlongUniformBlockUniformIndices[0]) != uniformIndices[0] || GLuint(longlongUniformBlockUniformIndices[1]) != uniformIndices[1]) &&
   1854 					(GLuint(longlongUniformBlockUniformIndices[1]) != uniformIndices[0] || GLuint(longlongUniformBlockUniformIndices[0]) != uniformIndices[1]))
   1855 				{
   1856 					m_testCtx.getLog() << TestLog::Message
   1857 						<< "// ERROR: Expected {"	<< uniformIndices[0]						<< ", " << uniformIndices[1] << "};"
   1858 						<<	"got {"					<< longlongUniformBlockUniformIndices[0]	<< ", " << longlongUniformBlockUniformIndices[1] << "}" << TestLog::EndMessage;
   1859 
   1860 					if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   1861 						m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform indices");
   1862 				}
   1863 
   1864 			}
   1865 		}
   1866 
   1867 		// check block names
   1868 
   1869 		{
   1870 			char buffer[2048] = {'x'};
   1871 			GLint written = 0;
   1872 			glGetActiveUniformBlockName(program, longlongUniformBlockIndex, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);
   1873 			checkIntEquals(m_testCtx, written, (GLint)std::string("longlongUniformBlockName").length());
   1874 
   1875 			written = 0;
   1876 			glGetActiveUniformBlockName(program, shortUniformBlockIndex, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);
   1877 			checkIntEquals(m_testCtx, written, (GLint)std::string("shortUniformBlockName").length());
   1878 
   1879 			// and one with too small buffer
   1880 			written = 0;
   1881 			glGetActiveUniformBlockName(program, longlongUniformBlockIndex, 1, &written, buffer);
   1882 			checkIntEquals(m_testCtx, written, 0);
   1883 		}
   1884 
   1885 		expectError(GL_NO_ERROR);
   1886 		glDeleteShader(shaderVert);
   1887 		glDeleteShader(shaderFrag);
   1888 		glDeleteProgram(program);
   1889 		expectError(GL_NO_ERROR);
   1890 	}
   1891 };
   1892 
   1893 class ProgramBinaryCase : public ApiCase
   1894 {
   1895 public:
   1896 	ProgramBinaryCase (Context& context, const char* name, const char* description)
   1897 		: ApiCase(context, name, description)
   1898 	{
   1899 	}
   1900 
   1901 	void test (void)
   1902 	{
   1903 		using tcu::TestLog;
   1904 
   1905 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   1906 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   1907 
   1908 		glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
   1909 		glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
   1910 
   1911 		glCompileShader(shaderVert);
   1912 		glCompileShader(shaderFrag);
   1913 		expectError(GL_NO_ERROR);
   1914 
   1915 		GLuint program = glCreateProgram();
   1916 		glAttachShader(program, shaderVert);
   1917 		glAttachShader(program, shaderFrag);
   1918 		glLinkProgram(program);
   1919 		expectError(GL_NO_ERROR);
   1920 
   1921 		// test PROGRAM_BINARY_RETRIEVABLE_HINT
   1922 		verifyProgramParam(m_testCtx, *this, program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_FALSE);
   1923 
   1924 		glProgramParameteri(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
   1925 		expectError(GL_NO_ERROR);
   1926 
   1927 		glLinkProgram(program);
   1928 		expectError(GL_NO_ERROR);
   1929 
   1930 		verifyProgramParam(m_testCtx, *this, program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
   1931 
   1932 		// test PROGRAM_BINARY_LENGTH does something
   1933 
   1934 		StateQueryMemoryWriteGuard<GLint> programLength;
   1935 		glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &programLength);
   1936 		expectError(GL_NO_ERROR);
   1937 		programLength.verifyValidity(m_testCtx);
   1938 
   1939 		glDeleteShader(shaderVert);
   1940 		glDeleteShader(shaderFrag);
   1941 		glDeleteProgram(program);
   1942 		expectError(GL_NO_ERROR);
   1943 	}
   1944 };
   1945 
   1946 class TransformFeedbackCase : public ApiCase
   1947 {
   1948 public:
   1949 	TransformFeedbackCase (Context& context, const char* name, const char* description)
   1950 		: ApiCase(context, name, description)
   1951 	{
   1952 	}
   1953 
   1954 	void test (void)
   1955 	{
   1956 		using tcu::TestLog;
   1957 
   1958 		static const char* transformFeedbackTestVertSource =
   1959 			"#version 300 es\n"
   1960 			"out highp vec4 tfOutput2withLongName;\n"
   1961 			"void main (void)\n"
   1962 			"{\n"
   1963 			"	gl_Position = vec4(0.0);\n"
   1964 			"	tfOutput2withLongName = vec4(0.0);\n"
   1965 			"}\n";
   1966 		static const char* transformFeedbackTestFragSource =
   1967 			"#version 300 es\n"
   1968 			"layout(location = 0) out highp vec4 fragColor;\n"
   1969 			"void main (void)\n"
   1970 			"{\n"
   1971 			"	fragColor = vec4(0.0);\n"
   1972 			"}\n";
   1973 
   1974 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   1975 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   1976 		GLuint shaderProg = glCreateProgram();
   1977 
   1978 		verifyProgramParam(m_testCtx, *this, shaderProg, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, GL_INTERLEAVED_ATTRIBS);
   1979 
   1980 		glShaderSource(shaderVert, 1, &transformFeedbackTestVertSource, DE_NULL);
   1981 		glShaderSource(shaderFrag, 1, &transformFeedbackTestFragSource, DE_NULL);
   1982 
   1983 		glCompileShader(shaderVert);
   1984 		glCompileShader(shaderFrag);
   1985 
   1986 		verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
   1987 		verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);
   1988 
   1989 		glAttachShader(shaderProg, shaderVert);
   1990 		glAttachShader(shaderProg, shaderFrag);
   1991 
   1992 		// check TRANSFORM_FEEDBACK_BUFFER_MODE
   1993 
   1994 		const char* transform_feedback_outputs[] = {"gl_Position", "tfOutput2withLongName"};
   1995 		const char* longest_output = transform_feedback_outputs[1];
   1996 		const GLenum bufferModes[] = {GL_SEPARATE_ATTRIBS, GL_INTERLEAVED_ATTRIBS};
   1997 
   1998 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bufferModes); ++ndx)
   1999 		{
   2000 			glTransformFeedbackVaryings(shaderProg, DE_LENGTH_OF_ARRAY(transform_feedback_outputs), transform_feedback_outputs, bufferModes[ndx]);
   2001 			glLinkProgram(shaderProg);
   2002 			expectError(GL_NO_ERROR);
   2003 
   2004 			verifyProgramParam(m_testCtx, *this, shaderProg, GL_LINK_STATUS, GL_TRUE);
   2005 			verifyProgramParam(m_testCtx, *this, shaderProg, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, bufferModes[ndx]);
   2006 		}
   2007 
   2008 		// TRANSFORM_FEEDBACK_VARYINGS
   2009 		verifyProgramParam(m_testCtx, *this, shaderProg, GL_TRANSFORM_FEEDBACK_VARYINGS, 2);
   2010 
   2011 		// TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH
   2012 		{
   2013 			StateQueryMemoryWriteGuard<GLint> maxOutputLen;
   2014 			glGetProgramiv(shaderProg, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &maxOutputLen);
   2015 
   2016 			maxOutputLen.verifyValidity(m_testCtx);
   2017 
   2018 			const GLint referenceLength = (GLint)std::string(longest_output).length() + 1;
   2019 			checkIntEquals(m_testCtx, maxOutputLen, referenceLength);
   2020 		}
   2021 
   2022 		// check varyings
   2023 		{
   2024 			StateQueryMemoryWriteGuard<GLint> varyings;
   2025 			glGetProgramiv(shaderProg, GL_TRANSFORM_FEEDBACK_VARYINGS, &varyings);
   2026 
   2027 			if (!varyings.isUndefined())
   2028 				for (int index = 0; index < varyings; ++index)
   2029 				{
   2030 					char buffer[2048] = {'x'};
   2031 
   2032 					GLint written = 0;
   2033 					GLint size = 0;
   2034 					GLenum type = 0;
   2035 					glGetTransformFeedbackVarying(shaderProg, index, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer);
   2036 
   2037 					if (written < DE_LENGTH_OF_ARRAY(buffer) && buffer[written] != '\0')
   2038 					{
   2039 						m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator" << TestLog::EndMessage;
   2040 						if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   2041 							m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid string terminator");
   2042 					}
   2043 
   2044 					// check with too small buffer
   2045 					written = 0;
   2046 					glGetTransformFeedbackVarying(shaderProg, index, 1, &written, &size, &type, buffer);
   2047 					if (written != 0)
   2048 					{
   2049 						m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0; got " << written << TestLog::EndMessage;
   2050 						if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   2051 							m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid write length");
   2052 					}
   2053 				}
   2054 		}
   2055 
   2056 
   2057 		glDeleteShader(shaderVert);
   2058 		glDeleteShader(shaderFrag);
   2059 		glDeleteProgram(shaderProg);
   2060 		expectError(GL_NO_ERROR);
   2061 	}
   2062 };
   2063 
   2064 class ActiveAttributesCase : public ApiCase
   2065 {
   2066 public:
   2067 	ActiveAttributesCase (Context& context, const char* name, const char* description)
   2068 		: ApiCase(context, name, description)
   2069 	{
   2070 	}
   2071 
   2072 	void test (void)
   2073 	{
   2074 		using tcu::TestLog;
   2075 
   2076 		static const char* testVertSource =
   2077 			"#version 300 es\n"
   2078 			"in highp vec2 longInputAttributeName;\n"
   2079 			"in highp vec2 shortName;\n"
   2080 			"void main (void)\n"
   2081 			"{\n"
   2082 			"	gl_Position = longInputAttributeName.yxxy + shortName.xyxy;\n"
   2083 			"}\n\0";
   2084 		static const char* testFragSource =
   2085 			"#version 300 es\n"
   2086 			"layout(location = 0) out mediump vec4 fragColor;"
   2087 			"void main (void)\n"
   2088 			"{\n"
   2089 			"	fragColor = vec4(0.0);\n"
   2090 			"}\n\0";
   2091 
   2092 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   2093 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   2094 
   2095 		glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
   2096 		glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
   2097 
   2098 		glCompileShader(shaderVert);
   2099 		glCompileShader(shaderFrag);
   2100 		expectError(GL_NO_ERROR);
   2101 
   2102 		GLuint program = glCreateProgram();
   2103 		glAttachShader(program, shaderVert);
   2104 		glAttachShader(program, shaderFrag);
   2105 		glLinkProgram(program);
   2106 		expectError(GL_NO_ERROR);
   2107 
   2108 		verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTES, 2);
   2109 		verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, (GLint)std::string("longInputAttributeName").length() + 1); // does include null-terminator
   2110 
   2111 		// check names
   2112 		for (int attributeNdx = 0; attributeNdx < 2; ++attributeNdx)
   2113 		{
   2114 			char buffer[2048] = {'x'};
   2115 
   2116 			GLint written = 0;
   2117 			GLint size = 0;
   2118 			GLenum type = 0;
   2119 			glGetActiveAttrib(program, attributeNdx, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer);
   2120 			expectError(GL_NO_ERROR);
   2121 
   2122 			if (deStringBeginsWith(buffer, "longInputAttributeName"))
   2123 			{
   2124 				checkIntEquals(m_testCtx, written, (GLint)std::string("longInputAttributeName").length()); // does NOT include null-terminator
   2125 			}
   2126 			else if (deStringBeginsWith(buffer, "shortName"))
   2127 			{
   2128 				checkIntEquals(m_testCtx, written, (GLint)std::string("shortName").length()); // does NOT include null-terminator
   2129 			}
   2130 			else
   2131 			{
   2132 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Got unexpected attribute name." << TestLog::EndMessage;
   2133 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
   2134 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected name");
   2135 			}
   2136 		}
   2137 
   2138 		// and with too short buffer
   2139 		{
   2140 			char buffer[2048] = {'x'};
   2141 
   2142 			GLint written = 0;
   2143 			GLint size = 0;
   2144 			GLenum type = 0;
   2145 
   2146 			glGetActiveAttrib(program, 0, 1, &written, &size, &type, buffer);
   2147 			expectError(GL_NO_ERROR);
   2148 			checkIntEquals(m_testCtx, written, 0);
   2149 		}
   2150 
   2151 		glDeleteShader(shaderVert);
   2152 		glDeleteShader(shaderFrag);
   2153 		glDeleteProgram(program);
   2154 		expectError(GL_NO_ERROR);
   2155 	}
   2156 };
   2157 
   2158 struct PointerData
   2159 {
   2160 	GLint		size;
   2161 	GLenum		type;
   2162 	GLint		stride;
   2163 	GLboolean	normalized;
   2164 	const void*	pointer;
   2165 };
   2166 
   2167 class VertexAttributeSizeCase : public ApiCase
   2168 {
   2169 public:
   2170 	VertexAttributeSizeCase (Context& context, const char* name, const char* description)
   2171 		: ApiCase(context, name, description)
   2172 	{
   2173 	}
   2174 
   2175 	void test (void)
   2176 	{
   2177 		GLfloat vertexData[4] = {0.0f}; // never accessed
   2178 
   2179 		const PointerData pointers[] =
   2180 		{
   2181 			// size test
   2182 			{ 4, GL_FLOAT,		0,	GL_FALSE, vertexData },
   2183 			{ 3, GL_FLOAT,		0,	GL_FALSE, vertexData },
   2184 			{ 2, GL_FLOAT,		0,	GL_FALSE, vertexData },
   2185 			{ 1, GL_FLOAT,		0,	GL_FALSE, vertexData },
   2186 			{ 4, GL_INT,		0,	GL_FALSE, vertexData },
   2187 			{ 3, GL_INT,		0,	GL_FALSE, vertexData },
   2188 			{ 2, GL_INT,		0,	GL_FALSE, vertexData },
   2189 			{ 1, GL_INT,		0,	GL_FALSE, vertexData },
   2190 		};
   2191 
   2192 		// Test with default VAO
   2193 		{
   2194 			const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
   2195 
   2196 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
   2197 			{
   2198 				glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
   2199 				expectError(GL_NO_ERROR);
   2200 
   2201 				verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[ndx].size);
   2202 			}
   2203 		}
   2204 
   2205 		// Test with multiple VAOs
   2206 		{
   2207 			const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
   2208 
   2209 			GLuint buf		= 0;
   2210 			GLuint vaos[2]	= {0};
   2211 
   2212 			glGenVertexArrays(2, vaos);
   2213 			glGenBuffers(1, &buf);
   2214 			glBindBuffer(GL_ARRAY_BUFFER, buf);
   2215 			expectError(GL_NO_ERROR);
   2216 
   2217 			// initial
   2218 			glBindVertexArray(vaos[0]);
   2219 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, 4);
   2220 			expectError(GL_NO_ERROR);
   2221 
   2222 			// set vao 0 to some value
   2223 			glVertexAttribPointer(0, pointers[0].size, pointers[0].type, pointers[0].normalized, pointers[0].stride, DE_NULL);
   2224 			expectError(GL_NO_ERROR);
   2225 
   2226 			// set vao 1 to some other value
   2227 			glBindVertexArray(vaos[1]);
   2228 			glVertexAttribPointer(0, pointers[1].size, pointers[1].type, pointers[1].normalized, pointers[1].stride, DE_NULL);
   2229 			expectError(GL_NO_ERROR);
   2230 
   2231 			// verify vao 1 state
   2232 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[1].size);
   2233 			expectError(GL_NO_ERROR);
   2234 
   2235 			// verify vao 0 state
   2236 			glBindVertexArray(vaos[0]);
   2237 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[0].size);
   2238 			expectError(GL_NO_ERROR);
   2239 
   2240 			glDeleteVertexArrays(2, vaos);
   2241 			glDeleteBuffers(1, &buf);
   2242 			expectError(GL_NO_ERROR);
   2243 		}
   2244 	}
   2245 };
   2246 
   2247 class VertexAttributeTypeCase : public ApiCase
   2248 {
   2249 public:
   2250 	VertexAttributeTypeCase (Context& context, const char* name, const char* description)
   2251 		: ApiCase(context, name, description)
   2252 	{
   2253 	}
   2254 
   2255 	void test (void)
   2256 	{
   2257 		// Test with default VAO
   2258 		{
   2259 			const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
   2260 
   2261 			const GLfloat vertexData[4] = {0.0f}; // never accessed
   2262 
   2263 			// test VertexAttribPointer
   2264 			{
   2265 				const PointerData pointers[] =
   2266 				{
   2267 					{ 1, GL_BYTE,								0,	GL_FALSE, vertexData	},
   2268 					{ 1, GL_SHORT,								0,	GL_FALSE, vertexData	},
   2269 					{ 1, GL_INT,								0,	GL_FALSE, vertexData	},
   2270 					{ 1, GL_FIXED,								0,	GL_FALSE, vertexData	},
   2271 					{ 1, GL_FLOAT,								0,	GL_FALSE, vertexData	},
   2272 					{ 1, GL_HALF_FLOAT,							0,	GL_FALSE, vertexData	},
   2273 					{ 1, GL_UNSIGNED_BYTE,						0,	GL_FALSE, vertexData	},
   2274 					{ 1, GL_UNSIGNED_SHORT,						0,	GL_FALSE, vertexData	},
   2275 					{ 1, GL_UNSIGNED_INT,						0,	GL_FALSE, vertexData	},
   2276 					{ 4, GL_INT_2_10_10_10_REV,					0,	GL_FALSE, vertexData	},
   2277 					{ 4, GL_UNSIGNED_INT_2_10_10_10_REV,		0,	GL_FALSE, vertexData	},
   2278 				};
   2279 
   2280 				for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
   2281 				{
   2282 					glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
   2283 					expectError(GL_NO_ERROR);
   2284 
   2285 					verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, pointers[ndx].type);
   2286 				}
   2287 			}
   2288 
   2289 			// test glVertexAttribIPointer
   2290 			{
   2291 				const PointerData pointers[] =
   2292 				{
   2293 					{ 1, GL_BYTE,								0,	GL_FALSE, vertexData	},
   2294 					{ 1, GL_SHORT,								0,	GL_FALSE, vertexData	},
   2295 					{ 1, GL_INT,								0,	GL_FALSE, vertexData	},
   2296 					{ 1, GL_UNSIGNED_BYTE,						0,	GL_FALSE, vertexData	},
   2297 					{ 1, GL_UNSIGNED_SHORT,						0,	GL_FALSE, vertexData	},
   2298 					{ 1, GL_UNSIGNED_INT,						0,	GL_FALSE, vertexData	},
   2299 				};
   2300 
   2301 				for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
   2302 				{
   2303 					glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride, pointers[ndx].pointer);
   2304 					expectError(GL_NO_ERROR);
   2305 
   2306 					verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, pointers[ndx].type);
   2307 				}
   2308 			}
   2309 		}
   2310 
   2311 		// Test with multiple VAOs
   2312 		{
   2313 			const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
   2314 
   2315 			GLuint buf		= 0;
   2316 			GLuint vaos[2]	= {0};
   2317 
   2318 			glGenVertexArrays(2, vaos);
   2319 			glGenBuffers(1, &buf);
   2320 			glBindBuffer(GL_ARRAY_BUFFER, buf);
   2321 			expectError(GL_NO_ERROR);
   2322 
   2323 			// initial
   2324 			glBindVertexArray(vaos[0]);
   2325 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_FLOAT);
   2326 			expectError(GL_NO_ERROR);
   2327 
   2328 			// set vao 0 to some value
   2329 			glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, DE_NULL);
   2330 			expectError(GL_NO_ERROR);
   2331 
   2332 			// set vao 1 to some other value
   2333 			glBindVertexArray(vaos[1]);
   2334 			glVertexAttribPointer(0, 1, GL_SHORT, GL_FALSE, 0, DE_NULL);
   2335 			expectError(GL_NO_ERROR);
   2336 
   2337 			// verify vao 1 state
   2338 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_SHORT);
   2339 			expectError(GL_NO_ERROR);
   2340 
   2341 			// verify vao 0 state
   2342 			glBindVertexArray(vaos[0]);
   2343 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_FLOAT);
   2344 			expectError(GL_NO_ERROR);
   2345 
   2346 			glDeleteVertexArrays(2, vaos);
   2347 			glDeleteBuffers(1, &buf);
   2348 			expectError(GL_NO_ERROR);
   2349 		}
   2350 	}
   2351 };
   2352 
   2353 class VertexAttributeStrideCase : public ApiCase
   2354 {
   2355 public:
   2356 	VertexAttributeStrideCase (Context& context, const char* name, const char* description)
   2357 		: ApiCase(context, name, description)
   2358 	{
   2359 	}
   2360 
   2361 	void test (void)
   2362 	{
   2363 		// Test with default VAO
   2364 		{
   2365 			const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
   2366 
   2367 			const GLfloat vertexData[4] = {0.0f}; // never accessed
   2368 
   2369 			struct StridePointerData
   2370 			{
   2371 				GLint		size;
   2372 				GLenum		type;
   2373 				GLint		stride;
   2374 				const void*	pointer;
   2375 			};
   2376 
   2377 			// test VertexAttribPointer
   2378 			{
   2379 				const StridePointerData pointers[] =
   2380 				{
   2381 					{ 1, GL_FLOAT,			0,	vertexData },
   2382 					{ 1, GL_FLOAT,			1,	vertexData },
   2383 					{ 1, GL_FLOAT,			4,	vertexData },
   2384 					{ 1, GL_HALF_FLOAT,		0,	vertexData },
   2385 					{ 1, GL_HALF_FLOAT,		1,	vertexData },
   2386 					{ 1, GL_HALF_FLOAT,		4,	vertexData },
   2387 					{ 1, GL_FIXED,			0,	vertexData },
   2388 					{ 1, GL_FIXED,			1,	vertexData },
   2389 					{ 1, GL_FIXED,			4,	vertexData },
   2390 				};
   2391 
   2392 				for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
   2393 				{
   2394 					glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, GL_FALSE, pointers[ndx].stride, pointers[ndx].pointer);
   2395 					expectError(GL_NO_ERROR);
   2396 
   2397 					verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, pointers[ndx].stride);
   2398 				}
   2399 			}
   2400 
   2401 			// test glVertexAttribIPointer
   2402 			{
   2403 				const StridePointerData pointers[] =
   2404 				{
   2405 					{ 1, GL_INT,				0,	vertexData },
   2406 					{ 1, GL_INT,				1,	vertexData },
   2407 					{ 1, GL_INT,				4,	vertexData },
   2408 					{ 4, GL_UNSIGNED_BYTE,		0,	vertexData },
   2409 					{ 4, GL_UNSIGNED_BYTE,		1,	vertexData },
   2410 					{ 4, GL_UNSIGNED_BYTE,		4,	vertexData },
   2411 					{ 2, GL_SHORT,				0,	vertexData },
   2412 					{ 2, GL_SHORT,				1,	vertexData },
   2413 					{ 2, GL_SHORT,				4,	vertexData },
   2414 				};
   2415 
   2416 				for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
   2417 				{
   2418 					glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride, pointers[ndx].pointer);
   2419 					expectError(GL_NO_ERROR);
   2420 
   2421 					verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, pointers[ndx].stride);
   2422 				}
   2423 			}
   2424 		}
   2425 
   2426 		// Test with multiple VAOs
   2427 		{
   2428 			const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
   2429 
   2430 			GLuint buf		= 0;
   2431 			GLuint vaos[2]	= {0};
   2432 
   2433 			glGenVertexArrays(2, vaos);
   2434 			glGenBuffers(1, &buf);
   2435 			glBindBuffer(GL_ARRAY_BUFFER, buf);
   2436 			expectError(GL_NO_ERROR);
   2437 
   2438 			// initial
   2439 			glBindVertexArray(vaos[0]);
   2440 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, 0);
   2441 			expectError(GL_NO_ERROR);
   2442 
   2443 			// set vao 0 to some value
   2444 			glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 4, DE_NULL);
   2445 			expectError(GL_NO_ERROR);
   2446 
   2447 			// set vao 1 to some other value
   2448 			glBindVertexArray(vaos[1]);
   2449 			glVertexAttribPointer(0, 1, GL_SHORT, GL_FALSE, 8, DE_NULL);
   2450 			expectError(GL_NO_ERROR);
   2451 
   2452 			// verify vao 1 state
   2453 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, 8);
   2454 			expectError(GL_NO_ERROR);
   2455 
   2456 			// verify vao 0 state
   2457 			glBindVertexArray(vaos[0]);
   2458 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, 4);
   2459 			expectError(GL_NO_ERROR);
   2460 
   2461 			glDeleteVertexArrays(2, vaos);
   2462 			glDeleteBuffers(1, &buf);
   2463 			expectError(GL_NO_ERROR);
   2464 		}
   2465 	}
   2466 };
   2467 
   2468 class VertexAttributeNormalizedCase : public ApiCase
   2469 {
   2470 public:
   2471 	VertexAttributeNormalizedCase (Context& context, const char* name, const char* description)
   2472 		: ApiCase(context, name, description)
   2473 	{
   2474 	}
   2475 
   2476 	void test (void)
   2477 	{
   2478 		// Test with default VAO
   2479 		{
   2480 			const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
   2481 
   2482 			const GLfloat vertexData[4] = {0.0f}; // never accessed
   2483 
   2484 			// test VertexAttribPointer
   2485 			{
   2486 				const PointerData pointers[] =
   2487 				{
   2488 					{ 1, GL_BYTE,								0,	GL_FALSE,	vertexData	},
   2489 					{ 1, GL_SHORT,								0,	GL_FALSE,	vertexData	},
   2490 					{ 1, GL_INT,								0,	GL_FALSE,	vertexData	},
   2491 					{ 1, GL_UNSIGNED_BYTE,						0,	GL_FALSE,	vertexData	},
   2492 					{ 1, GL_UNSIGNED_SHORT,						0,	GL_FALSE,	vertexData	},
   2493 					{ 1, GL_UNSIGNED_INT,						0,	GL_FALSE,	vertexData	},
   2494 					{ 4, GL_INT_2_10_10_10_REV,					0,	GL_FALSE,	vertexData	},
   2495 					{ 4, GL_UNSIGNED_INT_2_10_10_10_REV,		0,	GL_FALSE,	vertexData	},
   2496 					{ 1, GL_BYTE,								0,	GL_TRUE,	vertexData	},
   2497 					{ 1, GL_SHORT,								0,	GL_TRUE,	vertexData	},
   2498 					{ 1, GL_INT,								0,	GL_TRUE,	vertexData	},
   2499 					{ 1, GL_UNSIGNED_BYTE,						0,	GL_TRUE,	vertexData	},
   2500 					{ 1, GL_UNSIGNED_SHORT,						0,	GL_TRUE,	vertexData	},
   2501 					{ 1, GL_UNSIGNED_INT,						0,	GL_TRUE,	vertexData	},
   2502 					{ 4, GL_INT_2_10_10_10_REV,					0,	GL_TRUE,	vertexData	},
   2503 					{ 4, GL_UNSIGNED_INT_2_10_10_10_REV,		0,	GL_TRUE,	vertexData	},
   2504 				};
   2505 
   2506 				for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
   2507 				{
   2508 					glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
   2509 					expectError(GL_NO_ERROR);
   2510 
   2511 					verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, pointers[ndx].normalized);
   2512 				}
   2513 			}
   2514 
   2515 			// test glVertexAttribIPointer
   2516 			{
   2517 				const PointerData pointers[] =
   2518 				{
   2519 					{ 1, GL_BYTE,				0,	GL_FALSE, vertexData	},
   2520 					{ 1, GL_SHORT,				0,	GL_FALSE, vertexData	},
   2521 					{ 1, GL_INT,				0,	GL_FALSE, vertexData	},
   2522 					{ 1, GL_UNSIGNED_BYTE,		0,	GL_FALSE, vertexData	},
   2523 					{ 1, GL_UNSIGNED_SHORT,		0,	GL_FALSE, vertexData	},
   2524 					{ 1, GL_UNSIGNED_INT,		0,	GL_FALSE, vertexData	},
   2525 				};
   2526 
   2527 				for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
   2528 				{
   2529 					glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride, pointers[ndx].pointer);
   2530 					expectError(GL_NO_ERROR);
   2531 
   2532 					verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_FALSE);
   2533 				}
   2534 			}
   2535 		}
   2536 
   2537 		// Test with multiple VAOs
   2538 		{
   2539 			const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
   2540 
   2541 			GLuint buf		= 0;
   2542 			GLuint vaos[2]	= {0};
   2543 
   2544 			glGenVertexArrays(2, vaos);
   2545 			glGenBuffers(1, &buf);
   2546 			glBindBuffer(GL_ARRAY_BUFFER, buf);
   2547 			expectError(GL_NO_ERROR);
   2548 
   2549 			// initial
   2550 			glBindVertexArray(vaos[0]);
   2551 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_FALSE);
   2552 			expectError(GL_NO_ERROR);
   2553 
   2554 			// set vao 0 to some value
   2555 			glVertexAttribPointer(0, 1, GL_INT, GL_TRUE, 0, DE_NULL);
   2556 			expectError(GL_NO_ERROR);
   2557 
   2558 			// set vao 1 to some other value
   2559 			glBindVertexArray(vaos[1]);
   2560 			glVertexAttribPointer(0, 1, GL_INT, GL_FALSE, 0, DE_NULL);
   2561 			expectError(GL_NO_ERROR);
   2562 
   2563 			// verify vao 1 state
   2564 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_FALSE);
   2565 			expectError(GL_NO_ERROR);
   2566 
   2567 			// verify vao 0 state
   2568 			glBindVertexArray(vaos[0]);
   2569 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_TRUE);
   2570 			expectError(GL_NO_ERROR);
   2571 
   2572 			glDeleteVertexArrays(2, vaos);
   2573 			glDeleteBuffers(1, &buf);
   2574 			expectError(GL_NO_ERROR);
   2575 		}
   2576 	}
   2577 };
   2578 
   2579 class VertexAttributeIntegerCase : public ApiCase
   2580 {
   2581 public:
   2582 	VertexAttributeIntegerCase (Context& context, const char* name, const char* description)
   2583 		: ApiCase(context, name, description)
   2584 	{
   2585 	}
   2586 
   2587 	void test (void)
   2588 	{
   2589 		// Test with default VAO
   2590 		{
   2591 			const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
   2592 
   2593 			const GLfloat vertexData[4] = {0.0f}; // never accessed
   2594 
   2595 			// test VertexAttribPointer
   2596 			{
   2597 				const PointerData pointers[] =
   2598 				{
   2599 					{ 1, GL_BYTE,								0,	GL_FALSE, vertexData	},
   2600 					{ 1, GL_SHORT,								0,	GL_FALSE, vertexData	},
   2601 					{ 1, GL_INT,								0,	GL_FALSE, vertexData	},
   2602 					{ 1, GL_FIXED,								0,	GL_FALSE, vertexData	},
   2603 					{ 1, GL_FLOAT,								0,	GL_FALSE, vertexData	},
   2604 					{ 1, GL_HALF_FLOAT,							0,	GL_FALSE, vertexData	},
   2605 					{ 1, GL_UNSIGNED_BYTE,						0,	GL_FALSE, vertexData	},
   2606 					{ 1, GL_UNSIGNED_SHORT,						0,	GL_FALSE, vertexData	},
   2607 					{ 1, GL_UNSIGNED_INT,						0,	GL_FALSE, vertexData	},
   2608 					{ 4, GL_INT_2_10_10_10_REV,					0,	GL_FALSE, vertexData	},
   2609 					{ 4, GL_UNSIGNED_INT_2_10_10_10_REV,		0,	GL_FALSE, vertexData	},
   2610 				};
   2611 
   2612 				for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
   2613 				{
   2614 					glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
   2615 					expectError(GL_NO_ERROR);
   2616 
   2617 					verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FALSE);
   2618 				}
   2619 			}
   2620 
   2621 			// test glVertexAttribIPointer
   2622 			{
   2623 				const PointerData pointers[] =
   2624 				{
   2625 					{ 1, GL_BYTE,								0,	GL_FALSE, vertexData	},
   2626 					{ 1, GL_SHORT,								0,	GL_FALSE, vertexData	},
   2627 					{ 1, GL_INT,								0,	GL_FALSE, vertexData	},
   2628 					{ 1, GL_UNSIGNED_BYTE,						0,	GL_FALSE, vertexData	},
   2629 					{ 1, GL_UNSIGNED_SHORT,						0,	GL_FALSE, vertexData	},
   2630 					{ 1, GL_UNSIGNED_INT,						0,	GL_FALSE, vertexData	},
   2631 				};
   2632 
   2633 				for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
   2634 				{
   2635 					glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride, pointers[ndx].pointer);
   2636 					expectError(GL_NO_ERROR);
   2637 
   2638 					verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_TRUE);
   2639 				}
   2640 			}
   2641 		}
   2642 
   2643 		// Test with multiple VAOs
   2644 		{
   2645 			const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
   2646 
   2647 			GLuint buf		= 0;
   2648 			GLuint vaos[2]	= {0};
   2649 
   2650 			glGenVertexArrays(2, vaos);
   2651 			glGenBuffers(1, &buf);
   2652 			glBindBuffer(GL_ARRAY_BUFFER, buf);
   2653 			expectError(GL_NO_ERROR);
   2654 
   2655 			// initial
   2656 			glBindVertexArray(vaos[0]);
   2657 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FALSE);
   2658 			expectError(GL_NO_ERROR);
   2659 
   2660 			// set vao 0 to some value
   2661 			glVertexAttribIPointer(0, 1, GL_INT, 0, DE_NULL);
   2662 			expectError(GL_NO_ERROR);
   2663 
   2664 			// set vao 1 to some other value
   2665 			glBindVertexArray(vaos[1]);
   2666 			glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, DE_NULL);
   2667 			expectError(GL_NO_ERROR);
   2668 
   2669 			// verify vao 1 state
   2670 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FALSE);
   2671 			expectError(GL_NO_ERROR);
   2672 
   2673 			// verify vao 0 state
   2674 			glBindVertexArray(vaos[0]);
   2675 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_TRUE);
   2676 			expectError(GL_NO_ERROR);
   2677 
   2678 			glDeleteVertexArrays(2, vaos);
   2679 			glDeleteBuffers(1, &buf);
   2680 			expectError(GL_NO_ERROR);
   2681 		}
   2682 	}
   2683 };
   2684 
   2685 class VertexAttributeEnabledCase : public ApiCase
   2686 {
   2687 public:
   2688 	VertexAttributeEnabledCase (Context& context, const char* name, const char* description)
   2689 		: ApiCase(context, name, description)
   2690 	{
   2691 	}
   2692 
   2693 	void test (void)
   2694 	{
   2695 		// VERTEX_ATTRIB_ARRAY_ENABLED
   2696 
   2697 		// Test with default VAO
   2698 		{
   2699 			const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
   2700 
   2701 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
   2702 			glEnableVertexAttribArray(0);
   2703 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_TRUE);
   2704 			glDisableVertexAttribArray(0);
   2705 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
   2706 		}
   2707 
   2708 		// Test with multiple VAOs
   2709 		{
   2710 			const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
   2711 
   2712 			GLuint vaos[2] = {0};
   2713 
   2714 			glGenVertexArrays(2, vaos);
   2715 			expectError(GL_NO_ERROR);
   2716 
   2717 			// set vao 0 to some value
   2718 			glBindVertexArray(vaos[0]);
   2719 			glEnableVertexAttribArray(0);
   2720 			expectError(GL_NO_ERROR);
   2721 
   2722 			// set vao 1 to some other value
   2723 			glBindVertexArray(vaos[1]);
   2724 			glDisableVertexAttribArray(0);
   2725 			expectError(GL_NO_ERROR);
   2726 
   2727 			// verify vao 1 state
   2728 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
   2729 			expectError(GL_NO_ERROR);
   2730 
   2731 			// verify vao 0 state
   2732 			glBindVertexArray(vaos[0]);
   2733 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_TRUE);
   2734 			expectError(GL_NO_ERROR);
   2735 
   2736 			glDeleteVertexArrays(2, vaos);
   2737 			expectError(GL_NO_ERROR);
   2738 		}
   2739 	}
   2740 };
   2741 
   2742 class VertexAttributeDivisorCase : public ApiCase
   2743 {
   2744 public:
   2745 	VertexAttributeDivisorCase (Context& context, const char* name, const char* description)
   2746 		: ApiCase(context, name, description)
   2747 	{
   2748 	}
   2749 
   2750 	void test (void)
   2751 	{
   2752 		// Test with default VAO
   2753 		{
   2754 			const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
   2755 
   2756 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR,	0);
   2757 			glVertexAttribDivisor(0, 1);
   2758 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR,	1);
   2759 			glVertexAttribDivisor(0, 5);
   2760 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR,	5);
   2761 		}
   2762 
   2763 		// Test with multiple VAOs
   2764 		{
   2765 			const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
   2766 
   2767 			GLuint vaos[2] = {0};
   2768 
   2769 			glGenVertexArrays(2, vaos);
   2770 			expectError(GL_NO_ERROR);
   2771 
   2772 			// set vao 0 to some value
   2773 			glBindVertexArray(vaos[0]);
   2774 			glVertexAttribDivisor(0, 1);
   2775 			expectError(GL_NO_ERROR);
   2776 
   2777 			// set vao 1 to some other value
   2778 			glBindVertexArray(vaos[1]);
   2779 			glVertexAttribDivisor(0, 5);
   2780 			expectError(GL_NO_ERROR);
   2781 
   2782 			// verify vao 1 state
   2783 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 5);
   2784 			expectError(GL_NO_ERROR);
   2785 
   2786 			// verify vao 0 state
   2787 			glBindVertexArray(vaos[0]);
   2788 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 1);
   2789 			expectError(GL_NO_ERROR);
   2790 
   2791 			glDeleteVertexArrays(2, vaos);
   2792 			expectError(GL_NO_ERROR);
   2793 		}
   2794 	}
   2795 };
   2796 
   2797 class VertexAttributeBufferBindingCase : public ApiCase
   2798 {
   2799 public:
   2800 	VertexAttributeBufferBindingCase (Context& context, const char* name, const char* description)
   2801 		: ApiCase(context, name, description)
   2802 	{
   2803 	}
   2804 
   2805 	void test (void)
   2806 	{
   2807 		// Test with default VAO
   2808 		{
   2809 			const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
   2810 
   2811 			// initial
   2812 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, 0);
   2813 
   2814 			GLuint bufferID;
   2815 			glGenBuffers(1, &bufferID);
   2816 			glBindBuffer(GL_ARRAY_BUFFER, bufferID);
   2817 			expectError(GL_NO_ERROR);
   2818 
   2819 			glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
   2820 			expectError(GL_NO_ERROR);
   2821 
   2822 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufferID);
   2823 
   2824 			glDeleteBuffers(1, &bufferID);
   2825 			expectError(GL_NO_ERROR);
   2826 		}
   2827 
   2828 		// Test with multiple VAOs
   2829 		{
   2830 			const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
   2831 
   2832 			GLuint vaos[2] = {0};
   2833 			GLuint bufs[2] = {0};
   2834 
   2835 			glGenBuffers(2, bufs);
   2836 			expectError(GL_NO_ERROR);
   2837 
   2838 			glGenVertexArrays(2, vaos);
   2839 			expectError(GL_NO_ERROR);
   2840 
   2841 			// set vao 0 to some value
   2842 			glBindVertexArray(vaos[0]);
   2843 			glBindBuffer(GL_ARRAY_BUFFER, bufs[0]);
   2844 			glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
   2845 			expectError(GL_NO_ERROR);
   2846 
   2847 			// set vao 1 to some other value
   2848 			glBindVertexArray(vaos[1]);
   2849 			glBindBuffer(GL_ARRAY_BUFFER, bufs[1]);
   2850 			glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
   2851 			expectError(GL_NO_ERROR);
   2852 
   2853 			// verify vao 1 state
   2854 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufs[1]);
   2855 			expectError(GL_NO_ERROR);
   2856 
   2857 			// verify vao 0 state
   2858 			glBindVertexArray(vaos[0]);
   2859 			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufs[0]);
   2860 			expectError(GL_NO_ERROR);
   2861 
   2862 			glDeleteVertexArrays(2, vaos);
   2863 			glDeleteBuffers(2, bufs);
   2864 			expectError(GL_NO_ERROR);
   2865 		}
   2866 	}
   2867 };
   2868 
   2869 class VertexAttributePointerCase : public ApiCase
   2870 {
   2871 public:
   2872 	VertexAttributePointerCase (Context& context, const char* name, const char* description)
   2873 		: ApiCase(context, name, description)
   2874 	{
   2875 	}
   2876 
   2877 	void test (void)
   2878 	{
   2879 		// Test with default VAO
   2880 		{
   2881 			const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
   2882 
   2883 			StateQueryMemoryWriteGuard<GLvoid*> initialState;
   2884 			glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &initialState);
   2885 			initialState.verifyValidity(m_testCtx);
   2886 			checkPointerEquals(m_testCtx, initialState, 0);
   2887 
   2888 			const GLfloat vertexData[4] = {0.0f}; // never accessed
   2889 			const PointerData pointers[] =
   2890 			{
   2891 				{ 1, GL_BYTE,				0,	GL_FALSE, &vertexData[2] },
   2892 				{ 1, GL_SHORT,				0,	GL_FALSE, &vertexData[1] },
   2893 				{ 1, GL_INT,				0,	GL_FALSE, &vertexData[2] },
   2894 				{ 1, GL_FIXED,				0,	GL_FALSE, &vertexData[2] },
   2895 				{ 1, GL_FIXED,				0,	GL_FALSE, &vertexData[1] },
   2896 				{ 1, GL_FLOAT,				0,	GL_FALSE, &vertexData[0] },
   2897 				{ 1, GL_FLOAT,				0,	GL_FALSE, &vertexData[3] },
   2898 				{ 1, GL_FLOAT,				0,	GL_FALSE, &vertexData[2] },
   2899 				{ 1, GL_HALF_FLOAT,			0,	GL_FALSE, &vertexData[0] },
   2900 				{ 4, GL_HALF_FLOAT,			0,	GL_FALSE, &vertexData[1] },
   2901 				{ 4, GL_HALF_FLOAT,			0,	GL_FALSE, &vertexData[2] },
   2902 			};
   2903 
   2904 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
   2905 			{
   2906 				glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
   2907 				expectError(GL_NO_ERROR);
   2908 
   2909 				StateQueryMemoryWriteGuard<GLvoid*> state;
   2910 				glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state);
   2911 				state.verifyValidity(m_testCtx);
   2912 				checkPointerEquals(m_testCtx, state, pointers[ndx].pointer);
   2913 			}
   2914 		}
   2915 
   2916 		// Test with multiple VAOs
   2917 		{
   2918 			const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
   2919 
   2920 			GLuint vaos[2] = {0};
   2921 			GLuint bufs[2] = {0};
   2922 
   2923 			glGenBuffers(2, bufs);
   2924 			expectError(GL_NO_ERROR);
   2925 
   2926 			glGenVertexArrays(2, vaos);
   2927 			expectError(GL_NO_ERROR);
   2928 
   2929 			// set vao 0 to some value
   2930 			glBindVertexArray(vaos[0]);
   2931 			glBindBuffer(GL_ARRAY_BUFFER, bufs[0]);
   2932 			glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, ((deUint8*)DE_NULL) + 8);
   2933 			expectError(GL_NO_ERROR);
   2934 
   2935 			// set vao 1 to some other value
   2936 			glBindVertexArray(vaos[1]);
   2937 			glBindBuffer(GL_ARRAY_BUFFER, bufs[1]);
   2938 			glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, ((deUint8*)DE_NULL) + 4);
   2939 			expectError(GL_NO_ERROR);
   2940 
   2941 			// verify vao 1 state
   2942 			{
   2943 				StateQueryMemoryWriteGuard<GLvoid*> state;
   2944 				glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state);
   2945 				state.verifyValidity(m_testCtx);
   2946 				checkPointerEquals(m_testCtx, state, ((deUint8*)DE_NULL) + 4);
   2947 			}
   2948 			expectError(GL_NO_ERROR);
   2949 
   2950 			// verify vao 0 state
   2951 			glBindVertexArray(vaos[0]);
   2952 			{
   2953 				StateQueryMemoryWriteGuard<GLvoid*> state;
   2954 				glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state);
   2955 				state.verifyValidity(m_testCtx);
   2956 				checkPointerEquals(m_testCtx, state, ((deUint8*)DE_NULL) + 8);
   2957 			}
   2958 			expectError(GL_NO_ERROR);
   2959 
   2960 			glDeleteVertexArrays(2, vaos);
   2961 			glDeleteBuffers(2, bufs);
   2962 			expectError(GL_NO_ERROR);
   2963 		}
   2964 	}
   2965 };
   2966 
   2967 class UniformValueFloatCase : public ApiCase
   2968 {
   2969 public:
   2970 	UniformValueFloatCase (Context& context, const char* name, const char* description)
   2971 		: ApiCase(context, name, description)
   2972 	{
   2973 	}
   2974 
   2975 	void test (void)
   2976 	{
   2977 		static const char* testVertSource =
   2978 			"#version 300 es\n"
   2979 			"uniform highp float floatUniform;\n"
   2980 			"uniform highp vec2 float2Uniform;\n"
   2981 			"uniform highp vec3 float3Uniform;\n"
   2982 			"uniform highp vec4 float4Uniform;\n"
   2983 			"void main (void)\n"
   2984 			"{\n"
   2985 			"	gl_Position = vec4(floatUniform + float2Uniform.x + float3Uniform.x + float4Uniform.x);\n"
   2986 			"}\n";
   2987 		static const char* testFragSource =
   2988 			"#version 300 es\n"
   2989 			"layout(location = 0) out mediump vec4 fragColor;"
   2990 			"void main (void)\n"
   2991 			"{\n"
   2992 			"	fragColor = vec4(0.0);\n"
   2993 			"}\n";
   2994 
   2995 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   2996 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   2997 
   2998 		glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
   2999 		glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
   3000 
   3001 		glCompileShader(shaderVert);
   3002 		glCompileShader(shaderFrag);
   3003 		expectError(GL_NO_ERROR);
   3004 
   3005 		GLuint program = glCreateProgram();
   3006 		glAttachShader(program, shaderVert);
   3007 		glAttachShader(program, shaderFrag);
   3008 		glLinkProgram(program);
   3009 		glUseProgram(program);
   3010 		expectError(GL_NO_ERROR);
   3011 
   3012 		GLint location;
   3013 
   3014 		location = glGetUniformLocation(program,"floatUniform");
   3015 		glUniform1f(location, 1.0f);
   3016 		verifyUniformValue1f(m_testCtx, *this, program, location, 1.0f);
   3017 
   3018 		location = glGetUniformLocation(program,"float2Uniform");
   3019 		glUniform2f(location, 1.0f, 2.0f);
   3020 		verifyUniformValue2f(m_testCtx, *this, program, location, 1.0f, 2.0f);
   3021 
   3022 		location = glGetUniformLocation(program,"float3Uniform");
   3023 		glUniform3f(location, 1.0f, 2.0f, 3.0f);
   3024 		verifyUniformValue3f(m_testCtx, *this, program, location, 1.0f, 2.0f, 3.0f);
   3025 
   3026 		location = glGetUniformLocation(program,"float4Uniform");
   3027 		glUniform4f(location, 1.0f, 2.0f, 3.0f, 4.0f);
   3028 		verifyUniformValue4f(m_testCtx, *this, program, location, 1.0f, 2.0f, 3.0f, 4.0f);
   3029 
   3030 		glUseProgram(0);
   3031 		glDeleteShader(shaderVert);
   3032 		glDeleteShader(shaderFrag);
   3033 		glDeleteProgram(program);
   3034 		expectError(GL_NO_ERROR);
   3035 	}
   3036 };
   3037 
   3038 class UniformValueIntCase : public ApiCase
   3039 {
   3040 public:
   3041 	UniformValueIntCase (Context& context, const char* name, const char* description)
   3042 		: ApiCase(context, name, description)
   3043 	{
   3044 	}
   3045 
   3046 	void test (void)
   3047 	{
   3048 		static const char* testVertSource =
   3049 			"#version 300 es\n"
   3050 			"uniform highp int intUniform;\n"
   3051 			"uniform highp ivec2 int2Uniform;\n"
   3052 			"uniform highp ivec3 int3Uniform;\n"
   3053 			"uniform highp ivec4 int4Uniform;\n"
   3054 			"void main (void)\n"
   3055 			"{\n"
   3056 			"	gl_Position = vec4(float(intUniform + int2Uniform.x + int3Uniform.x + int4Uniform.x));\n"
   3057 			"}\n";
   3058 		static const char* testFragSource =
   3059 			"#version 300 es\n"
   3060 			"layout(location = 0) out mediump vec4 fragColor;"
   3061 			"void main (void)\n"
   3062 			"{\n"
   3063 			"	fragColor = vec4(0.0);\n"
   3064 			"}\n";
   3065 
   3066 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   3067 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   3068 
   3069 		glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
   3070 		glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
   3071 
   3072 		glCompileShader(shaderVert);
   3073 		glCompileShader(shaderFrag);
   3074 		expectError(GL_NO_ERROR);
   3075 
   3076 		GLuint program = glCreateProgram();
   3077 		glAttachShader(program, shaderVert);
   3078 		glAttachShader(program, shaderFrag);
   3079 		glLinkProgram(program);
   3080 		glUseProgram(program);
   3081 		expectError(GL_NO_ERROR);
   3082 
   3083 		GLint location;
   3084 
   3085 		location = glGetUniformLocation(program,"intUniform");
   3086 		glUniform1i(location, 1);
   3087 		verifyUniformValue1i(m_testCtx, *this, program, location, 1);
   3088 
   3089 		location = glGetUniformLocation(program,"int2Uniform");
   3090 		glUniform2i(location, 1, 2);
   3091 		verifyUniformValue2i(m_testCtx, *this, program, location, 1, 2);
   3092 
   3093 		location = glGetUniformLocation(program,"int3Uniform");
   3094 		glUniform3i(location, 1, 2, 3);
   3095 		verifyUniformValue3i(m_testCtx, *this, program, location, 1, 2, 3);
   3096 
   3097 		location = glGetUniformLocation(program,"int4Uniform");
   3098 		glUniform4i(location, 1, 2, 3, 4);
   3099 		verifyUniformValue4i(m_testCtx, *this, program, location, 1, 2, 3, 4);
   3100 
   3101 		glUseProgram(0);
   3102 		glDeleteShader(shaderVert);
   3103 		glDeleteShader(shaderFrag);
   3104 		glDeleteProgram(program);
   3105 		expectError(GL_NO_ERROR);
   3106 	}
   3107 };
   3108 
   3109 class UniformValueUintCase : public ApiCase
   3110 {
   3111 public:
   3112 	UniformValueUintCase (Context& context, const char* name, const char* description)
   3113 		: ApiCase(context, name, description)
   3114 	{
   3115 	}
   3116 
   3117 	void test (void)
   3118 	{
   3119 		static const char* testVertSource =
   3120 			"#version 300 es\n"
   3121 			"uniform highp uint uintUniform;\n"
   3122 			"uniform highp uvec2 uint2Uniform;\n"
   3123 			"uniform highp uvec3 uint3Uniform;\n"
   3124 			"uniform highp uvec4 uint4Uniform;\n"
   3125 			"void main (void)\n"
   3126 			"{\n"
   3127 			"	gl_Position = vec4(float(uintUniform + uint2Uniform.x + uint3Uniform.x + uint4Uniform.x));\n"
   3128 			"}\n";
   3129 		static const char* testFragSource =
   3130 			"#version 300 es\n"
   3131 			"layout(location = 0) out mediump vec4 fragColor;"
   3132 			"void main (void)\n"
   3133 			"{\n"
   3134 			"	fragColor = vec4(0.0);\n"
   3135 			"}\n";
   3136 
   3137 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   3138 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   3139 
   3140 		glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
   3141 		glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
   3142 
   3143 		glCompileShader(shaderVert);
   3144 		glCompileShader(shaderFrag);
   3145 		expectError(GL_NO_ERROR);
   3146 
   3147 		GLuint program = glCreateProgram();
   3148 		glAttachShader(program, shaderVert);
   3149 		glAttachShader(program, shaderFrag);
   3150 		glLinkProgram(program);
   3151 		glUseProgram(program);
   3152 		expectError(GL_NO_ERROR);
   3153 
   3154 		GLint location;
   3155 
   3156 		location = glGetUniformLocation(program,"uintUniform");
   3157 		glUniform1ui(location, 1);
   3158 		verifyUniformValue1ui(m_testCtx, *this, program, location, 1);
   3159 
   3160 		location = glGetUniformLocation(program,"uint2Uniform");
   3161 		glUniform2ui(location, 1, 2);
   3162 		verifyUniformValue2ui(m_testCtx, *this, program, location, 1, 2);
   3163 
   3164 		location = glGetUniformLocation(program,"uint3Uniform");
   3165 		glUniform3ui(location, 1, 2, 3);
   3166 		verifyUniformValue3ui(m_testCtx, *this, program, location, 1, 2, 3);
   3167 
   3168 		location = glGetUniformLocation(program,"uint4Uniform");
   3169 		glUniform4ui(location, 1, 2, 3, 4);
   3170 		verifyUniformValue4ui(m_testCtx, *this, program, location, 1, 2, 3, 4);
   3171 
   3172 		glUseProgram(0);
   3173 		glDeleteShader(shaderVert);
   3174 		glDeleteShader(shaderFrag);
   3175 		glDeleteProgram(program);
   3176 		expectError(GL_NO_ERROR);
   3177 	}
   3178 };
   3179 
   3180 
   3181 class UniformValueBooleanCase : public ApiCase
   3182 {
   3183 public:
   3184 	UniformValueBooleanCase (Context& context, const char* name, const char* description)
   3185 		: ApiCase(context, name, description)
   3186 	{
   3187 	}
   3188 
   3189 	void test (void)
   3190 	{
   3191 		static const char* testVertSource =
   3192 			"#version 300 es\n"
   3193 			"uniform bool boolUniform;\n"
   3194 			"uniform bvec2 bool2Uniform;\n"
   3195 			"uniform bvec3 bool3Uniform;\n"
   3196 			"uniform bvec4 bool4Uniform;\n"
   3197 			"void main (void)\n"
   3198 			"{\n"
   3199 			"	gl_Position = vec4(float(boolUniform) + float(bool2Uniform.x) + float(bool3Uniform.x) + float(bool4Uniform.x));\n"
   3200 			"}\n";
   3201 		static const char* testFragSource =
   3202 			"#version 300 es\n"
   3203 			"layout(location = 0) out mediump vec4 fragColor;"
   3204 			"void main (void)\n"
   3205 			"{\n"
   3206 			"	fragColor = vec4(0.0);\n"
   3207 			"}\n";
   3208 
   3209 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   3210 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   3211 
   3212 		glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
   3213 		glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
   3214 
   3215 		glCompileShader(shaderVert);
   3216 		glCompileShader(shaderFrag);
   3217 		expectError(GL_NO_ERROR);
   3218 
   3219 		GLuint program = glCreateProgram();
   3220 		glAttachShader(program, shaderVert);
   3221 		glAttachShader(program, shaderFrag);
   3222 		glLinkProgram(program);
   3223 		glUseProgram(program);
   3224 		expectError(GL_NO_ERROR);
   3225 
   3226 		GLint location;
   3227 
   3228 		// int conversion
   3229 
   3230 		location = glGetUniformLocation(program,"boolUniform");
   3231 		glUniform1i(location, 1);
   3232 		verifyUniformValue1i(m_testCtx, *this, program, location, 1);
   3233 
   3234 		location = glGetUniformLocation(program,"bool2Uniform");
   3235 		glUniform2i(location, 1, 2);
   3236 		verifyUniformValue2i(m_testCtx, *this, program, location, 1, 1);
   3237 
   3238 		location = glGetUniformLocation(program,"bool3Uniform");
   3239 		glUniform3i(location, 0, 1, 2);
   3240 		verifyUniformValue3i(m_testCtx, *this, program, location, 0, 1, 1);
   3241 
   3242 		location = glGetUniformLocation(program,"bool4Uniform");
   3243 		glUniform4i(location, 1, 0, 1, -1);
   3244 		verifyUniformValue4i(m_testCtx, *this, program, location, 1, 0, 1, 1);
   3245 
   3246 		// float conversion
   3247 
   3248 		location = glGetUniformLocation(program,"boolUniform");
   3249 		glUniform1f(location, 1.0f);
   3250 		verifyUniformValue1i(m_testCtx, *this, program, location, 1);
   3251 
   3252 		location = glGetUniformLocation(program,"bool2Uniform");
   3253 		glUniform2f(location, 1.0f, 0.1f);
   3254 		verifyUniformValue2i(m_testCtx, *this, program, location, 1, 1);
   3255 
   3256 		location = glGetUniformLocation(program,"bool3Uniform");
   3257 		glUniform3f(location, 0.0f, 0.1f, -0.1f);
   3258 		verifyUniformValue3i(m_testCtx, *this, program, location, 0, 1, 1);
   3259 
   3260 		location = glGetUniformLocation(program,"bool4Uniform");
   3261 		glUniform4f(location, 1.0f, 0.0f, 0.1f, -0.9f);
   3262 		verifyUniformValue4i(m_testCtx, *this, program, location, 1, 0, 1, 1);
   3263 
   3264 		glUseProgram(0);
   3265 		glDeleteShader(shaderVert);
   3266 		glDeleteShader(shaderFrag);
   3267 		glDeleteProgram(program);
   3268 		expectError(GL_NO_ERROR);
   3269 	}
   3270 };
   3271 
   3272 class UniformValueSamplerCase : public ApiCase
   3273 {
   3274 public:
   3275 	UniformValueSamplerCase (Context& context, const char* name, const char* description)
   3276 		: ApiCase(context, name, description)
   3277 	{
   3278 	}
   3279 
   3280 	void test (void)
   3281 	{
   3282 		static const char* testVertSource =
   3283 			"#version 300 es\n"
   3284 			"void main (void)\n"
   3285 			"{\n"
   3286 			"	gl_Position = vec4(0.0);\n"
   3287 			"}\n";
   3288 		static const char* testFragSource =
   3289 			"#version 300 es\n"
   3290 			"uniform highp sampler2D uniformSampler;\n"
   3291 			"layout(location = 0) out mediump vec4 fragColor;"
   3292 			"void main (void)\n"
   3293 			"{\n"
   3294 			"	fragColor = vec4(textureSize(uniformSampler, 0).x);\n"
   3295 			"}\n";
   3296 
   3297 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   3298 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   3299 
   3300 		glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
   3301 		glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
   3302 
   3303 		glCompileShader(shaderVert);
   3304 		glCompileShader(shaderFrag);
   3305 		expectError(GL_NO_ERROR);
   3306 
   3307 		GLuint program = glCreateProgram();
   3308 		glAttachShader(program, shaderVert);
   3309 		glAttachShader(program, shaderFrag);
   3310 		glLinkProgram(program);
   3311 		glUseProgram(program);
   3312 		expectError(GL_NO_ERROR);
   3313 
   3314 		GLint location;
   3315 
   3316 		location = glGetUniformLocation(program,"uniformSampler");
   3317 		glUniform1i(location, 1);
   3318 		verifyUniformValue1i(m_testCtx, *this, program, location, 1);
   3319 
   3320 		glUseProgram(0);
   3321 		glDeleteShader(shaderVert);
   3322 		glDeleteShader(shaderFrag);
   3323 		glDeleteProgram(program);
   3324 		expectError(GL_NO_ERROR);
   3325 	}
   3326 };
   3327 
   3328 class UniformValueArrayCase : public ApiCase
   3329 {
   3330 public:
   3331 	UniformValueArrayCase (Context& context, const char* name, const char* description)
   3332 		: ApiCase(context, name, description)
   3333 	{
   3334 	}
   3335 
   3336 	void test (void)
   3337 	{
   3338 		static const char* testVertSource =
   3339 			"#version 300 es\n"
   3340 			"uniform highp float arrayUniform[5];"
   3341 			"uniform highp vec2 array2Uniform[5];"
   3342 			"uniform highp vec3 array3Uniform[5];"
   3343 			"uniform highp vec4 array4Uniform[5];"
   3344 			"void main (void)\n"
   3345 			"{\n"
   3346 			"	gl_Position = \n"
   3347 			"		+ vec4(arrayUniform[0]		+ arrayUniform[1]		+ arrayUniform[2]		+ arrayUniform[3]		+ arrayUniform[4])\n"
   3348 			"		+ vec4(array2Uniform[0].x	+ array2Uniform[1].x	+ array2Uniform[2].x	+ array2Uniform[3].x	+ array2Uniform[4].x)\n"
   3349 			"		+ vec4(array3Uniform[0].x	+ array3Uniform[1].x	+ array3Uniform[2].x	+ array3Uniform[3].x	+ array3Uniform[4].x)\n"
   3350 			"		+ vec4(array4Uniform[0].x	+ array4Uniform[1].x	+ array4Uniform[2].x	+ array4Uniform[3].x	+ array4Uniform[4].x);\n"
   3351 			"}\n";
   3352 		static const char* testFragSource =
   3353 			"#version 300 es\n"
   3354 			"layout(location = 0) out mediump vec4 fragColor;"
   3355 			"void main (void)\n"
   3356 			"{\n"
   3357 			"	fragColor = vec4(0.0);\n"
   3358 			"}\n";
   3359 
   3360 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   3361 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   3362 
   3363 		glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
   3364 		glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
   3365 
   3366 		glCompileShader(shaderVert);
   3367 		glCompileShader(shaderFrag);
   3368 		expectError(GL_NO_ERROR);
   3369 
   3370 		GLuint program = glCreateProgram();
   3371 		glAttachShader(program, shaderVert);
   3372 		glAttachShader(program, shaderFrag);
   3373 		glLinkProgram(program);
   3374 		glUseProgram(program);
   3375 		expectError(GL_NO_ERROR);
   3376 
   3377 		GLint location;
   3378 
   3379 		float uniformValue[5 * 4] =
   3380 		{
   3381 			-1.0f,	0.1f,	4.0f,	800.0f,
   3382 			13.0f,	55.0f,	12.0f,	91.0f,
   3383 			-55.1f,	1.1f,	98.0f,	19.0f,
   3384 			41.0f,	65.0f,	4.0f,	12.2f,
   3385 			95.0f,	77.0f,	32.0f,	48.0f
   3386 		};
   3387 
   3388 		location = glGetUniformLocation(program,"arrayUniform");
   3389 		glUniform1fv(location, 5, uniformValue);
   3390 		expectError(GL_NO_ERROR);
   3391 
   3392 		verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[0]"), uniformValue[0]);
   3393 		verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[1]"), uniformValue[1]);
   3394 		verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[2]"), uniformValue[2]);
   3395 		verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[3]"), uniformValue[3]);
   3396 		verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[4]"), uniformValue[4]);
   3397 		expectError(GL_NO_ERROR);
   3398 
   3399 		location = glGetUniformLocation(program,"array2Uniform");
   3400 		glUniform2fv(location, 5, uniformValue);
   3401 		expectError(GL_NO_ERROR);
   3402 
   3403 		verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[0]"), uniformValue[2 * 0], uniformValue[(2 * 0) + 1]);
   3404 		verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[1]"), uniformValue[2 * 1], uniformValue[(2 * 1) + 1]);
   3405 		verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[2]"), uniformValue[2 * 2], uniformValue[(2 * 2) + 1]);
   3406 		verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[3]"), uniformValue[2 * 3], uniformValue[(2 * 3) + 1]);
   3407 		verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[4]"), uniformValue[2 * 4], uniformValue[(2 * 4) + 1]);
   3408 		expectError(GL_NO_ERROR);
   3409 
   3410 		location = glGetUniformLocation(program,"array3Uniform");
   3411 		glUniform3fv(location, 5, uniformValue);
   3412 		expectError(GL_NO_ERROR);
   3413 
   3414 		verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[0]"), uniformValue[3 * 0], uniformValue[(3 * 0) + 1], uniformValue[(3 * 0) + 2]);
   3415 		verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[1]"), uniformValue[3 * 1], uniformValue[(3 * 1) + 1], uniformValue[(3 * 1) + 2]);
   3416 		verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[2]"), uniformValue[3 * 2], uniformValue[(3 * 2) + 1], uniformValue[(3 * 2) + 2]);
   3417 		verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[3]"), uniformValue[3 * 3], uniformValue[(3 * 3) + 1], uniformValue[(3 * 3) + 2]);
   3418 		verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[4]"), uniformValue[3 * 4], uniformValue[(3 * 4) + 1], uniformValue[(3 * 4) + 2]);
   3419 		expectError(GL_NO_ERROR);
   3420 
   3421 		location = glGetUniformLocation(program,"array4Uniform");
   3422 		glUniform4fv(location, 5, uniformValue);
   3423 		expectError(GL_NO_ERROR);
   3424 
   3425 		verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[0]"), uniformValue[4 * 0], uniformValue[(4 * 0) + 1], uniformValue[(4 * 0) + 2], uniformValue[(4 * 0) + 3]);
   3426 		verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[1]"), uniformValue[4 * 1], uniformValue[(4 * 1) + 1], uniformValue[(4 * 1) + 2], uniformValue[(4 * 1) + 3]);
   3427 		verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[2]"), uniformValue[4 * 2], uniformValue[(4 * 2) + 1], uniformValue[(4 * 2) + 2], uniformValue[(4 * 2) + 3]);
   3428 		verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[3]"), uniformValue[4 * 3], uniformValue[(4 * 3) + 1], uniformValue[(4 * 3) + 2], uniformValue[(4 * 3) + 3]);
   3429 		verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[4]"), uniformValue[4 * 4], uniformValue[(4 * 4) + 1], uniformValue[(4 * 4) + 2], uniformValue[(4 * 4) + 3]);
   3430 		expectError(GL_NO_ERROR);
   3431 
   3432 		glUseProgram(0);
   3433 		glDeleteShader(shaderVert);
   3434 		glDeleteShader(shaderFrag);
   3435 		glDeleteProgram(program);
   3436 		expectError(GL_NO_ERROR);
   3437 	}
   3438 };
   3439 
   3440 class UniformValueMatrixCase : public ApiCase
   3441 {
   3442 public:
   3443 	UniformValueMatrixCase (Context& context, const char* name, const char* description)
   3444 		: ApiCase(context, name, description)
   3445 	{
   3446 	}
   3447 
   3448 	void test (void)
   3449 	{
   3450 		static const char* testVertSource =
   3451 			"#version 300 es\n"
   3452 			"uniform highp mat2 mat2Uniform;"
   3453 			"uniform highp mat3 mat3Uniform;"
   3454 			"uniform highp mat4 mat4Uniform;"
   3455 			"void main (void)\n"
   3456 			"{\n"
   3457 			"	gl_Position = vec4(mat2Uniform[0][0] + mat3Uniform[0][0] + mat4Uniform[0][0]);\n"
   3458 			"}\n";
   3459 		static const char* testFragSource =
   3460 			"#version 300 es\n"
   3461 			"layout(location = 0) out mediump vec4 fragColor;"
   3462 			"void main (void)\n"
   3463 			"{\n"
   3464 			"	fragColor = vec4(0.0);\n"
   3465 			"}\n";
   3466 
   3467 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
   3468 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
   3469 
   3470 		glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
   3471 		glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
   3472 
   3473 		glCompileShader(shaderVert);
   3474 		glCompileShader(shaderFrag);
   3475 		expectError(GL_NO_ERROR);
   3476 
   3477 		GLuint program = glCreateProgram();
   3478 		glAttachShader(program, shaderVert);
   3479 		glAttachShader(program, shaderFrag);
   3480 		glLinkProgram(program);
   3481 		glUseProgram(program);
   3482 		expectError(GL_NO_ERROR);
   3483 
   3484 		GLint location;
   3485 
   3486 		float matrixValues[4 * 4] =
   3487 		{
   3488 			-1.0f,	0.1f,	4.0f,	800.0f,
   3489 			13.0f,	55.0f,	12.0f,	91.0f,
   3490 			-55.1f,	1.1f,	98.0f,	19.0f,
   3491 			41.0f,	65.0f,	4.0f,	12.2f,
   3492 		};
   3493 
   3494 		// the values of the matrix are returned in column major order but they can be given in either order
   3495 
   3496 		location = glGetUniformLocation(program,"mat2Uniform");
   3497 		glUniformMatrix2fv(location, 1, GL_FALSE, matrixValues);
   3498 		verifyUniformMatrixValues<2>(m_testCtx, *this, program, location, matrixValues, false);
   3499 		glUniformMatrix2fv(location, 1, GL_TRUE, matrixValues);
   3500 		verifyUniformMatrixValues<2>(m_testCtx, *this, program, location, matrixValues, true);
   3501 
   3502 		location = glGetUniformLocation(program,"mat3Uniform");
   3503 		glUniformMatrix3fv(location, 1, GL_FALSE, matrixValues);
   3504 		verifyUniformMatrixValues<3>(m_testCtx, *this, program, location, matrixValues, false);
   3505 		glUniformMatrix3fv(location, 1, GL_TRUE, matrixValues);
   3506 		verifyUniformMatrixValues<3>(m_testCtx, *this, program, location, matrixValues, true);
   3507 
   3508 		location = glGetUniformLocation(program,"mat4Uniform");
   3509 		glUniformMatrix4fv(location, 1, GL_FALSE, matrixValues);
   3510 		verifyUniformMatrixValues<4>(m_testCtx, *this, program, location, matrixValues, false);
   3511 		glUniformMatrix4fv(location, 1, GL_TRUE, matrixValues);
   3512 		verifyUniformMatrixValues<4>(m_testCtx, *this, program, location, matrixValues, true);
   3513 
   3514 		glUseProgram(0);
   3515 		glDeleteShader(shaderVert);
   3516 		glDeleteShader(shaderFrag);
   3517 		glDeleteProgram(program);
   3518 		expectError(GL_NO_ERROR);
   3519 	}
   3520 };
   3521 
   3522 class PrecisionFormatCase : public ApiCase
   3523 {
   3524 public:
   3525 	struct RequiredFormat
   3526 	{
   3527 		int negativeRange;
   3528 		int positiveRange;
   3529 		int precision;
   3530 	};
   3531 
   3532 	PrecisionFormatCase (Context& context, const char* name, const char* description, glw::GLenum shaderType, glw::GLenum precisionType)
   3533 		: ApiCase			(context, name, description)
   3534 		, m_shaderType		(shaderType)
   3535 		, m_precisionType	(precisionType)
   3536 	{
   3537 	}
   3538 
   3539 private:
   3540 	void test (void)
   3541 	{
   3542 		const RequiredFormat											expected = getRequiredFormat();
   3543 		bool															error = false;
   3544 		gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLboolean>	shaderCompiler;
   3545 		gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint[2]>	range;
   3546 		gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint>		precision;
   3547 
   3548 		// query values
   3549 		glGetShaderPrecisionFormat(m_shaderType, m_precisionType, range, &precision);
   3550 		expectError(GL_NO_ERROR);
   3551 
   3552 		if (!range.verifyValidity(m_testCtx))
   3553 			return;
   3554 		if (!precision.verifyValidity(m_testCtx))
   3555 			return;
   3556 
   3557 		m_log
   3558 			<< tcu::TestLog::Message
   3559 			<< "range[0] = " << range[0] << "\n"
   3560 			<< "range[1] = " << range[1] << "\n"
   3561 			<< "precision = " << precision
   3562 			<< tcu::TestLog::EndMessage;
   3563 
   3564 		// verify values
   3565 
   3566 		if (m_precisionType == GL_HIGH_FLOAT)
   3567 		{
   3568 			// highp float must be IEEE 754 single
   3569 
   3570 			if (range[0] != expected.negativeRange ||
   3571 				range[1] != expected.positiveRange ||
   3572 				precision != expected.precision)
   3573 			{
   3574 				m_log
   3575 					<< tcu::TestLog::Message
   3576 					<< "// ERROR: Invalid precision format, expected:\n"
   3577 					<< "\trange[0] = " << expected.negativeRange << "\n"
   3578 					<< "\trange[1] = " << expected.positiveRange << "\n"
   3579 					<< "\tprecision = " << expected.precision
   3580 					<< tcu::TestLog::EndMessage;
   3581 				error = true;
   3582 			}
   3583 		}
   3584 		else
   3585 		{
   3586 			if (range[0] < expected.negativeRange)
   3587 			{
   3588 				m_log << tcu::TestLog::Message << "// ERROR: Invalid range[0], expected greater or equal to " << expected.negativeRange << tcu::TestLog::EndMessage;
   3589 				error = true;
   3590 			}
   3591 
   3592 			if (range[1] < expected.positiveRange)
   3593 			{
   3594 				m_log << tcu::TestLog::Message << "// ERROR: Invalid range[1], expected greater or equal to " << expected.positiveRange << tcu::TestLog::EndMessage;
   3595 				error = true;
   3596 			}
   3597 
   3598 			if (precision < expected.precision)
   3599 			{
   3600 				m_log << tcu::TestLog::Message << "// ERROR: Invalid precision, expected greater or equal to " << expected.precision << tcu::TestLog::EndMessage;
   3601 				error = true;
   3602 			}
   3603 		}
   3604 
   3605 		if (error)
   3606 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid precision/range");
   3607 	}
   3608 
   3609 	RequiredFormat getRequiredFormat (void) const
   3610 	{
   3611 		// Precisions for different types.
   3612 		const RequiredFormat requirements[] =
   3613 		{
   3614 			{   0,   0,  8 }, //!< lowp float
   3615 			{  13,  13, 10 }, //!< mediump float
   3616 			{ 127, 127, 23 }, //!< highp float
   3617 			{   8,   7,  0 }, //!< lowp int
   3618 			{  15,  14,  0 }, //!< mediump int
   3619 			{  31,  30,  0 }, //!< highp int
   3620 		};
   3621 		const int ndx = (int)m_precisionType - (int)GL_LOW_FLOAT;
   3622 
   3623 		DE_ASSERT(ndx >= 0);
   3624 		DE_ASSERT(ndx < DE_LENGTH_OF_ARRAY(requirements));
   3625 		return requirements[ndx];
   3626 	}
   3627 
   3628 	const glw::GLenum m_shaderType;
   3629 	const glw::GLenum m_precisionType;
   3630 };
   3631 
   3632 } // anonymous
   3633 
   3634 
   3635 ShaderStateQueryTests::ShaderStateQueryTests (Context& context)
   3636 	: TestCaseGroup(context, "shader", "Shader State Query tests")
   3637 {
   3638 }
   3639 
   3640 void ShaderStateQueryTests::init (void)
   3641 {
   3642 	// shader
   3643 	addChild(new ShaderTypeCase						(m_context, "shader_type",							"SHADER_TYPE"));
   3644 	addChild(new ShaderCompileStatusCase			(m_context, "shader_compile_status",				"COMPILE_STATUS"));
   3645 	addChild(new ShaderInfoLogCase					(m_context, "shader_info_log_length",				"INFO_LOG_LENGTH"));
   3646 	addChild(new ShaderSourceCase					(m_context, "shader_source_length",					"SHADER_SOURCE_LENGTH"));
   3647 
   3648 	// shader and program
   3649 	addChild(new DeleteStatusCase					(m_context, "delete_status",						"DELETE_STATUS"));
   3650 
   3651 	// vertex-attrib
   3652 	addChild(new CurrentVertexAttribInitialCase		(m_context, "current_vertex_attrib_initial",		"CURRENT_VERTEX_ATTRIB"));
   3653 	addChild(new CurrentVertexAttribFloatCase		(m_context, "current_vertex_attrib_float",			"CURRENT_VERTEX_ATTRIB"));
   3654 	addChild(new CurrentVertexAttribIntCase			(m_context, "current_vertex_attrib_int",			"CURRENT_VERTEX_ATTRIB"));
   3655 	addChild(new CurrentVertexAttribUintCase		(m_context, "current_vertex_attrib_uint",			"CURRENT_VERTEX_ATTRIB"));
   3656 	addChild(new CurrentVertexAttribConversionCase	(m_context, "current_vertex_attrib_float_to_int",	"CURRENT_VERTEX_ATTRIB"));
   3657 
   3658 	// program
   3659 	addChild(new ProgramInfoLogCase					(m_context, "program_info_log_length",				"INFO_LOG_LENGTH",	ProgramInfoLogCase::BUILDERROR_COMPILE));
   3660 	addChild(new ProgramInfoLogCase					(m_context, "program_info_log_length_link_error",	"INFO_LOG_LENGTH",	ProgramInfoLogCase::BUILDERROR_LINK));
   3661 	addChild(new ProgramValidateStatusCase			(m_context, "program_validate_status",				"VALIDATE_STATUS"));
   3662 	addChild(new ProgramAttachedShadersCase			(m_context, "program_attached_shaders",				"ATTACHED_SHADERS"));
   3663 
   3664 	addChild(new ProgramActiveUniformNameCase		(m_context, "program_active_uniform_name",			"ACTIVE_UNIFORMS and ACTIVE_UNIFORM_MAX_LENGTH"));
   3665 	addChild(new ProgramUniformCase					(m_context, "program_active_uniform_types",			"UNIFORM_TYPE, UNIFORM_SIZE, and UNIFORM_IS_ROW_MAJOR"));
   3666 	addChild(new ProgramActiveUniformBlocksCase		(m_context, "program_active_uniform_blocks",		"ACTIVE_UNIFORM_BLOCK_x"));
   3667 	addChild(new ProgramBinaryCase					(m_context, "program_binary",						"PROGRAM_BINARY_LENGTH and PROGRAM_BINARY_RETRIEVABLE_HINT"));
   3668 
   3669 	// transform feedback
   3670 	addChild(new TransformFeedbackCase				(m_context, "transform_feedback",					"TRANSFORM_FEEDBACK_BUFFER_MODE, TRANSFORM_FEEDBACK_VARYINGS, TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH"));
   3671 
   3672 	// attribute related
   3673 	addChild(new ActiveAttributesCase				(m_context, "active_attributes",					"ACTIVE_ATTRIBUTES and ACTIVE_ATTRIBUTE_MAX_LENGTH"));
   3674 	addChild(new VertexAttributeSizeCase			(m_context, "vertex_attrib_size",					"VERTEX_ATTRIB_ARRAY_SIZE"));
   3675 	addChild(new VertexAttributeTypeCase			(m_context, "vertex_attrib_type",					"VERTEX_ATTRIB_ARRAY_TYPE"));
   3676 	addChild(new VertexAttributeStrideCase			(m_context, "vertex_attrib_stride",					"VERTEX_ATTRIB_ARRAY_STRIDE"));
   3677 	addChild(new VertexAttributeNormalizedCase		(m_context, "vertex_attrib_normalized",				"VERTEX_ATTRIB_ARRAY_NORMALIZED"));
   3678 	addChild(new VertexAttributeIntegerCase			(m_context, "vertex_attrib_integer",				"VERTEX_ATTRIB_ARRAY_INTEGER"));
   3679 	addChild(new VertexAttributeEnabledCase			(m_context, "vertex_attrib_array_enabled",			"VERTEX_ATTRIB_ARRAY_ENABLED"));
   3680 	addChild(new VertexAttributeDivisorCase			(m_context, "vertex_attrib_array_divisor",			"VERTEX_ATTRIB_ARRAY_DIVISOR"));
   3681 	addChild(new VertexAttributeBufferBindingCase	(m_context, "vertex_attrib_array_buffer_binding",	"VERTEX_ATTRIB_ARRAY_BUFFER_BINDING"));
   3682 	addChild(new VertexAttributePointerCase			(m_context, "vertex_attrib_pointerv",				"GetVertexAttribPointerv"));
   3683 
   3684 	// uniform values
   3685 	addChild(new UniformValueFloatCase				(m_context, "uniform_value_float",					"GetUniform*"));
   3686 	addChild(new UniformValueIntCase				(m_context, "uniform_value_int",					"GetUniform*"));
   3687 	addChild(new UniformValueUintCase				(m_context, "uniform_value_uint",					"GetUniform*"));
   3688 	addChild(new UniformValueBooleanCase			(m_context, "uniform_value_boolean",				"GetUniform*"));
   3689 	addChild(new UniformValueSamplerCase			(m_context, "uniform_value_sampler",				"GetUniform*"));
   3690 	addChild(new UniformValueArrayCase				(m_context, "uniform_value_array",					"GetUniform*"));
   3691 	addChild(new UniformValueMatrixCase				(m_context, "uniform_value_matrix",					"GetUniform*"));
   3692 
   3693 	// precision format query
   3694 	addChild(new PrecisionFormatCase				(m_context, "precision_vertex_lowp_float",			"GetShaderPrecisionFormat",		GL_VERTEX_SHADER,	GL_LOW_FLOAT));
   3695 	addChild(new PrecisionFormatCase				(m_context, "precision_vertex_mediump_float",		"GetShaderPrecisionFormat",		GL_VERTEX_SHADER,	GL_MEDIUM_FLOAT));
   3696 	addChild(new PrecisionFormatCase				(m_context, "precision_vertex_highp_float",			"GetShaderPrecisionFormat",		GL_VERTEX_SHADER,	GL_HIGH_FLOAT));
   3697 	addChild(new PrecisionFormatCase				(m_context, "precision_vertex_lowp_int",			"GetShaderPrecisionFormat",		GL_VERTEX_SHADER,	GL_LOW_INT));
   3698 	addChild(new PrecisionFormatCase				(m_context, "precision_vertex_mediump_int",			"GetShaderPrecisionFormat",		GL_VERTEX_SHADER,	GL_MEDIUM_INT));
   3699 	addChild(new PrecisionFormatCase				(m_context, "precision_vertex_highp_int",			"GetShaderPrecisionFormat",		GL_VERTEX_SHADER,	GL_HIGH_INT));
   3700 	addChild(new PrecisionFormatCase				(m_context, "precision_fragment_lowp_float",		"GetShaderPrecisionFormat",		GL_FRAGMENT_SHADER,	GL_LOW_FLOAT));
   3701 	addChild(new PrecisionFormatCase				(m_context, "precision_fragment_mediump_float",		"GetShaderPrecisionFormat",		GL_FRAGMENT_SHADER,	GL_MEDIUM_FLOAT));
   3702 	addChild(new PrecisionFormatCase				(m_context, "precision_fragment_highp_float",		"GetShaderPrecisionFormat",		GL_FRAGMENT_SHADER,	GL_HIGH_FLOAT));
   3703 	addChild(new PrecisionFormatCase				(m_context, "precision_fragment_lowp_int",			"GetShaderPrecisionFormat",		GL_FRAGMENT_SHADER,	GL_LOW_INT));
   3704 	addChild(new PrecisionFormatCase				(m_context, "precision_fragment_mediump_int",		"GetShaderPrecisionFormat",		GL_FRAGMENT_SHADER,	GL_MEDIUM_INT));
   3705 	addChild(new PrecisionFormatCase				(m_context, "precision_fragment_highp_int",			"GetShaderPrecisionFormat",		GL_FRAGMENT_SHADER,	GL_HIGH_INT));
   3706 }
   3707 
   3708 } // Functional
   3709 } // gles3
   3710 } // deqp
   3711