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