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