Apply sRGB conversion to reference in sRGB framebuffer fetch test am: c76765be1f
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / gles31 / es31cProgramInterfaceQueryTests.cpp
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
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
22  */ /*-------------------------------------------------------------------*/
23
24 #include "es31cProgramInterfaceQueryTests.hpp"
25 #include "glwEnums.hpp"
26 #include "glwFunctions.hpp"
27 #include <cstdarg>
28 #include <map>
29 #include <set>
30
31 namespace glcts
32 {
33
34 using namespace glw;
35
36 namespace
37 {
38
39 class PIQBase : public glcts::SubcaseBase
40 {
41
42 public:
43         virtual ~PIQBase()
44         {
45         }
46
47         virtual std::string PassCriteria()
48         {
49                 return "All called functions return expected values.";
50         }
51
52         virtual std::string Purpose()
53         {
54                 return "Verify that the set of tested functions glGetProgram* return\n"
55                            "expected results when used to get data from program\n"
56                            "made of " +
57                            ShadersDesc() + "." + PurposeExt();
58         }
59
60         virtual std::string Method()
61         {
62                 return "Create a program using " + ShadersDesc() +
63                            "\n"
64                            "then use set of tested functions to get an information about it and\n"
65                            "verify that information with the expected data" +
66                            Expectations();
67         }
68
69         virtual long Cleanup()
70         {
71                 glUseProgram(0);
72                 return NO_ERROR;
73         }
74
75         virtual long Setup()
76         {
77                 return NO_ERROR;
78         }
79
80 protected:
81         void LinkProgram(GLuint program)
82         {
83                 glLinkProgram(program);
84                 GLsizei length;
85                 GLchar  log[1024];
86                 glGetProgramInfoLog(program, sizeof(log), &length, log);
87                 if (length > 1)
88                 {
89                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
90                                                                                                 << log << tcu::TestLog::EndMessage;
91                 }
92         }
93
94         GLuint CreateProgram(const char* src_vs, const char* src_fs, bool link)
95         {
96                 const GLuint p = glCreateProgram();
97
98                 if (src_vs)
99                 {
100                         GLuint sh = glCreateShader(GL_VERTEX_SHADER);
101                         glAttachShader(p, sh);
102                         glDeleteShader(sh);
103                         glShaderSource(sh, 1, &src_vs, NULL);
104                         glCompileShader(sh);
105                 }
106                 if (src_fs)
107                 {
108                         GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
109                         glAttachShader(p, sh);
110                         glDeleteShader(sh);
111                         glShaderSource(sh, 1, &src_fs, NULL);
112                         glCompileShader(sh);
113                 }
114                 if (link)
115                 {
116                         LinkProgram(p);
117                 }
118                 return p;
119         }
120
121         virtual std::string ShadersDesc()
122         {
123                 return "";
124         }
125
126         virtual std::string Expectations()
127         {
128                 return ".";
129         }
130
131         virtual std::string PurposeExt()
132         {
133                 return "";
134         }
135
136         virtual inline void ExpectError(GLenum expected, long& error)
137         {
138                 if (error != NO_ERROR)
139                         return;
140                 GLenum tmp = glGetError();
141                 if (tmp == expected)
142                 {
143                         m_context.getTestContext().getLog()
144                                 << tcu::TestLog::Message << "Found expected error" << tcu::TestLog::EndMessage;
145                         error = NO_ERROR; // Error is expected
146                 }
147                 else
148                 {
149                         error = ERROR;
150                         m_context.getTestContext().getLog() << tcu::TestLog::Message << expected
151                                                                                                 << " error was expected, found: " << tmp << tcu::TestLog::EndMessage;
152                 }
153         }
154
155         virtual inline void VerifyGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, int expected,
156                                                                                                         long& error)
157         {
158                 GLint res;
159                 glGetProgramInterfaceiv(program, programInterface, pname, &res);
160                 if (res != expected)
161                 {
162                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
163                                                                                                 << expected << tcu::TestLog::EndMessage;
164                         error = ERROR;
165                 }
166         }
167
168         virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum programInterface, const std::string& name,
169                                                                                                           GLuint expected, long& error)
170         {
171                 GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str());
172                 if (res != expected)
173                 {
174                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
175                                                                                                 << expected << tcu::TestLog::EndMessage;
176                         error = ERROR;
177                 }
178         }
179
180         virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum                 programInterface,
181                                                                                                           std::map<std::string, GLuint>& indices, const std::string& name,
182                                                                                                           long& error)
183         {
184                 GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str());
185                 if (res == GL_INVALID_INDEX)
186                 {
187                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res
188                                                                                                 << ", expected number other than -1" << tcu::TestLog::EndMessage;
189                         error = ERROR;
190                         return;
191                 }
192                 std::map<std::string, GLuint>::iterator it = indices.begin();
193                 while (it != indices.end())
194                 {
195                         if (it->second == res)
196                         {
197                                 m_context.getTestContext().getLog()
198                                         << tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage;
199                                 error = ERROR;
200                                 return;
201                         }
202                         ++it;
203                 }
204                 indices[name] = res;
205         }
206
207         virtual inline void VerifyGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index,
208                                                                                                          const std::string& expected, long& error)
209         {
210                 GLchar  name[1024] = { '\0' };
211                 GLsizei len;
212                 glGetProgramResourceName(program, programInterface, index, 1024, &len, name);
213                 if (len <= 0 || len > 1023 || name[len - 1] == '\0')
214                 {
215                         m_context.getTestContext().getLog()
216                                 << tcu::TestLog::Message
217                                 << "ERROR: Length in glGetProgramResourceName should not count null terminator!"
218                                 << tcu::TestLog::EndMessage;
219                         error = ERROR;
220                 }
221                 else if (name != expected || name[len] != '\0')
222                 {
223                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << name << ", expected "
224                                                                                                 << expected << tcu::TestLog::EndMessage;
225                         error = ERROR;
226                 }
227         }
228
229         virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum programInterface,
230                                                                                                                  const std::string& name, GLint expected, long& error)
231         {
232                 GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str());
233                 if (res != expected)
234                 {
235                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
236                                                                                                 << expected << tcu::TestLog::EndMessage;
237                         error = ERROR;
238                 }
239         }
240
241         virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum                programInterface,
242                                                                                                                  std::map<std::string, GLint>& locations,
243                                                                                                                  const std::string& name, long& error)
244         {
245                 GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str());
246                 if (res < 0)
247                 {
248                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res
249                                                                                                 << ", expected not less than 0" << tcu::TestLog::EndMessage;
250                         error = ERROR;
251                         return;
252                 }
253                 std::map<std::string, GLint>::iterator it = locations.begin();
254                 while (it != locations.end())
255                 {
256                         if (it->second == res)
257                         {
258                                 m_context.getTestContext().getLog()
259                                         << tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage;
260                                 error = ERROR;
261                                 return;
262                         }
263                         ++it;
264                 }
265                 locations[name] = res;
266         }
267
268         virtual inline void VerifyGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index,
269                                                                                                    GLsizei propCount, const GLenum props[], GLsizei expectedLength,
270                                                                                                    const GLint expected[], long& error)
271         {
272                 const GLsizei bufSize = 1000;
273                 GLsizei           length;
274                 GLint             params[bufSize];
275                 glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, &length, params);
276                 if (length != expectedLength || length <= 0)
277                 {
278                         error = ERROR;
279                         m_context.getTestContext().getLog()
280                                 << tcu::TestLog::Message << "ERROR: Got length " << length << ", expected " << expectedLength
281                                 << "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index
282                                 << tcu::TestLog::EndMessage;
283                         return;
284                 }
285                 for (int i = 0; i < length; ++i)
286                 {
287                         if (params[i] != expected[i])
288                         {
289                                 error = ERROR;
290                                 m_context.getTestContext().getLog()
291                                         << tcu::TestLog::Message << "ERROR: Got " << params[i] << ", expected " << expected[i]
292                                         << " at: " << i << "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index
293                                         << tcu::TestLog::EndMessage;
294                         }
295                 }
296         }
297
298         virtual inline GLint GetProgramivRetValue(GLuint program, GLenum pname)
299         {
300                 GLint ret;
301                 glGetProgramiv(program, pname, &ret);
302                 return ret;
303         }
304
305         static const GLenum interfaces[];
306 };
307
308 const GLenum PIQBase::interfaces[] = { GL_PROGRAM_INPUT,
309                                                                            GL_PROGRAM_OUTPUT,
310                                                                            GL_UNIFORM,
311                                                                            GL_UNIFORM_BLOCK,
312                                                                            GL_BUFFER_VARIABLE,
313                                                                            GL_SHADER_STORAGE_BLOCK,
314                                                                            GL_ATOMIC_COUNTER_BUFFER,
315                                                                            GL_TRANSFORM_FEEDBACK_VARYING };
316
317 class NoShaders : public PIQBase
318 {
319
320         virtual std::string Title()
321         {
322                 return "No Shaders Test";
323         }
324
325         virtual std::string ShadersDesc()
326         {
327                 return "no shaders";
328         }
329
330         virtual long Run()
331         {
332                 const GLuint program = glCreateProgram();
333
334                 long error = NO_ERROR;
335                 int  size  = sizeof(PIQBase::interfaces) / sizeof(PIQBase::interfaces[0]);
336
337                 for (int i = 0; i < size; ++i)
338                 {
339                         VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_ACTIVE_RESOURCES, 0, error);
340                         if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER)
341                                 continue;
342                         VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_MAX_NAME_LENGTH, 0, error);
343                 }
344                 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
345                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
346                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
347
348                 for (int i = 0; i < size; ++i)
349                 {
350                         if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER)
351                                 continue;
352                         VerifyGetProgramResourceIndex(program, PIQBase::interfaces[i], "", GL_INVALID_INDEX, error);
353                 }
354
355                 // can't test GetProgramResourceLocation* here since program has to be linked
356                 // can't test GetProgramResourceiv, need valid index
357
358                 glDeleteProgram(program);
359                 return error;
360         }
361 };
362
363 class SimpleShaders : public PIQBase
364 {
365
366 public:
367         virtual std::string Title()
368         {
369                 return "Simple Shaders Test";
370         }
371
372         virtual std::string ShadersDesc()
373         {
374                 return "fallthrough fragment and vertex shaders";
375         }
376
377         virtual std::string VertexShader()
378         {
379                 return "#version 310 es                      \n"
380                            "in vec4 position;                    \n"
381                            "void main(void)                      \n"
382                            "{                                    \n"
383                            "    gl_Position = position;          \n"
384                            "}";
385         }
386
387         virtual std::string FragmentShader()
388         {
389                 return "#version 310 es                \n"
390                            "out mediump vec4 color;        \n"
391                            "void main() {                  \n"
392                            "    color = vec4(0, 1, 0, 1);  \n"
393                            "}";
394         }
395
396         virtual long Run()
397         {
398                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
399                 glBindAttribLocation(program, 0, "position");
400                 glLinkProgram(program);
401
402                 long error = NO_ERROR;
403
404                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
405                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
406                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
407                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
408
409                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
410                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
411
412                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
413                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
414
415                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
416                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
417
418                 GLenum props[] = { GL_NAME_LENGTH,
419                                                    GL_TYPE,
420                                                    GL_ARRAY_SIZE,
421                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
422                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
423                                                    GL_REFERENCED_BY_VERTEX_SHADER,
424                                                    GL_LOCATION };
425                 GLint expected[] = { 9, 35666, 1, 0, 0, 1, 0 };
426                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 7, props, 7, expected, error);
427
428                 GLenum props2[] = { GL_NAME_LENGTH,
429                                                         GL_TYPE,
430                                                         GL_ARRAY_SIZE,
431                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
432                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
433                                                         GL_REFERENCED_BY_VERTEX_SHADER,
434                                                         GL_LOCATION };
435                 GLint expected2[] = { 6, 35666, 1, 0, 1, 0, 0 };
436                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 7, props2, 7, expected2, error);
437
438                 glDeleteProgram(program);
439                 return error;
440         }
441 };
442
443 class ComputeShaderTest : public PIQBase
444 {
445 public:
446         virtual std::string Title()
447         {
448                 return "Compute Shader Test";
449         }
450
451         virtual std::string ShadersDesc()
452         {
453                 return "compute shader";
454         }
455
456         virtual std::string ComputeShader()
457         {
458                 return "layout(local_size_x = 1, local_size_y = 1) in; \n"
459                            "layout(std430) buffer Output {                 \n"
460                            "  mediump vec4 data[];                         \n"
461                            "} g_out;                                       \n"
462                            ""
463                            "void main() {                                   \n"
464                            "   g_out.data[0] = vec4(1.0, 2.0, 3.0, 4.0);    \n"
465                            "   g_out.data[100] = vec4(1.0, 2.0, 3.0, 4.0);  \n"
466                            "}";
467         }
468
469         GLuint CreateComputeProgram(const std::string& cs)
470         {
471                 const GLuint p = glCreateProgram();
472
473                 const char* const kGLSLVer = "#version 310 es\n";
474
475                 if (!cs.empty())
476                 {
477                         const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
478                         glAttachShader(p, sh);
479                         glDeleteShader(sh);
480                         const char* const src[2] = { kGLSLVer, cs.c_str() };
481                         glShaderSource(sh, 2, src, NULL);
482                         glCompileShader(sh);
483                 }
484
485                 return p;
486         }
487
488         bool CheckProgram(GLuint program, bool* compile_error = NULL)
489         {
490                 GLint compile_status = GL_TRUE;
491                 GLint status;
492                 glGetProgramiv(program, GL_LINK_STATUS, &status);
493
494                 if (status == GL_FALSE)
495                 {
496                         GLint attached_shaders;
497                         glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
498
499                         if (attached_shaders > 0)
500                         {
501                                 std::vector<GLuint> shaders(attached_shaders);
502                                 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
503
504                                 for (GLint i = 0; i < attached_shaders; ++i)
505                                 {
506                                         GLenum type;
507                                         glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
508                                         switch (type)
509                                         {
510                                         case GL_VERTEX_SHADER:
511                                                 m_context.getTestContext().getLog()
512                                                         << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
513                                                 break;
514                                         case GL_TESS_CONTROL_SHADER:
515                                                 m_context.getTestContext().getLog()
516                                                         << tcu::TestLog::Message << "*** Tessellation Control Shader ***"
517                                                         << tcu::TestLog::EndMessage;
518                                                 break;
519                                         case GL_TESS_EVALUATION_SHADER:
520                                                 m_context.getTestContext().getLog()
521                                                         << tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
522                                                         << tcu::TestLog::EndMessage;
523                                                 break;
524                                         case GL_GEOMETRY_SHADER:
525                                                 m_context.getTestContext().getLog()
526                                                         << tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
527                                                 break;
528                                         case GL_FRAGMENT_SHADER:
529                                                 m_context.getTestContext().getLog()
530                                                         << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
531                                                 break;
532                                         case GL_COMPUTE_SHADER:
533                                                 m_context.getTestContext().getLog()
534                                                         << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
535                                                 break;
536                                         default:
537                                                 m_context.getTestContext().getLog()
538                                                         << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
539                                         }
540
541                                         GLint res;
542                                         glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
543                                         if (res != GL_TRUE)
544                                                 compile_status = res;
545
546                                         // shader source
547                                         GLint length;
548                                         glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
549                                         if (length > 0)
550                                         {
551                                                 std::vector<GLchar> source(length);
552                                                 glGetShaderSource(shaders[i], length, NULL, &source[0]);
553                                                 m_context.getTestContext().getLog()
554                                                         << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
555                                         }
556
557                                         // shader info log
558                                         glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
559                                         if (length > 0)
560                                         {
561                                                 std::vector<GLchar> log(length);
562                                                 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
563                                                 m_context.getTestContext().getLog()
564                                                         << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
565                                         }
566                                 }
567                         }
568
569                         // program info log
570                         GLint length;
571                         glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
572                         if (length > 0)
573                         {
574                                 std::vector<GLchar> log(length);
575                                 glGetProgramInfoLog(program, length, NULL, &log[0]);
576                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
577                         }
578                 }
579
580                 if (compile_error)
581                         *compile_error = (compile_status == GL_TRUE ? false : true);
582                 if (compile_status != GL_TRUE)
583                         return false;
584                 return status == GL_TRUE ? true : false;
585         }
586
587         virtual void inline VerifyCompute(GLuint program, long& error)
588         {
589                 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 15, error);
590                 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, 1, error);
591                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
592                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 7, error);
593                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 1, error);
594
595                 std::map<std::string, GLuint> indicesSSB;
596                 std::map<std::string, GLuint> indicesBV;
597                 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Output", error);
598                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "Output.data", error);
599
600                 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], "Output", error);
601                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], "Output.data[0]", error);
602
603                 GLenum props3[] = { GL_NAME_LENGTH,
604                                                         GL_BUFFER_BINDING,
605                                                         GL_NUM_ACTIVE_VARIABLES,
606                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
607                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
608                                                         GL_REFERENCED_BY_VERTEX_SHADER,
609                                                         GL_ACTIVE_VARIABLES };
610                 GLint expected3[] = { 7, 0, 1, 1, 0, 0, static_cast<GLint>(indicesBV["Outputa.data"]) };
611                 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], 7, props3, 7, expected3,
612                                                                    error);
613
614                 GLenum props4[] = { GL_NAME_LENGTH,
615                                                         GL_TYPE,
616                                                         GL_ARRAY_SIZE,
617                                                         GL_BLOCK_INDEX,
618                                                         GL_IS_ROW_MAJOR,
619                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
620                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
621                                                         GL_REFERENCED_BY_VERTEX_SHADER,
622                                                         GL_TOP_LEVEL_ARRAY_SIZE };
623                 GLint expected4[] = { 15, 35666, 0, static_cast<GLint>(indicesSSB["Output"]), 0, 1, 0, 0, 1 };
624                 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], 9, props4, 9, expected4,
625                                                                    error);
626         }
627
628         virtual long Run()
629         {
630                 GLuint program = CreateComputeProgram(ComputeShader());
631                 glLinkProgram(program);
632                 if (!CheckProgram(program))
633                 {
634                         glDeleteProgram(program);
635                         return ERROR;
636                 }
637                 glUseProgram(program);
638
639                 long error = NO_ERROR;
640
641                 VerifyCompute(program, error);
642
643                 glDeleteProgram(program);
644                 return error;
645         }
646 };
647
648 class InputTypes : public SimpleShaders
649 {
650         virtual std::string Title()
651         {
652                 return "Input Types Test";
653         }
654
655         virtual std::string ShadersDesc()
656         {
657                 return "vertex shader with different `in` types and a fallthrough fragment shader";
658         }
659
660         virtual std::string VertexShader()
661         {
662                 return "#version 310 es                      \n"
663                            "in mat4 a;                           \n"
664                            "in vec4 b;                           \n"
665                            "in float c;                          \n"
666                            "in mat2x3 d;                         \n"
667                            "in vec2 e;                           \n"
668                            "in uint f;                           \n"
669                            "in vec3 g;                           \n"
670                            "in int h;                            \n"
671                            "void main(void)                      \n"
672                            "{                                    \n"
673                            "   vec4 pos;                                                 \n"
674                            "   pos.w = float(h) + g.x + g.y + d[1].y;                    \n"
675                            "   pos.y = float(b.x) * c + c + d[0][0];                     \n"
676                            "   pos.x = a[0].x + a[1].y + a[2].z + a[3].w;                \n"
677                            "   pos.z = d[0][1] + float(e.x) * float(f) + d[1][0];        \n"
678                            "   gl_Position = pos;                                        \n"
679                            "}";
680         }
681
682         virtual long Run()
683         {
684                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
685                 glBindAttribLocation(program, 0, "a");
686                 glBindAttribLocation(program, 4, "b");
687                 glBindAttribLocation(program, 5, "c");
688                 glBindAttribLocation(program, 7, "d");
689                 glBindAttribLocation(program, 11, "e");
690                 glBindAttribLocation(program, 12, "f");
691                 glBindAttribLocation(program, 13, "g");
692                 glBindAttribLocation(program, 15, "h");
693                 LinkProgram(program);
694
695                 long error = NO_ERROR;
696
697                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error);
698                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error);
699
700                 std::map<std::string, GLuint> indices;
701                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error);
702                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error);
703                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c", error);
704                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error);
705                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error);
706                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error);
707                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error);
708                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error);
709
710                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error);
711                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error);
712                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c"], "c", error);
713                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d", error);
714                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error);
715                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error);
716                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g", error);
717                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error);
718
719                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error);
720                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error);
721                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error);
722                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error);
723                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error);
724                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error);
725                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error);
726                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error);
727
728                 GLenum props[] = {
729                         GL_NAME_LENGTH,
730                         GL_TYPE,
731                         GL_ARRAY_SIZE,
732                         GL_REFERENCED_BY_COMPUTE_SHADER,
733                         GL_REFERENCED_BY_FRAGMENT_SHADER,
734                         GL_REFERENCED_BY_VERTEX_SHADER,
735                         GL_LOCATION,
736                 };
737                 GLint expected[] = { 2, 35676, 1, 0, 0, 1, 0 };
738                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 7, props, 7, expected, error);
739                 GLint expected2[] = { 2, 35666, 1, 0, 0, 1, 4 };
740                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 7, props, 7, expected2, error);
741                 GLint expected3[] = { 2, 5126, 1, 0, 0, 1, 5 };
742                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c"], 7, props, 7, expected3, error);
743                 GLint expected4[] = { 2, 35685, 1, 0, 0, 1, 7 };
744                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 7, props, 7, expected4, error);
745                 GLint expected5[] = { 2, 35664, 1, 0, 0, 1, 11 };
746                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 7, props, 7, expected5, error);
747                 GLint expected6[] = { 2, 5125, 1, 0, 0, 1, 12 };
748                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 7, props, 7, expected6, error);
749                 GLint expected7[] = { 2, 35665, 1, 0, 0, 1, 13 };
750                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 7, props, 7, expected7, error);
751                 GLint expected8[] = { 2, 5124, 1, 0, 0, 1, 15 };
752                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 7, props, 7, expected8, error);
753
754                 glDeleteProgram(program);
755                 return error;
756         }
757 };
758
759 class InputBuiltIn : public SimpleShaders
760 {
761
762         virtual std::string Title()
763         {
764                 return "Input Built-ins Test";
765         }
766
767         virtual std::string ShadersDesc()
768         {
769                 return "vertex shader using built-in variables and a fallthrough fragment shader";
770         }
771
772         virtual std::string Expectations()
773         {
774                 return ".\n\n In this case we ask for information about built-in variables for the input interface.";
775         }
776
777         virtual std::string VertexShader()
778         {
779                 return "#version 310 es                      \n"
780                            "void main(void)                      \n"
781                            "{                                    \n"
782                            "    gl_Position = (float(gl_VertexID) + float(gl_InstanceID)) * vec4(0.1);          \n"
783                            "}";
784         }
785
786         virtual long Run()
787         {
788                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
789                 LinkProgram(program);
790
791                 long error = NO_ERROR;
792
793                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 2, error);
794                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 14, error);
795
796                 std::map<std::string, GLuint> indices;
797                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_VertexID", error);
798                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_InstanceID", error);
799
800                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], "gl_VertexID", error);
801                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], "gl_InstanceID", error);
802
803                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_VertexID", -1, error);
804                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_InstanceID", -1, error);
805
806                 GLenum props[] = { GL_NAME_LENGTH,
807                                                    GL_TYPE,
808                                                    GL_ARRAY_SIZE,
809                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
810                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
811                                                    GL_REFERENCED_BY_VERTEX_SHADER,
812                                                    GL_LOCATION };
813                 GLint expected[] = { 12, 5124, 1, 0, 0, 1, -1 };
814                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], 7, props, 7, expected, error);
815                 GLint expected2[] = { 14, 5124, 1, 0, 0, 1, -1 };
816                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], 7, props, 7, expected2, error);
817
818                 glDeleteProgram(program);
819                 return error;
820         }
821 };
822
823 class InputLayout : public SimpleShaders
824 {
825         virtual std::string Title()
826         {
827                 return "Input Layout Test";
828         }
829
830         virtual std::string ShadersDesc()
831         {
832                 return "vertex shader with different `in` variables locations set through layout and a fallthrough fragment "
833                            "shader";
834         }
835
836         virtual std::string VertexShader()
837         {
838                 return "#version 310 es                      \n"
839                            "layout(location = 4) in vec4 b;      \n"
840                            "layout(location = 7) in mat2x3 d;    \n"
841                            "layout(location = 5) in float c;     \n"
842                            "layout(location = 12) in uint f;     \n"
843                            "layout(location = 13) in vec3 g;     \n"
844                            "layout(location = 0) in mat4 a;      \n"
845                            "layout(location = 15) in int h;      \n"
846                            "layout(location = 11) in vec2 e;     \n"
847                            "void main(void)                      \n"
848                            "{                                    \n"
849                            "   vec4 pos;                                              \n"
850                            "   pos.w = float(h) + g.x + g.y + d[1][1];                \n"
851                            "   pos.y = float(b.x) * c + c + d[0][0];                  \n"
852                            "   pos.x = a[0].x + a[1].y + a[2].z + a[3].w;             \n"
853                            "   pos.z = d[0][1] + float(e.x) * float(f) + d[1][0];     \n"
854                            "   gl_Position = pos;                                     \n"
855                            "}";
856         }
857
858         virtual long Run()
859         {
860                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
861                 LinkProgram(program);
862
863                 long error = NO_ERROR;
864
865                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error);
866                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error);
867
868                 std::map<std::string, GLuint> indices;
869                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error);
870                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error);
871                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c", error);
872                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error);
873                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error);
874                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error);
875                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error);
876                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error);
877
878                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error);
879                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error);
880                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c"], "c", error);
881                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d", error);
882                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error);
883                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error);
884                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g", error);
885                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error);
886
887                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error);
888                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error);
889                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error);
890                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error);
891                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error);
892                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error);
893                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error);
894                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error);
895
896                 GLenum props[] = { GL_NAME_LENGTH,
897                                                    GL_TYPE,
898                                                    GL_ARRAY_SIZE,
899                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
900                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
901                                                    GL_REFERENCED_BY_VERTEX_SHADER,
902                                                    GL_LOCATION };
903                 GLint expected[] = { 2, 35676, 1, 0, 0, 1, 0 };
904                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 7, props, 7, expected, error);
905                 GLint expected2[] = { 2, 35666, 1, 0, 0, 1, 4 };
906                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 7, props, 7, expected2, error);
907                 GLint expected3[] = { 2, 5126, 1, 0, 0, 1, 5 };
908                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c"], 7, props, 7, expected3, error);
909                 GLint expected4[] = { 2, 35685, 1, 0, 0, 1, 7 };
910                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 7, props, 7, expected4, error);
911                 GLint expected5[] = { 2, 35664, 1, 0, 0, 1, 11 };
912                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 7, props, 7, expected5, error);
913                 GLint expected6[] = { 2, 5125, 1, 0, 0, 1, 12 };
914                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 7, props, 7, expected6, error);
915                 GLint expected7[] = { 2, 35665, 1, 0, 0, 1, 13 };
916                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 7, props, 7, expected7, error);
917                 GLint expected8[] = { 2, 5124, 1, 0, 0, 1, 15 };
918                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 7, props, 7, expected8, error);
919
920                 glDeleteProgram(program);
921                 return error;
922         }
923 };
924
925 class OutputLayout : public SimpleShaders
926 {
927         virtual std::string Title()
928         {
929                 return "Output Layout Test";
930         }
931
932         virtual std::string ShadersDesc()
933         {
934                 return "fragment shader with different `out` variables locations set through layout and a fallthrough vertex "
935                            "shader";
936         }
937
938         virtual std::string FragmentShader()
939         {
940                 return "#version 310 es                \n"
941                            "layout(location = 2) out uint b;                    \n"
942                            "layout(location = 3) out mediump vec2 e;            \n"
943                            "layout(location = 0) out mediump vec3 a[2];         \n"
944                            "void main() {                  \n"
945                            "    b = 12u;                   \n"
946                            "    e = vec2(0, 1);            \n"
947                            "    a[1] = vec3(0, 1, 0);      \n"
948                            "    a[0] = vec3(0, 1, 0);      \n"
949                            "}";
950         }
951
952         virtual long Run()
953         {
954                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
955                 glBindAttribLocation(program, 0, "position");
956                 LinkProgram(program);
957
958                 long error = NO_ERROR;
959
960                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 3, error);
961                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
962
963                 std::map<std::string, GLuint> indices;
964                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "a", error);
965                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "b", error);
966                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "e", error);
967
968                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["a"], "a[0]", error);
969                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["b"], "b", error);
970                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["e"], "e", error);
971
972                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
973                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a", 0, error);
974                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[1]", 1, error);
975                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "b", 2, error);
976                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "e", 3, error);
977
978                 GLenum props[] = { GL_NAME_LENGTH,
979                                                    GL_TYPE,
980                                                    GL_ARRAY_SIZE,
981                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
982                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
983                                                    GL_REFERENCED_BY_VERTEX_SHADER,
984                                                    GL_LOCATION };
985                 GLint expected_a[] = { 5, 35665, 2, 0, 1, 0, 0 };
986                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["a"], 7, props, 7, expected_a, error);
987                 GLint expected_b[] = { 2, 5125, 1, 0, 1, 0, 2 };
988                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["b"], 7, props, 7, expected_b, error);
989                 GLint expected_e[] = { 2, 35664, 1, 0, 1, 0, 3 };
990                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["e"], 7, props, 7, expected_e, error);
991
992                 glDeleteProgram(program);
993                 return error;
994         }
995 };
996
997 class UniformSimple : public PIQBase
998 {
999         virtual std::string Title()
1000         {
1001                 return "Uniform Simple Test";
1002         }
1003
1004         virtual std::string ShadersDesc()
1005         {
1006                 return "fallthrough fragment and vertex shaders with uniforms used";
1007         }
1008
1009         virtual std::string PurposeExt()
1010         {
1011                 return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.";
1012         }
1013
1014         virtual std::string VertexShader()
1015         {
1016                 return "#version 310 es                      \n"
1017                            "in vec4 position;                    \n"
1018                            "uniform mediump vec4 repos;          \n"
1019                            "void main(void)                      \n"
1020                            "{                                    \n"
1021                            "    gl_Position = position + repos;  \n"
1022                            "}";
1023         }
1024
1025         virtual std::string FragmentShader()
1026         {
1027                 return "#version 310 es                \n"
1028                            "uniform mediump vec4 recolor;  \n"
1029                            "out mediump vec4 color;        \n"
1030                            "void main() {                  \n"
1031                            "    color = vec4(0, 1, 0, 1) + recolor;  \n"
1032                            "}";
1033         }
1034
1035         virtual long Run()
1036         {
1037                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1038                 glBindAttribLocation(program, 0, "position");
1039                 LinkProgram(program);
1040
1041                 long error = NO_ERROR;
1042
1043                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1044                                                                         GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1045                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 8, error);
1046
1047                 std::map<std::string, GLuint> indices;
1048                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "repos", error);
1049                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "recolor", error);
1050
1051                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["repos"], "repos", error);
1052                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["recolor"], "recolor", error);
1053
1054                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "repos", glGetUniformLocation(program, "repos"), error);
1055                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "recolor", glGetUniformLocation(program, "recolor"),
1056                                                                                  error);
1057
1058                 GLenum props[] = { GL_NAME_LENGTH,
1059                                                    GL_TYPE,
1060                                                    GL_ARRAY_SIZE,
1061                                                    GL_OFFSET,
1062                                                    GL_BLOCK_INDEX,
1063                                                    GL_ARRAY_STRIDE,
1064                                                    GL_MATRIX_STRIDE,
1065                                                    GL_IS_ROW_MAJOR,
1066                                                    GL_ATOMIC_COUNTER_BUFFER_INDEX,
1067                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
1068                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
1069                                                    GL_REFERENCED_BY_VERTEX_SHADER,
1070                                                    GL_LOCATION };
1071                 GLint expected[] = { 6, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "repos") };
1072                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["repos"], 13, props, 13, expected, error);
1073
1074                 GLint expected2[] = { 8, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "recolor") };
1075                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["recolor"], 13, props, 13, expected2, error);
1076
1077                 glDeleteProgram(program);
1078                 return error;
1079         }
1080 };
1081
1082 class UniformTypes : public PIQBase
1083 {
1084         virtual std::string Title()
1085         {
1086                 return "Uniform Types Test";
1087         }
1088
1089         virtual std::string ShadersDesc()
1090         {
1091                 return "fallthrough fragment and vertex shaders with different uniform types used";
1092         }
1093
1094         virtual std::string PurposeExt()
1095         {
1096                 return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.\n";
1097         }
1098
1099         virtual std::string VertexShader()
1100         {
1101                 return "#version 310 es                      \n"
1102                            "in vec4 position;                    \n"
1103                            "uniform mediump vec4 a;              \n"
1104                            "uniform ivec3 b;                     \n"
1105                            "uniform uvec2 c[3];                  \n"
1106                            "uniform mediump mat2 g[8];           \n"
1107                            "uniform mediump mat3x2 i;            \n"
1108                            "void main(void)                      \n"
1109                            "{                                    \n"
1110                            "    float tmp;                       \n"
1111                            "    tmp = g[0][1][1] * g[1][0][0] + g[2][1][0] - g[3][0][1]; \n"
1112                            "    tmp = tmp + g[4][0][0] * g[5][1][0] - g[6][1][1] + g[7][0][1]; \n"
1113                            "    tmp = tmp + a.z + +float(b.y) + float(c[0].x) - float(c[1].x) * float(c[2].y);   \n"
1114                            "    tmp = tmp + i[1][1];             \n"
1115                            "    gl_Position = position * tmp;    \n"
1116                            "}";
1117         }
1118
1119         virtual std::string FragmentShader()
1120         {
1121                 return "#version 310 es                \n"
1122                            "struct U {                     \n"
1123                            "   bool a[3];                  \n"
1124                            "   mediump vec4 b;                     \n"
1125                            "   mediump mat3 c;                     \n"
1126                            "   mediump float d[2];                 \n"
1127                            "};                             \n"
1128                            "struct UU {                    \n"
1129                            "   U a;                        \n"
1130                            "   U b[2];                     \n"
1131                            "   uvec2 c;                    \n"
1132                            "};                             \n"
1133                            "uniform mediump mat4 d;                \n"
1134                            "uniform mediump mat3 e;                \n"
1135                            "uniform mediump float h;               \n"
1136                            "uniform int f;                 \n"
1137                            "uniform U j;                   \n"
1138                            "uniform UU k;                  \n"
1139                            "uniform UU l[3];               \n"
1140                            "out mediump vec4 color;                \n"
1141                            "void main() {                  \n"
1142                            "    mediump float tmp;                 \n"
1143                            "    tmp = h + float(f) + e[2][2];           \n"
1144                            "    tmp = tmp + d[0][0] + j.b.x;     \n"
1145                            "    tmp = tmp + k.b[0].c[0][0];      \n"
1146                            "    tmp = tmp + l[2].a.c[0][1];      \n"
1147                            "    tmp = tmp + l[2].b[1].d[0];      \n"
1148                            "    tmp = tmp + float(l[0].c.x);            \n"
1149                            "    color = vec4(0, 1, 0, 1) * tmp;  \n"
1150                            "}";
1151         }
1152
1153         virtual long Run()
1154         {
1155                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1156                 glBindAttribLocation(program, 0, "position");
1157                 LinkProgram(program);
1158
1159                 long error = NO_ERROR;
1160
1161                 // only active structure members
1162                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1163                                                                         GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1164                 // l[2].b[1].d[0] and \0
1165                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 15, error);
1166
1167                 std::map<std::string, GLuint> indices;
1168                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a", error);
1169                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "b", error);
1170                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "c", error);
1171                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "d", error);
1172                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "e", error);
1173                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "f", error);
1174                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "g", error);
1175                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "h", error);
1176                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "i", error);
1177                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "j.b", error);
1178                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "k.b[0].c", error);
1179                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[0].c", error);
1180                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].b[1].d[0]", error);
1181                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].a.c", error);
1182
1183                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a"], "a", error);
1184                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["b"], "b", error);
1185                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["c"], "c[0]", error);
1186                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["d"], "d", error);
1187                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["e"], "e", error);
1188                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["f"], "f", error);
1189                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["g"], "g[0]", error);
1190                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["h"], "h", error);
1191                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["i"], "i", error);
1192                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["j.b"], "j.b", error);
1193                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["k.b[0].c"], "k.b[0].c", error);
1194                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[0].c"], "l[0].c", error);
1195                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], "l[2].b[1].d[0]", error);
1196                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].a.c"], "l[2].a.c", error);
1197
1198                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
1199                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", glGetUniformLocation(program, "b"), error);
1200                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", glGetUniformLocation(program, "c"), error);
1201                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", glGetUniformLocation(program, "d"), error);
1202                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", glGetUniformLocation(program, "e"), error);
1203                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "f", glGetUniformLocation(program, "f"), error);
1204                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "g", glGetUniformLocation(program, "g"), error);
1205                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "h", glGetUniformLocation(program, "h"), error);
1206                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "i", glGetUniformLocation(program, "i"), error);
1207                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "j.b", glGetUniformLocation(program, "j.b"), error);
1208                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "k.b[0].c", glGetUniformLocation(program, "k.b[0].c"),
1209                                                                                  error);
1210                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[0].c", glGetUniformLocation(program, "l[0].c"), error);
1211                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].b[1].d[0]",
1212                                                                                  glGetUniformLocation(program, "l[2].b[1].d[0]"), error);
1213                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].a.c", glGetUniformLocation(program, "l[2].a.c"),
1214                                                                                  error);
1215
1216                 GLenum props[] = { GL_NAME_LENGTH,
1217                                                    GL_TYPE,
1218                                                    GL_ARRAY_SIZE,
1219                                                    GL_OFFSET,
1220                                                    GL_BLOCK_INDEX,
1221                                                    GL_ARRAY_STRIDE,
1222                                                    GL_MATRIX_STRIDE,
1223                                                    GL_IS_ROW_MAJOR,
1224                                                    GL_ATOMIC_COUNTER_BUFFER_INDEX,
1225                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
1226                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
1227                                                    GL_REFERENCED_BY_VERTEX_SHADER,
1228                                                    GL_LOCATION };
1229                 GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "a") };
1230                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a"], 13, props, 13, expected, error);
1231                 GLint expected2[] = { 2, 35668, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "b") };
1232                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["b"], 13, props, 13, expected2, error);
1233                 GLint expected3[] = { 5, 36294, 3, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "c") };
1234                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["c"], 13, props, 13, expected3, error);
1235                 GLint expected4[] = { 2, 35676, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "d") };
1236                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["d"], 13, props, 13, expected4, error);
1237                 GLint expected5[] = { 2, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "e") };
1238                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["e"], 13, props, 13, expected5, error);
1239                 GLint expected6[] = { 2, 5124, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "f") };
1240                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["f"], 13, props, 13, expected6, error);
1241                 GLint expected7[] = { 5, 35674, 8, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "g") };
1242                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["g"], 13, props, 13, expected7, error);
1243                 GLint expected8[] = { 2, 5126, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "h") };
1244                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["h"], 13, props, 13, expected8, error);
1245                 GLint expected9[] = { 2, 35687, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "i") };
1246                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["i"], 13, props, 13, expected9, error);
1247                 GLint expected10[] = { 4, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "j.b") };
1248                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["j.b"], 13, props, 13, expected10, error);
1249                 GLint expected11[] = { 9, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "k.b[0].c") };
1250                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["k.b[0].c"], 13, props, 13, expected11, error);
1251                 GLint expected12[] = { 7, 36294, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[0].c") };
1252                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[0].c"], 13, props, 13, expected12, error);
1253                 GLint expected13[] = {
1254                         15, 5126, 2, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[2].b[1].d[0]")
1255                 };
1256                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], 13, props, 13, expected13, error);
1257                 GLint expected14[] = { 9, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[2].a.c") };
1258                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].a.c"], 13, props, 13, expected14, error);
1259
1260                 glDeleteProgram(program);
1261                 return error;
1262         }
1263 };
1264
1265 class UniformBlockTypes : public PIQBase
1266 {
1267         virtual std::string Title()
1268         {
1269                 return "Uniform Block Types Test";
1270         }
1271
1272         virtual std::string ShadersDesc()
1273         {
1274                 return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
1275         }
1276
1277         virtual std::string PurposeExt()
1278         {
1279                 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param.\n";
1280         }
1281
1282         virtual std::string VertexShader()
1283         {
1284                 return "#version 310 es                      \n"
1285                            "in vec4 position;                    \n"
1286                            ""
1287                            "uniform SimpleBlock {                \n"
1288                            "   mediump mat3x2 a;                         \n"
1289                            "   mediump mat4 b;                           \n"
1290                            "   vec4 c;                           \n"
1291                            "};                                   \n"
1292                            ""
1293                            "uniform NotSoSimpleBlockk {          \n"
1294                            "   ivec2 a[4];                       \n"
1295                            "   mediump mat3 b[2];                        \n"
1296                            "   mediump mat2 c;                           \n"
1297                            "} d;                                         \n"
1298                            ""
1299                            "void main(void)                                               \n"
1300                            "{                                                             \n"
1301                            "    mediump float tmp;                                        \n"
1302                            "    tmp =  a[0][1] * b[1][2] * c.x;                           \n"
1303                            "    tmp = tmp + float(d.a[2].y) + d.b[0][1][1] + d.c[1][1];   \n"
1304                            "    gl_Position = position * tmp;                             \n"
1305                            "}";
1306         }
1307
1308         virtual std::string FragmentShader()
1309         {
1310                 return "#version 310 es                \n"
1311                            "struct U {                     \n"
1312                            "   bool a[3];                  \n"
1313                            "   mediump vec4 b;                     \n"
1314                            "   mediump mat3 c;                     \n"
1315                            "   mediump float d[2];                 \n"
1316                            "};                             \n"
1317                            "struct UU {                    \n"
1318                            "   U a;                        \n"
1319                            "   U b[2];                     \n"
1320                            "   uvec2 c;                    \n"
1321                            "};                             \n"
1322                            ""
1323                            "uniform TrickyBlock {                            \n"
1324                            "   UU a[3];                                      \n"
1325                            "   mediump mat4 b;                               \n"
1326                            "   uint c;                                       \n"
1327                            "} e[2];                                          \n"
1328                            ""
1329                            "out mediump vec4 color;                        \n"
1330                            "void main() {                                  \n"
1331                            "    mediump float tmp;                         \n"
1332                            "    tmp = e[0].a[2].b[0].d[1] * float(e[1].c); \n"
1333                            "    color = vec4(0, 1, 0, 1) * tmp;            \n"
1334                            "}";
1335         }
1336
1337         virtual long Run()
1338         {
1339                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1340                 glBindAttribLocation(program, 0, "position");
1341                 LinkProgram(program);
1342
1343                 long error = NO_ERROR;
1344
1345                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1346                                                                         GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1347                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, 4, error);
1348                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
1349
1350                 std::map<std::string, GLuint> indicesUB;
1351                 std::map<std::string, GLuint> indicesU;
1352                 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "SimpleBlock", error);
1353                 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "NotSoSimpleBlockk", error);
1354                 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock", error);
1355                 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock[1]", error);
1356                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1357                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1358                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1359                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.a[0]", error);
1360                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.c", error);
1361                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.b[0]", error);
1362                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TrickyBlock.a[2].b[0].d", error);
1363
1364                 glUniformBlockBinding(program, indicesUB["SimpleBlock"], 0);
1365                 glUniformBlockBinding(program, indicesUB["NotSoSimpleBlockk"], 2);
1366                 glUniformBlockBinding(program, indicesUB["TrickyBlock"], 3);
1367                 glUniformBlockBinding(program, indicesUB["TrickyBlock[1]"], 4);
1368
1369                 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], "SimpleBlock", error);
1370                 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], "NotSoSimpleBlockk",
1371                                                                          error);
1372                 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], "TrickyBlock[0]", error);
1373                 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], "TrickyBlock[1]", error);
1374                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1375                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1376                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1377                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.a[0]"], "NotSoSimpleBlockk.a[0]",
1378                                                                          error);
1379                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.c"], "NotSoSimpleBlockk.c",
1380                                                                          error);
1381                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.b[0]"], "NotSoSimpleBlockk.b[0]",
1382                                                                          error);
1383                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"],
1384                                                                          "TrickyBlock.a[2].b[0].d[0]", error);
1385
1386                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1387                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1388                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1389
1390                 GLenum props[] = {
1391                         GL_NAME_LENGTH,
1392                         GL_BUFFER_BINDING,
1393                         GL_REFERENCED_BY_COMPUTE_SHADER,
1394                         GL_REFERENCED_BY_FRAGMENT_SHADER,
1395                         GL_REFERENCED_BY_VERTEX_SHADER,
1396                         GL_BUFFER_DATA_SIZE,
1397                 };
1398                 GLint size;
1399                 glGetActiveUniformBlockiv(program, indicesUB["SimpleBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1400                 GLint expected[] = { 12, 0, 0, 0, 1, size };
1401                 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 6, props, 6, expected, error);
1402                 glGetActiveUniformBlockiv(program, indicesUB["NotSoSimpleBlockk"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1403                 GLint expected2[] = { 18, 2, 0, 0, 1, size };
1404                 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 6, props, 6, expected2,
1405                                                                    error);
1406                 glGetActiveUniformBlockiv(program, indicesUB["TrickyBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1407                 GLint expected3[] = { 15, 3, 0, 1, 0, size };
1408                 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], 6, props, 6, expected3, error);
1409                 GLint expected4[] = { 15, 4, 0, 1, 0, size };
1410                 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], 6, props, 6, expected4,
1411                                                                    error);
1412
1413                 GLenum props2[] = { GL_NAME_LENGTH,
1414                                                         GL_TYPE,
1415                                                         GL_ARRAY_SIZE,
1416                                                         GL_BLOCK_INDEX,
1417                                                         GL_ARRAY_STRIDE,
1418                                                         GL_IS_ROW_MAJOR,
1419                                                         GL_ATOMIC_COUNTER_BUFFER_INDEX,
1420                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
1421                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
1422                                                         GL_REFERENCED_BY_VERTEX_SHADER,
1423                                                         GL_LOCATION };
1424                 GLint expected5[] = { 2, 35687, 1, static_cast<GLint>(indicesUB["SimpleBlock"]), 0, 0, -1, 0, 0, 1, -1 };
1425                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 11, props2, 11, expected5, error);
1426                 GLenum props3[] = { GL_NAME_LENGTH,
1427                                                         GL_TYPE,
1428                                                         GL_ARRAY_SIZE,
1429                                                         GL_BLOCK_INDEX,
1430                                                         GL_MATRIX_STRIDE,
1431                                                         GL_IS_ROW_MAJOR,
1432                                                         GL_ATOMIC_COUNTER_BUFFER_INDEX,
1433                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
1434                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
1435                                                         GL_REFERENCED_BY_VERTEX_SHADER,
1436                                                         GL_LOCATION };
1437                 GLint expected6[] = { 27, 5126, 2, static_cast<GLint>(indicesUB["TrickyBlock"]), 0, 0, -1, 0, 1, 0, -1 };
1438                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"], 11, props3, 11, expected6,
1439                                                                    error);
1440
1441                 GLenum                   prop   = GL_ACTIVE_VARIABLES;
1442                 const GLsizei   bufSize = 1000;
1443                 GLsizei                  length;
1444                 GLint                    param[bufSize];
1445                 std::set<GLuint> exp;
1446                 exp.insert(indicesU["a"]);
1447                 exp.insert(indicesU["b"]);
1448                 exp.insert(indicesU["c"]);
1449                 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 1, &prop, bufSize, &length, param);
1450                 for (int i = 0; i < length; ++i)
1451                 {
1452                         if (exp.find(param[i]) == exp.end())
1453                         {
1454                                 m_context.getTestContext().getLog()
1455                                         << tcu::TestLog::Message
1456                                         << "Unexpected index found in active variables of SimpleBlock: " << param[i]
1457                                         << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1458                                         << tcu::TestLog::EndMessage;
1459                                 glDeleteProgram(program);
1460                                 return ERROR;
1461                         }
1462                         else if (length != 3)
1463                         {
1464                                 m_context.getTestContext().getLog()
1465                                         << tcu::TestLog::Message
1466                                         << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1467                                         << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1468                                 glDeleteProgram(program);
1469                                 return ERROR;
1470                         }
1471                 }
1472                 std::set<GLuint> exp2;
1473                 exp2.insert(indicesU["NotSoSimpleBlockk.a[0]"]);
1474                 exp2.insert(indicesU["NotSoSimpleBlockk.b[0]"]);
1475                 exp2.insert(indicesU["NotSoSimpleBlockk.c"]);
1476                 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 1, &prop, bufSize, &length,
1477                                                            param);
1478                 for (int i = 0; i < length; ++i)
1479                 {
1480                         if (exp2.find(param[i]) == exp2.end())
1481                         {
1482                                 m_context.getTestContext().getLog()
1483                                         << tcu::TestLog::Message
1484                                         << "Unexpected index found in active variables of NotSoSimpleBlockk: " << param[i]
1485                                         << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1486                                         << tcu::TestLog::EndMessage;
1487                                 glDeleteProgram(program);
1488                                 return ERROR;
1489                         }
1490                         else if (length != 3)
1491                         {
1492                                 m_context.getTestContext().getLog()
1493                                         << tcu::TestLog::Message
1494                                         << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1495                                         << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1496                                 glDeleteProgram(program);
1497                                 return ERROR;
1498                         }
1499                 }
1500
1501                 GLint res;
1502                 glGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
1503                 if (res < 3)
1504                 {
1505                         m_context.getTestContext().getLog()
1506                                 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!"
1507                                 << tcu::TestLog::EndMessage;
1508                         glDeleteProgram(program);
1509                         return ERROR;
1510                 }
1511
1512                 glDeleteProgram(program);
1513                 return error;
1514         }
1515 };
1516
1517 class TransformFeedbackTypes : public SimpleShaders
1518 {
1519         virtual std::string Title()
1520         {
1521                 return "Transform Feedback Varying Types";
1522         }
1523
1524         virtual std::string ShadersDesc()
1525         {
1526                 return "fallthrough fragment and vertex shaders with different types of out variables used";
1527         }
1528
1529         virtual std::string PurposeExt()
1530         {
1531                 return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n";
1532         }
1533
1534         virtual std::string VertexShader()
1535         {
1536                 return "#version 310 es                      \n"
1537                            "in vec4 position;                    \n"
1538                            ""
1539                            "flat out highp vec4 a;               \n"
1540                            "out mediump float b[2];              \n"
1541                            "flat out highp uvec2 c;              \n"
1542                            "flat out highp uint d;               \n"
1543                            "out mediump vec3 e[2];               \n"
1544                            "flat out int f;                      \n"
1545                            ""
1546                            "void main(void)                      \n"
1547                            "{                                    \n"
1548                            "   vec4 pos;                         \n"
1549                            "   a = vec4(1);                      \n"
1550                            "   b[0] = 1.1;                       \n"
1551                            "   b[1] = 1.1;                       \n"
1552                            "   c = uvec2(1u);                    \n"
1553                            "   d = 1u;                           \n"
1554                            "   e[0] = vec3(1.1);                 \n"
1555                            "   e[1] = vec3(1.1);                 \n"
1556                            "   f = 1;                            \n"
1557                            "   gl_Position = position;           \n"
1558                            "}";
1559         }
1560
1561         virtual long Run()
1562         {
1563                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1564                 glBindAttribLocation(program, 0, "position");
1565                 const char* varyings[6] = { "a", "b[0]", "b[1]", "c", "d", "e" };
1566                 glTransformFeedbackVaryings(program, 6, varyings, GL_INTERLEAVED_ATTRIBS);
1567                 LinkProgram(program);
1568
1569                 long error = NO_ERROR;
1570
1571                 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 6, error);
1572                 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 5, error);
1573
1574                 std::map<std::string, GLuint> indices;
1575                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error);
1576                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[0]", error);
1577                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[1]", error);
1578                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error);
1579                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error);
1580                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error);
1581
1582                 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error);
1583                 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], "b[0]", error);
1584                 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], "b[1]", error);
1585                 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error);
1586                 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error);
1587                 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error);
1588
1589                 GLenum props[]  = { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE };
1590                 GLint  expected[] = { 2, 35666, 1 };
1591                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error);
1592                 GLint expected2[] = { 5, 5126, 1 };
1593                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], 3, props, 3, expected2,
1594                                                                    error);
1595                 GLint expected3[] = { 5, 5126, 1 };
1596                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], 3, props, 3, expected3,
1597                                                                    error);
1598                 GLint expected4[] = { 2, 36294, 1 };
1599                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected4, error);
1600                 GLint expected5[] = { 2, 5125, 1 };
1601                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected5, error);
1602                 GLint expected6[] = { 2, 35665, 2 };
1603                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected6, error);
1604
1605                 glDeleteProgram(program);
1606                 return error;
1607         }
1608 };
1609
1610 class AtomicCounterSimple : public ComputeShaderTest
1611 {
1612 public:
1613         virtual std::string Title()
1614         {
1615                 return "Atomic Counter Buffer Simple Test";
1616         }
1617
1618         virtual std::string ShadersDesc()
1619         {
1620                 return "compute shader with atomic counters used";
1621         }
1622
1623         virtual std::string PurposeExt()
1624         {
1625                 return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1626         }
1627
1628         virtual long Run()
1629         {
1630
1631                 GLint max_buffer_bindings = 0;
1632                 glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings);
1633                 if (max_buffer_bindings < 6)
1634                 {
1635                         OutputNotSupported("Test requires at least 6 atomic counter buffer binding points.");
1636                         return NOT_SUPPORTED;
1637                 }
1638
1639                 const char* const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in;  \n"
1640                                                                         "layout(std430) buffer Output {                  \n"
1641                                                                         "   mediump vec4 data;                           \n"
1642                                                                         "} g_out;                                        \n"
1643                                                                         ""
1644                                                                         "layout (binding = 1, offset = 0) uniform highp atomic_uint a;    \n"
1645                                                                         "layout (binding = 2, offset = 0) uniform highp atomic_uint b;    \n"
1646                                                                         "layout (binding = 2, offset = 4) uniform highp atomic_uint c;    \n"
1647                                                                         "layout (binding = 5, offset = 0) uniform highp atomic_uint d[3]; \n"
1648                                                                         "layout (binding = 5, offset = 12) uniform highp atomic_uint e;   \n"
1649                                                                         ""
1650                                                                         "void main() {                                                         \n"
1651                                                                         "   uint x = atomicCounterIncrement(d[0]) + atomicCounterIncrement(a); \n"
1652                                                                         "   uint y = atomicCounterIncrement(d[1]) + atomicCounterIncrement(b); \n"
1653                                                                         "   uint z = atomicCounterIncrement(d[2]) + atomicCounterIncrement(c); \n"
1654                                                                         "   uint w = atomicCounterIncrement(e);                                \n"
1655                                                                         "   g_out.data = vec4(float(x), float(y), float(z), float(w));         \n"
1656                                                                         "}";
1657
1658                 GLuint program = CreateComputeProgram(glsl_cs);
1659                 glLinkProgram(program);
1660                 if (!CheckProgram(program))
1661                 {
1662                         glDeleteProgram(program);
1663                         return ERROR;
1664                 }
1665                 glUseProgram(program);
1666
1667                 long error = NO_ERROR;
1668
1669                 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 3, error);
1670                 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 2, error);
1671
1672                 std::map<std::string, GLuint> indicesU;
1673                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1674                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1675                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1676                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "d", error);
1677                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "e", error);
1678
1679                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1680                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1681                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1682                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["d"], "d[0]", error);
1683                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["e"], "e", error);
1684
1685                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1686                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1687                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1688                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", -1, error);
1689                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", -1, error);
1690                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[0]", -1, error);
1691                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[1]", -1, error);
1692                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[2]", -1, error);
1693
1694                 GLenum            prop  = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1695                 const GLsizei bufSize = 1000;
1696                 GLsizei           length;
1697                 GLint             res;
1698                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1699
1700                 GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES, GL_ACTIVE_VARIABLES };
1701                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1702                 GLint expected[] = { 1, 4, 1, static_cast<GLint>(indicesU["a"]) };
1703                 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 4, props, 4, expected, error);
1704
1705                 GLenum props2[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES };
1706                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1707                 GLint expected2[] = { 2, 8, 2 };
1708                 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1709                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["c"], 1, &prop, bufSize, &length, &res);
1710                 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1711
1712                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1713                 GLint expected3[] = { 5, 16, 2 };
1714                 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1715                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["e"], 1, &prop, bufSize, &length, &res);
1716                 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1717
1718                 GLenum                   prop2 = GL_ACTIVE_VARIABLES;
1719                 GLint                    param[bufSize];
1720                 std::set<GLuint> exp;
1721                 exp.insert(indicesU["b"]);
1722                 exp.insert(indicesU["c"]);
1723                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1724                 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
1725                 for (int i = 0; i < length; ++i)
1726                 {
1727                         if (exp.find(param[i]) == exp.end() || length != 2)
1728                         {
1729                                 m_context.getTestContext().getLog()
1730                                         << tcu::TestLog::Message << "Length: " << length
1731                                         << "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
1732                                         << tcu::TestLog::EndMessage;
1733                                 glDeleteProgram(program);
1734                                 return ERROR;
1735                         }
1736                 }
1737                 std::set<GLuint> exp2;
1738                 GLint                    param2[bufSize];
1739                 exp2.insert(indicesU["d"]);
1740                 exp2.insert(indicesU["e"]);
1741                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1742                 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param2);
1743                 for (int i = 0; i < length; ++i)
1744                 {
1745                         if (exp2.find(param2[i]) == exp2.end() || length != 2)
1746                         {
1747                                 m_context.getTestContext().getLog()
1748                                         << tcu::TestLog::Message << "Length: " << length
1749                                         << "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param2[i]
1750                                         << tcu::TestLog::EndMessage;
1751                                 glDeleteProgram(program);
1752                                 return ERROR;
1753                         }
1754                 }
1755
1756                 glDeleteProgram(program);
1757                 return error;
1758         }
1759 };
1760
1761 class AtomicCounterSimpleOneBuffer : public ComputeShaderTest
1762 {
1763 public:
1764         virtual std::string Title()
1765         {
1766                 return "Atomic Counter Buffer Simple One Buffer Test";
1767         }
1768
1769         virtual std::string ShadersDesc()
1770         {
1771                 return "compute shader with atomic counters used";
1772         }
1773
1774         virtual std::string PurposeExt()
1775         {
1776                 return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1777         }
1778
1779         virtual long Run()
1780         {
1781
1782                 GLint max_buffer_bindings = 0;
1783                 glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings);
1784                 if (max_buffer_bindings < 3)
1785                 {
1786                         OutputNotSupported("Test requires at least 3 atomic counter buffer binding points.");
1787                         return NOT_SUPPORTED;
1788                 }
1789
1790                 const char* const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in;  \n"
1791                                                                         "layout(std430) buffer Output {                  \n"
1792                                                                         "   mediump vec4 data;                           \n"
1793                                                                         "} g_out;                                        \n"
1794                                                                         ""
1795                                                                         "layout (binding = 0, offset = 0) uniform highp atomic_uint a;    \n"
1796                                                                         "layout (binding = 0, offset = 4) uniform highp atomic_uint b[3]; \n"
1797                                                                         "layout (binding = 0, offset = 16) uniform highp atomic_uint c;   \n"
1798                                                                         ""
1799                                                                         "void main() {                                                         \n"
1800                                                                         "   uint x = atomicCounterIncrement(b[0]) + atomicCounterIncrement(a); \n"
1801                                                                         "   uint y = atomicCounterIncrement(b[1]) + atomicCounterIncrement(a); \n"
1802                                                                         "   uint z = atomicCounterIncrement(b[2]) + atomicCounterIncrement(a); \n"
1803                                                                         "   uint w = atomicCounterIncrement(c);                                \n"
1804                                                                         "   g_out.data = vec4(float(x), float(y), float(z), float(w));         \n"
1805                                                                         "}";
1806
1807                 GLuint program = CreateComputeProgram(glsl_cs);
1808                 glLinkProgram(program);
1809                 if (!CheckProgram(program))
1810                 {
1811                         glDeleteProgram(program);
1812                         return ERROR;
1813                 }
1814                 glUseProgram(program);
1815
1816                 long error = NO_ERROR;
1817
1818                 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 1, error);
1819                 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 3, error);
1820
1821                 std::map<std::string, GLuint> indicesU;
1822                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1823                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1824                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1825
1826                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1827                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b[0]", error);
1828                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1829
1830                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1831                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1832                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1833                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[0]", -1, error);
1834                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[1]", -1, error);
1835                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[2]", -1, error);
1836
1837                 GLenum            prop  = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1838                 const GLsizei bufSize = 1000;
1839                 GLsizei           length;
1840                 GLint             res;
1841
1842                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1843                 if (res != 0)
1844                 {
1845                         m_context.getTestContext().getLog()
1846                                 << tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage;
1847                         glDeleteProgram(program);
1848                         return ERROR;
1849                 }
1850
1851                 GLenum props[]  = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES };
1852                 GLint  expected[] = { 0, 20, 3 };
1853                 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props, 3, expected, error);
1854
1855                 GLenum                   prop2 = GL_ACTIVE_VARIABLES;
1856                 GLint                    param[bufSize];
1857                 std::set<GLuint> exp;
1858                 exp.insert(indicesU["a"]);
1859                 exp.insert(indicesU["b"]);
1860                 exp.insert(indicesU["c"]);
1861
1862                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1863                 if (res != 0)
1864                 {
1865                         m_context.getTestContext().getLog()
1866                                 << tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage;
1867                         glDeleteProgram(program);
1868                         return ERROR;
1869                 }
1870
1871                 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
1872                 for (int i = 0; i < length; ++i)
1873                 {
1874                         if (exp.find(param[i]) == exp.end() || length != 3)
1875                         {
1876                                 m_context.getTestContext().getLog()
1877                                         << tcu::TestLog::Message << "Length: " << length
1878                                         << "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
1879                                         << tcu::TestLog::EndMessage;
1880                                 glDeleteProgram(program);
1881                                 return ERROR;
1882                         }
1883                 }
1884
1885                 glDeleteProgram(program);
1886                 return error;
1887         }
1888 };
1889
1890 class InvalidValueTest : public SimpleShaders
1891 {
1892         virtual std::string Title()
1893         {
1894                 return "Invalid Value Test";
1895         }
1896
1897         virtual std::string PassCriteria()
1898         {
1899                 return "GL_INVALID_VALUE error is generated after every function call.";
1900         }
1901
1902         virtual std::string Purpose()
1903         {
1904                 return "Verify that wrong use of functions generates GL_INVALID_VALUE as described in spec.";
1905         }
1906
1907         virtual std::string Method()
1908         {
1909                 return "Call functions with invalid values and check if GL_INVALID_VALUE was generated.";
1910         }
1911
1912         virtual long Run()
1913         {
1914                 long error = NO_ERROR;
1915
1916                 GLint   res;
1917                 GLsizei len               = 0;
1918                 GLchar  name[100] = { '\0' };
1919                 GLenum  props[1]  = { GL_NAME_LENGTH };
1920
1921                 m_context.getTestContext().getLog()
1922                         << tcu::TestLog::Message << "Case 1: <program> not a name of shader/program object"
1923                         << tcu::TestLog::EndMessage;
1924                 glGetProgramInterfaceiv(1337u, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
1925                 ExpectError(GL_INVALID_VALUE, error);
1926                 glGetProgramResourceIndex(31337u, GL_PROGRAM_INPUT, "pie");
1927                 ExpectError(GL_INVALID_VALUE, error);
1928                 glGetProgramResourceName(1337u, GL_PROGRAM_INPUT, 0, 1024, &len, name);
1929                 ExpectError(GL_INVALID_VALUE, error);
1930                 glGetProgramResourceiv(1337u, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
1931                 ExpectError(GL_INVALID_VALUE, error);
1932                 glGetProgramResourceLocation(1337u, GL_PROGRAM_INPUT, "pie");
1933                 ExpectError(GL_INVALID_VALUE, error);
1934                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage;
1935
1936                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1937                 glBindAttribLocation(program, 0, "position");
1938                 LinkProgram(program);
1939
1940                 m_context.getTestContext().getLog()
1941                         << tcu::TestLog::Message
1942                         << "Case 2: <index> is greater than the number of the active resources in GetProgramResourceName"
1943                         << tcu::TestLog::EndMessage;
1944                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage;
1945                 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 3000, 1024, &len, name);
1946                 ExpectError(GL_INVALID_VALUE, error);
1947                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2: finished" << tcu::TestLog::EndMessage;
1948
1949                 m_context.getTestContext().getLog()
1950                         << tcu::TestLog::Message << "Case 3: <propCount> is zero in GetProgramResourceiv"
1951                         << tcu::TestLog::EndMessage;
1952                 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 0, props, 1024, &len, &res);
1953                 ExpectError(GL_INVALID_VALUE, error);
1954                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3: finished" << tcu::TestLog::EndMessage;
1955
1956                 std::string str = "position";
1957                 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, -100, NULL, const_cast<char*>(str.c_str()));
1958                 ExpectError(GL_INVALID_VALUE, error);
1959                 GLenum prop = GL_NAME_LENGTH;
1960                 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, &prop, -100, &len, &res);
1961                 ExpectError(GL_INVALID_VALUE, error);
1962
1963                 glDeleteProgram(program);
1964                 return error;
1965         }
1966 };
1967
1968 class InvalidEnumTest : public SimpleShaders
1969 {
1970         virtual std::string Title()
1971         {
1972                 return "Invalid Enum Test";
1973         }
1974
1975         virtual std::string PassCriteria()
1976         {
1977                 return "GL_INVALID_ENUM error is generated after every function call.";
1978         }
1979
1980         virtual std::string Purpose()
1981         {
1982                 return "Verify that wrong use of functions generates GL_INVALID_ENUM as described in spec.";
1983         }
1984
1985         virtual std::string Method()
1986         {
1987                 return "Call functions with invalid enums and check if GL_INVALID_ENUM was generated.";
1988         }
1989
1990         // make sure at least one atomic counter resource is active
1991         virtual std::string FragmentShader()
1992         {
1993                 return "#version 310 es                                        \n"
1994                            "layout (binding = 0, offset = 0) uniform highp atomic_uint a;\n"
1995                            "out mediump vec4 outColor;                             \n"
1996                            "void main(void) {                                      \n"
1997                            "   uint b = atomicCounterIncrement(a);                 \n"
1998                            "   outColor = vec4(float(b));                          \n"
1999                            "}                                                      \n";
2000         }
2001
2002         virtual long Run()
2003         {
2004                 GLint max_buffers = 0, max_counters = 0;
2005                 glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &max_buffers);
2006                 glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, &max_counters);
2007                 if (max_buffers < 1 || max_counters < 1)
2008                 {
2009                         OutputNotSupported("Test requires at least 1 atomic counter.");
2010                         return NOT_SUPPORTED;
2011                 }
2012
2013                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2014                 glBindAttribLocation(program, 0, "position");
2015                 LinkProgram(program);
2016
2017                 long error = NO_ERROR;
2018
2019                 GLint   res;
2020                 GLsizei len               = 0;
2021                 GLchar  name[100] = { '\0' };
2022                 GLenum  props[1]  = { GL_TEXTURE_1D };
2023
2024                 m_context.getTestContext().getLog()
2025                         << tcu::TestLog::Message << "Case 1: <programInterface> is ATOMIC_COUNTER_BUFFER in "
2026                                                                                 "GetProgramResourceIndex or GetProgramResourceName"
2027                         << tcu::TestLog::EndMessage;
2028                 glGetProgramResourceIndex(program, GL_ATOMIC_COUNTER_BUFFER, name);
2029                 ExpectError(GL_INVALID_ENUM, error);
2030                 glGetProgramResourceName(program, GL_ATOMIC_COUNTER_BUFFER, 0, 1024, &len, name);
2031                 ExpectError(GL_INVALID_ENUM, error);
2032                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2033
2034                 m_context.getTestContext().getLog()
2035                         << tcu::TestLog::Message
2036                         << "Case 2: <props> is not a property name supported by the command GetProgramResourceiv"
2037                         << tcu::TestLog::EndMessage;
2038                 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2039                 ExpectError(GL_INVALID_ENUM, error);
2040                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2041
2042                 glGetProgramResourceLocation(program, GL_ATOMIC_COUNTER_BUFFER, "position");
2043                 ExpectError(GL_INVALID_ENUM, error);
2044
2045                 glDeleteProgram(program);
2046                 return error;
2047         }
2048 };
2049
2050 class InvalidOperationTest : public SimpleShaders
2051 {
2052         virtual std::string Title()
2053         {
2054                 return "Invalid Operation Test";
2055         }
2056
2057         virtual std::string PassCriteria()
2058         {
2059                 return "GL_INVALID_OPERATION error is generated after every function call.";
2060         }
2061
2062         virtual std::string Purpose()
2063         {
2064                 return "Verify that wrong use of functions generates GL_INVALID_OPERATION as described in spec.";
2065         }
2066
2067         virtual std::string Method()
2068         {
2069                 return "Perform invalid operation and check if GL_INVALID_OPERATION was generated.";
2070         }
2071
2072         virtual long Run()
2073         {
2074                 long error = NO_ERROR;
2075
2076                 GLuint program  = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2077                 GLuint program2 = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2078                 glBindAttribLocation(program, 0, "position");
2079                 LinkProgram(program);
2080
2081                 const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
2082                 GLint            res;
2083                 GLsizei          len       = 0;
2084                 GLchar           name[100] = { '\0' };
2085                 GLenum           props[1]  = { GL_OFFSET };
2086
2087                 m_context.getTestContext().getLog()
2088                         << tcu::TestLog::Message << "Case 1: <program> is the name of a shader object" << tcu::TestLog::EndMessage;
2089                 glGetProgramInterfaceiv(sh, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2090                 ExpectError(GL_INVALID_OPERATION, error);
2091                 glGetProgramResourceIndex(sh, GL_PROGRAM_INPUT, "pie");
2092                 ExpectError(GL_INVALID_OPERATION, error);
2093                 glGetProgramResourceName(sh, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2094                 ExpectError(GL_INVALID_OPERATION, error);
2095                 glGetProgramResourceiv(sh, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2096                 ExpectError(GL_INVALID_OPERATION, error);
2097                 glGetProgramResourceLocation(sh, GL_PROGRAM_INPUT, "pie");
2098                 ExpectError(GL_INVALID_OPERATION, error);
2099                 glDeleteShader(sh);
2100                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2101
2102                 m_context.getTestContext().getLog()
2103                         << tcu::TestLog::Message << "Case 2: <pname> is not supported in GetProgramInterfaceiv"
2104                         << tcu::TestLog::EndMessage;
2105                 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2106                 ExpectError(GL_INVALID_OPERATION, error);
2107                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2108
2109                 m_context.getTestContext().getLog()
2110                         << tcu::TestLog::Message << "Case 3: <props> is not supported in GetProgramResourceiv"
2111                         << tcu::TestLog::EndMessage;
2112                 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2113                 ExpectError(GL_INVALID_OPERATION, error);
2114                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3 finished" << tcu::TestLog::EndMessage;
2115
2116                 m_context.getTestContext().getLog()
2117                         << tcu::TestLog::Message << "Case 4: <program> has not been linked in GetProgramResourceLocation"
2118                         << tcu::TestLog::EndMessage;
2119                 glGetProgramResourceLocation(program2, GL_PROGRAM_INPUT, "pie");
2120                 ExpectError(GL_INVALID_OPERATION, error);
2121                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 4 finished" << tcu::TestLog::EndMessage;
2122
2123                 glDeleteProgram(program);
2124                 glDeleteProgram(program2);
2125                 return error;
2126         }
2127 };
2128
2129 class ShaderStorageBlock : public ComputeShaderTest
2130 {
2131         virtual std::string Title()
2132         {
2133                 return "Shader Storage Block Test";
2134         }
2135
2136         virtual std::string ShadersDesc()
2137         {
2138                 return "compute shader different types of storage blocks used";
2139         }
2140
2141         virtual std::string PurposeExt()
2142         {
2143                 return "\n\n Purpose is to verify calls using GL_BUFFER_VARIABLE and GL_SHADER_STORAGE_BLOCK as an interface "
2144                            "params.\n";
2145         }
2146
2147         virtual std::string ComputeShader()
2148         {
2149                 return "layout(local_size_x = 1, local_size_y = 1) in;  \n"
2150                            "layout(std430) buffer Output {                  \n"
2151                            "   mediump vec4 data;                           \n"
2152                            "} g_out;                                        \n"
2153                            ""
2154                            "struct U {                     \n"
2155                            "   bool a[3];                  \n"
2156                            "   mediump vec4 b;                     \n"
2157                            "   mediump mat3 c;                     \n"
2158                            "   mediump float d[2];                 \n"
2159                            "};                             \n"
2160                            "struct UU {                    \n"
2161                            "   U a;                        \n"
2162                            "   U b[2];                     \n"
2163                            "   uvec2 c;                    \n"
2164                            "};                             \n"
2165                            ""
2166                            "layout(binding=4) buffer TrickyBuffer {          \n"
2167                            "   UU a[3];                                      \n"
2168                            "   mediump mat4 b;                               \n"
2169                            "   uint c;                                       \n"
2170                            "} e[2];                                          \n"
2171                            ""
2172                            "layout(binding = 0) buffer SimpleBuffer {                \n"
2173                            "   mediump mat3x2 a;                                     \n"
2174                            "   mediump mat4 b;                                       \n"
2175                            "   mediump vec4 c;                                       \n"
2176                            "};                                                       \n"
2177                            ""
2178                            "layout(binding = 1) buffer NotSoSimpleBuffer {           \n"
2179                            "   ivec2 a[4];                                           \n"
2180                            "   mediump mat3 b[2];                                    \n"
2181                            "   mediump mat2 c;                                       \n"
2182                            "} d;                                                     \n"
2183                            ""
2184                            "void main() {                                    \n"
2185                            "    mediump float tmp;                           \n"
2186                            "    mediump float tmp2;                          \n"
2187                            "    tmp = e[0].a[0].b[0].d[0] * float(e[1].c);   \n"
2188                            "    tmp2 = a[0][0] * b[0][0] * c.x;                                \n"
2189                            "    tmp2 = tmp2 + float(d.a[0].y) + d.b[0][0][0] + d.c[0][0];      \n"
2190                            "    g_out.data = vec4(0, 1, 0, 1) * tmp * tmp2;                    \n"
2191                            "}";
2192         }
2193
2194         virtual long Run()
2195         {
2196                 GLuint program = CreateComputeProgram(ComputeShader());
2197                 glLinkProgram(program);
2198                 if (!CheckProgram(program))
2199                 {
2200                         glDeleteProgram(program);
2201                         return ERROR;
2202                 }
2203                 glUseProgram(program);
2204
2205                 long error = NO_ERROR;
2206
2207                 GLint res;
2208                 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 28, error);
2209                 glGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &res);
2210                 if (res < 7)
2211                 {
2212                         m_context.getTestContext().getLog()
2213                                 << tcu::TestLog::Message
2214                                 << "Error on: glGetProgramInterfaceiv, if: GL_BUFFER_VARIABLE, param: GL_ACTIVE_RESOURCES\n"
2215                                 << "Expected value greater or equal to 7, got " << res << tcu::TestLog::EndMessage;
2216                         glDeleteProgram(program);
2217                         return ERROR;
2218                 }
2219                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 5, error);
2220                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
2221
2222                 std::map<std::string, GLuint> indicesSSB;
2223                 std::map<std::string, GLuint> indicesBV;
2224                 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
2225                 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "NotSoSimpleBuffer", error);
2226                 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer", error);
2227                 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer[1]", error);
2228                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a", error);
2229                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "b", error);
2230                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "c", error);
2231                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.a[0]", error);
2232                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.c", error);
2233                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.b[0]", error);
2234                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.a[0].b[0].d", error);
2235                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.b", error);
2236                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.c", error);
2237
2238                 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer",
2239                                                                          error);
2240                 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"],
2241                                                                          "NotSoSimpleBuffer", error);
2242                 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], "TrickyBuffer[0]",
2243                                                                          error);
2244                 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], "TrickyBuffer[1]",
2245                                                                          error);
2246                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
2247                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["b"], "b", error);
2248                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["c"], "c", error);
2249                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.a[0]"],
2250                                                                          "NotSoSimpleBuffer.a[0]", error);
2251                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.c"],
2252                                                                          "NotSoSimpleBuffer.c", error);
2253                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.b[0]"],
2254                                                                          "NotSoSimpleBuffer.b[0]", error);
2255                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"],
2256                                                                          "TrickyBuffer.a[0].b[0].d[0]", error);
2257                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.b"], "TrickyBuffer.b", error);
2258                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.c"], "TrickyBuffer.c", error);
2259
2260                 GLenum props[] = { GL_NAME_LENGTH,
2261                                                    GL_BUFFER_BINDING,
2262                                                    GL_NUM_ACTIVE_VARIABLES,
2263                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
2264                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
2265                                                    GL_REFERENCED_BY_VERTEX_SHADER };
2266                 GLint expected[] = { 13, 0, 3, 1, 0, 0 };
2267                 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 6, props, 6, expected,
2268                                                                    error);
2269                 GLenum props2[] = { GL_NAME_LENGTH, GL_BUFFER_BINDING, GL_REFERENCED_BY_COMPUTE_SHADER,
2270                                                         GL_REFERENCED_BY_FRAGMENT_SHADER, GL_REFERENCED_BY_VERTEX_SHADER };
2271                 GLint expected2[] = { 18, 1, 1, 0, 0 };
2272                 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 5, props2, 5,
2273                                                                    expected2, error);
2274                 GLint expected3[] = { 16, 4, 1, 0, 0 };
2275                 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], 5, props2, 5,
2276                                                                    expected3, error);
2277                 GLint expected4[] = { 16, 5, 1, 0, 0 };
2278                 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], 5, props2, 5,
2279                                                                    expected4, error);
2280
2281                 GLenum props3[] = { GL_NAME_LENGTH,
2282                                                         GL_TYPE,
2283                                                         GL_ARRAY_SIZE,
2284                                                         GL_BLOCK_INDEX,
2285                                                         GL_ARRAY_STRIDE,
2286                                                         GL_IS_ROW_MAJOR,
2287                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
2288                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
2289                                                         GL_REFERENCED_BY_VERTEX_SHADER,
2290                                                         GL_TOP_LEVEL_ARRAY_SIZE,
2291                                                         GL_TOP_LEVEL_ARRAY_STRIDE };
2292                 GLint expected5[] = { 2, 35687, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 1, 0, 0, 1, 0 };
2293                 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a"], 11, props3, 11, expected5, error);
2294                 GLenum props4[] = { GL_NAME_LENGTH,
2295                                                         GL_TYPE,
2296                                                         GL_ARRAY_SIZE,
2297                                                         GL_BLOCK_INDEX,
2298                                                         GL_MATRIX_STRIDE,
2299                                                         GL_IS_ROW_MAJOR,
2300                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
2301                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
2302                                                         GL_REFERENCED_BY_VERTEX_SHADER,
2303                                                         GL_TOP_LEVEL_ARRAY_SIZE };
2304                 GLint expected6[] = { 28, 5126, 2, static_cast<GLint>(indicesSSB["TrickyBuffer"]), 0, 0, 1, 0, 0, 3 };
2305                 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"], 10, props4, 10,
2306                                                                    expected6, error);
2307
2308                 GLenum                   prop   = GL_ACTIVE_VARIABLES;
2309                 const GLsizei   bufSize = 1000;
2310                 GLsizei                  length;
2311                 GLint                    param[bufSize];
2312                 std::set<GLuint> exp;
2313                 exp.insert(indicesBV["a"]);
2314                 exp.insert(indicesBV["b"]);
2315                 exp.insert(indicesBV["c"]);
2316                 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 1, &prop, bufSize, &length,
2317                                                            param);
2318                 for (int i = 0; i < length; ++i)
2319                 {
2320                         if (exp.find(param[i]) == exp.end())
2321                         {
2322                                 m_context.getTestContext().getLog()
2323                                         << tcu::TestLog::Message
2324                                         << "Unexpected index found in active variables of SimpleBuffer: " << param[i]
2325                                         << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
2326                                            "GL_SHADER_STORAGE_BLOCK"
2327                                         << tcu::TestLog::EndMessage;
2328                                 glDeleteProgram(program);
2329                                 return ERROR;
2330                         }
2331                         else if (length != 3)
2332                         {
2333                                 m_context.getTestContext().getLog()
2334                                         << tcu::TestLog::Message
2335                                         << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK"
2336                                         << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
2337                                 glDeleteProgram(program);
2338                                 return ERROR;
2339                         }
2340                 }
2341                 std::set<GLuint> exp2;
2342                 exp2.insert(indicesBV["NotSoSimpleBuffer.a[0]"]);
2343                 exp2.insert(indicesBV["NotSoSimpleBuffer.b[0]"]);
2344                 exp2.insert(indicesBV["NotSoSimpleBuffer.c"]);
2345                 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 1, &prop, bufSize,
2346                                                            &length, param);
2347                 for (int i = 0; i < length; ++i)
2348                 {
2349                         if (exp2.find(param[i]) == exp2.end())
2350                         {
2351                                 m_context.getTestContext().getLog()
2352                                         << tcu::TestLog::Message
2353                                         << "Unexpected index found in active variables of NotSoSimpleBuffer: " << param[i]
2354                                         << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
2355                                            "GL_SHADER_STORAGE_BLOCK"
2356                                         << tcu::TestLog::EndMessage;
2357                                 glDeleteProgram(program);
2358                                 return ERROR;
2359                         }
2360                         else if (length != 3)
2361                         {
2362                                 m_context.getTestContext().getLog()
2363                                         << tcu::TestLog::Message
2364                                         << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK"
2365                                         << param[i] << "\nExpected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
2366                                 glDeleteProgram(program);
2367                                 return ERROR;
2368                         }
2369                 }
2370
2371                 glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2372                 if (res < 3)
2373                 {
2374                         m_context.getTestContext().getLog()
2375                                 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!\n"
2376                                 << "Call: glGetProgramInterfaceiv, interface: GL_SHADER_STORAGE_BLOCK" << tcu::TestLog::EndMessage;
2377                         return ERROR;
2378                 }
2379
2380                 glDeleteProgram(program);
2381                 return error;
2382         }
2383 };
2384
2385 class NullLength : public SimpleShaders
2386 {
2387
2388         virtual std::string Title()
2389         {
2390                 return "NULL Length Test";
2391         }
2392
2393         virtual std::string PurposeExt()
2394         {
2395                 return "\n\n Purpose is to verify that GetProgramResourceName with null length doesn't return length (doesn't "
2396                            "crash).\n";
2397         }
2398
2399         virtual std::string VertexShader()
2400         {
2401                 return "#version 310 es                      \n"
2402                            "in vec4 position;                    \n"
2403                            "void main(void)                      \n"
2404                            "{                                    \n"
2405                            "    gl_Position = position;          \n"
2406                            "}";
2407         }
2408
2409         virtual std::string FragmentShader()
2410         {
2411                 return "#version 310 es                \n"
2412                            "out mediump vec4 color;                \n"
2413                            "void main() {                  \n"
2414                            "    color = vec4(0, 1, 0, 1);  \n"
2415                            "}";
2416         }
2417
2418         virtual long Run()
2419         {
2420                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2421                 glBindAttribLocation(program, 0, "position");
2422                 LinkProgram(program);
2423
2424                 GLchar name[1024] = { '\0' };
2425                 GLuint index      = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color");
2426                 GLenum prop               = GL_ARRAY_SIZE;
2427                 GLint  res;
2428                 glGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, 1024, NULL, name);
2429                 glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &prop, 1, NULL, &res);
2430
2431                 std::string expected = "color";
2432                 if (name != expected)
2433                 {
2434                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected name: " << expected
2435                                                                                                 << ", got: " << name << tcu::TestLog::EndMessage;
2436                         glDeleteProgram(program);
2437                         return ERROR;
2438                 }
2439                 else if (res != 1)
2440                 {
2441                         m_context.getTestContext().getLog()
2442                                 << tcu::TestLog::Message << "Expected array_size: 1, got: " << res << tcu::TestLog::EndMessage;
2443                         glDeleteProgram(program);
2444                         return ERROR;
2445                 }
2446
2447                 glDeleteProgram(program);
2448                 return NO_ERROR;
2449         }
2450 };
2451
2452 class ArraysOfArrays : public SimpleShaders
2453 {
2454
2455         virtual std::string Title()
2456         {
2457                 return "Arrays Of Arrays Test";
2458         }
2459
2460         virtual std::string ShadersDesc()
2461         {
2462                 return "fallthrough fragment and vertex shaders with multi dimensional uniform array used";
2463         }
2464
2465         virtual std::string PurposeExt()
2466         {
2467                 return "\n\n Purpose is to verify that feature works correctly with arrays_of_arrays feature.\n";
2468         }
2469
2470         virtual std::string VertexShader()
2471         {
2472                 return "#version 310 es                      \n"
2473                            "in vec4 position;                    \n"
2474                            "uniform mediump vec4 a[3][4][5];             \n"
2475                            "void main(void)                      \n"
2476                            "{                                                 \n"
2477                            "    gl_Position = position + a[2][1][0];          \n"
2478                            "}";
2479         }
2480
2481         virtual std::string FragmentShader()
2482         {
2483                 return "#version 310 es                \n"
2484                            "out mediump vec4 color;                \n"
2485                            "void main() {                  \n"
2486                            "    color = vec4(0, 1, 0, 1);  \n"
2487                            "}";
2488         }
2489
2490         virtual long Run()
2491         {
2492                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2493                 glBindAttribLocation(program, 0, "position");
2494                 LinkProgram(program);
2495
2496                 long error = NO_ERROR;
2497
2498                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 11, error);
2499
2500                 std::map<std::string, GLuint> indices;
2501                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a[2][1]", error);
2502                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, "a[2][1][0]", indices["a[2][1]"], error);
2503
2504                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a[2][1]"], "a[2][1][0]", error);
2505
2506                 GLenum props[] = { GL_NAME_LENGTH,
2507                                                    GL_TYPE,
2508                                                    GL_ARRAY_SIZE,
2509                                                    GL_OFFSET,
2510                                                    GL_BLOCK_INDEX,
2511                                                    GL_ARRAY_STRIDE,
2512                                                    GL_MATRIX_STRIDE,
2513                                                    GL_IS_ROW_MAJOR,
2514                                                    GL_ATOMIC_COUNTER_BUFFER_INDEX,
2515                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
2516                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
2517                                                    GL_REFERENCED_BY_VERTEX_SHADER,
2518                                                    GL_LOCATION };
2519                 GLint expected[] = { 11, 35666, 5, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "a[2][1]") };
2520                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a[2][1]"], 13, props, 13, expected, error);
2521
2522                 glDeleteProgram(program);
2523                 return error;
2524         }
2525 };
2526
2527 class TopLevelArray : public ComputeShaderTest
2528 {
2529
2530         virtual std::string Title()
2531         {
2532                 return "Top Level Array Test";
2533         }
2534
2535         virtual std::string ShadersDesc()
2536         {
2537                 return "compute shader with multi dimensional array used inside storage block";
2538         }
2539
2540         virtual std::string PurposeExt()
2541         {
2542                 return "\n\n Purpose is to verify that feature works correctly when querying for GL_TOP_LEVEL_ARRAY_SIZE\n"
2543                            " and GL_TOP_LEVEL_ARRAY_STRIDE.\n";
2544         }
2545
2546         virtual std::string ComputeShader()
2547         {
2548                 return "layout(local_size_x = 1, local_size_y = 1) in; \n"
2549                            "layout(std430) buffer Outp {                   \n"
2550                            "   mediump vec4 d;                             \n"
2551                            "} g_out;                                       \n"
2552                            ""
2553                            "buffer Block {                       \n"
2554                            "   mediump vec4 a[5][4][3];          \n"
2555                            "};                                   \n"
2556                            ""
2557                            "void main(void)                      \n"
2558                            "{                                    \n"
2559                            "    g_out.d = a[0][0][0];            \n"
2560                            "}";
2561         }
2562
2563         virtual long Run()
2564         {
2565                 GLuint program = CreateComputeProgram(ComputeShader());
2566                 glLinkProgram(program);
2567                 if (!CheckProgram(program))
2568                 {
2569                         glDeleteProgram(program);
2570                         return ERROR;
2571                 }
2572                 glUseProgram(program);
2573
2574                 long error = NO_ERROR;
2575
2576                 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 11, error);
2577                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 6, error);
2578                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 2, error);
2579
2580                 std::map<std::string, GLuint> indicesSSB;
2581                 std::map<std::string, GLuint> indicesBV;
2582                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a[0][0]", error);
2583                 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Block", error);
2584
2585                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], "a[0][0][0]", error);
2586                 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Block"], "Block", error);
2587
2588                 GLenum props3[] = { GL_NAME_LENGTH,
2589                                                         GL_TYPE,
2590                                                         GL_ARRAY_SIZE,
2591                                                         GL_BLOCK_INDEX,
2592                                                         GL_IS_ROW_MAJOR,
2593                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
2594                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
2595                                                         GL_REFERENCED_BY_VERTEX_SHADER,
2596                                                         GL_TOP_LEVEL_ARRAY_SIZE };
2597                 GLint expected5[] = { 11, 35666, 3, static_cast<GLint>(indicesSSB["Block"]), 0, 1, 0, 0, 5 };
2598                 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 9, props3, 9, expected5, error);
2599
2600                 GLenum  prop = GL_TOP_LEVEL_ARRAY_STRIDE;
2601                 GLsizei len;
2602                 GLint   res;
2603                 glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 1, &prop, 1024, &len, &res);
2604                 if (res <= 0)
2605                 {
2606                         m_context.getTestContext().getLog()
2607                                 << tcu::TestLog::Message
2608                                 << "Call: glGetProgramResourceiv, interface: GL_BUFFER_VARIABLE, param: GL_TOP_LEVEL_ARRAY_STRIDE\n"
2609                                 << "Expected value greater than 0, got: " << res << tcu::TestLog::EndMessage;
2610                         glDeleteProgram(program);
2611                         return ERROR;
2612                 }
2613
2614                 glDeleteProgram(program);
2615                 return error;
2616         }
2617 };
2618
2619 class SeparateProgramsVertex : public SimpleShaders
2620 {
2621 public:
2622         virtual std::string Title()
2623         {
2624                 return "Separate Program Vertex Shader Test";
2625         }
2626
2627         virtual std::string ShadersDesc()
2628         {
2629                 return "vertex shader as separate shader object";
2630         }
2631
2632         virtual std::string PurposeExt()
2633         {
2634                 return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
2635                            "functionality.\n";
2636         }
2637
2638         virtual GLuint CreateShaderProgram(GLenum type, GLsizei count, const GLchar** strings)
2639         {
2640                 GLuint program = glCreateShaderProgramv(type, count, strings);
2641                 GLint  status  = GL_TRUE;
2642                 glGetProgramiv(program, GL_LINK_STATUS, &status);
2643                 if (status == GL_FALSE)
2644                 {
2645                         GLsizei length;
2646                         GLchar  log[1024];
2647                         glGetProgramInfoLog(program, sizeof(log), &length, log);
2648                         if (length > 1)
2649                         {
2650                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
2651                                                                                                         << log << tcu::TestLog::EndMessage;
2652                         }
2653                 }
2654                 return program;
2655         }
2656
2657         virtual long Run()
2658         {
2659                 long error = NO_ERROR;
2660
2661                 const char* srcVS = "#version 310 es                            \n"
2662                                                         "layout(location = 0) in vec4 in_vertex;    \n"
2663                                                         ""
2664                                                         "out mediump float r, g, b;                           \n"
2665                                                         "out mediump vec4 iLikePie;                           \n"
2666                                                         ""
2667                                                         "uniform mediump float u;                           \n"
2668                                                         "uniform mediump vec4 v;                            \n"
2669                                                         ""
2670                                                         "void main() {                     \n"
2671                                                         "  gl_Position = in_vertex;        \n"
2672                                                         "  r = u;                          \n"
2673                                                         "  g = 0.0;                        \n"
2674                                                         "  b = 0.0;                        \n"
2675                                                         "  iLikePie = v;                   \n"
2676                                                         "}";
2677
2678                 const GLuint vs = CreateShaderProgram(GL_VERTEX_SHADER, 1, &srcVS);
2679
2680                 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2681                 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 2, error);
2682                 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 10, error);
2683                 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
2684                 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 12, error);
2685                 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
2686
2687                 std::map<std::string, GLuint> indicesU;
2688                 std::map<std::string, GLuint> indicesI;
2689                 std::map<std::string, GLuint> indicesO;
2690                 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "u", error);
2691                 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "v", error);
2692                 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_INPUT, indicesI, "in_vertex", error);
2693                 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "r", error);
2694                 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "g", error);
2695                 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "b", error);
2696                 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "iLikePie", error);
2697                 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
2698
2699                 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["u"], "u", error);
2700                 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["v"], "v", error);
2701                 VerifyGetProgramResourceName(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], "in_vertex", error);
2702                 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["r"], "r", error);
2703                 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["g"], "g", error);
2704                 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
2705                 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], "iLikePie", error);
2706                 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
2707
2708                 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "u", glGetUniformLocation(vs, "u"), error);
2709                 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "v", glGetUniformLocation(vs, "v"), error);
2710                 VerifyGetProgramResourceLocation(vs, GL_PROGRAM_INPUT, "in_vertex", 0, error);
2711
2712                 GLenum props[] = { GL_NAME_LENGTH,
2713                                                    GL_TYPE,
2714                                                    GL_ARRAY_SIZE,
2715                                                    GL_OFFSET,
2716                                                    GL_BLOCK_INDEX,
2717                                                    GL_ARRAY_STRIDE,
2718                                                    GL_MATRIX_STRIDE,
2719                                                    GL_IS_ROW_MAJOR,
2720                                                    GL_ATOMIC_COUNTER_BUFFER_INDEX,
2721                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
2722                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
2723                                                    GL_REFERENCED_BY_VERTEX_SHADER,
2724                                                    GL_LOCATION };
2725                 GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(vs, "v") };
2726                 VerifyGetProgramResourceiv(vs, GL_UNIFORM, indicesU["v"], 13, props, 13, expected, error);
2727
2728                 GLenum props2[] = { GL_NAME_LENGTH,
2729                                                         GL_TYPE,
2730                                                         GL_ARRAY_SIZE,
2731                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
2732                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
2733                                                         GL_REFERENCED_BY_VERTEX_SHADER,
2734                                                         GL_LOCATION };
2735                 GLint expected2[] = { 10, 35666, 1, 0, 0, 1, 0 };
2736                 VerifyGetProgramResourceiv(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], 7, props2, 7, expected2, error);
2737
2738                 GLenum props3[] = { GL_NAME_LENGTH,
2739                                                         GL_TYPE,
2740                                                         GL_ARRAY_SIZE,
2741                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
2742                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
2743                                                         GL_REFERENCED_BY_VERTEX_SHADER };
2744                 GLint expected3[] = { 9, 35666, 1, 0, 0, 1 };
2745                 VerifyGetProgramResourceiv(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], 6, props3, 6, expected3, error);
2746
2747                 glDeleteProgram(vs);
2748                 return error;
2749         }
2750 };
2751
2752 class SeparateProgramsFragment : public SeparateProgramsVertex
2753 {
2754
2755         virtual std::string Title()
2756         {
2757                 return "Separate Program Fragment Shader Test";
2758         }
2759
2760         virtual std::string ShadersDesc()
2761         {
2762                 return "fragment shader as separate shader object";
2763         }
2764
2765         virtual long Run()
2766         {
2767                 long error = NO_ERROR;
2768
2769                 const char* srcTCS = "#version 310 es                                  \n"
2770                                                          "out mediump vec4 fs_color;                       \n"
2771                                                          ""
2772                                                          "layout(location = 1) uniform mediump vec4 x;     \n"
2773                                                          ""
2774                                                          "in mediump vec4 vs_color;                        \n"
2775                                                          "void main() {                                    \n"
2776                                                          "   fs_color = vs_color + x;                      \n"
2777                                                          "}";
2778
2779                 const GLuint tcs = CreateShaderProgram(GL_FRAGMENT_SHADER, 1, &srcTCS);
2780
2781                 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
2782                 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
2783                 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 9, error);
2784                 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
2785                 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2786                 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2787
2788                 std::map<std::string, GLuint> indicesI;
2789                 std::map<std::string, GLuint> indicesO;
2790                 std::map<std::string, GLuint> indicesU;
2791                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "vs_color", error);
2792                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "fs_color", error);
2793                 VerifyGetProgramResourceIndex(tcs, GL_UNIFORM, indicesU, "x", error);
2794
2795                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], "vs_color", error);
2796                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], "fs_color", error);
2797                 VerifyGetProgramResourceName(tcs, GL_UNIFORM, indicesU["x"], "x", error);
2798
2799                 VerifyGetProgramResourceLocation(tcs, GL_UNIFORM, "x", 1, error);
2800
2801                 GLenum props2[] = { GL_NAME_LENGTH,
2802                                                         GL_TYPE,
2803                                                         GL_ARRAY_SIZE,
2804                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
2805                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
2806                                                         GL_REFERENCED_BY_VERTEX_SHADER };
2807                 GLint expected2[] = { 9, 35666, 1, 0, 1, 0 };
2808                 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], 6, props2, 6, expected2, error);
2809                 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], 6, props2, 6, expected2, error);
2810
2811                 GLenum props[] = { GL_NAME_LENGTH,
2812                                                    GL_TYPE,
2813                                                    GL_ARRAY_SIZE,
2814                                                    GL_OFFSET,
2815                                                    GL_BLOCK_INDEX,
2816                                                    GL_ARRAY_STRIDE,
2817                                                    GL_MATRIX_STRIDE,
2818                                                    GL_IS_ROW_MAJOR,
2819                                                    GL_ATOMIC_COUNTER_BUFFER_INDEX,
2820                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
2821                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
2822                                                    GL_REFERENCED_BY_VERTEX_SHADER,
2823                                                    GL_LOCATION };
2824                 GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 1 };
2825                 VerifyGetProgramResourceiv(tcs, GL_UNIFORM, indicesU["x"], 13, props, 13, expected, error);
2826
2827                 glDeleteProgram(tcs);
2828                 return error;
2829         }
2830 };
2831
2832 class UniformBlockAdvanced : public SimpleShaders
2833 {
2834         virtual std::string Title()
2835         {
2836                 return "Uniform Block Advanced Test";
2837         }
2838
2839         virtual std::string ShadersDesc()
2840         {
2841                 return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
2842         }
2843
2844         virtual std::string PurposeExt()
2845         {
2846                 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param and\n"
2847                            "verify results of querying offset, strides and row order.\n";
2848         }
2849
2850         virtual std::string VertexShader()
2851         {
2852                 return "#version 310 es                      \n"
2853                            "in vec4 position;                    \n"
2854                            ""
2855                            "layout(row_major) uniform SimpleBlock {   \n"
2856                            "   mat4 a;                                \n"
2857                            "   vec4 b[10];                            \n"
2858                            "};                                        \n"
2859                            ""
2860                            "void main(void)                      \n"
2861                            "{                                    \n"
2862                            "    float tmp;                       \n"
2863                            "    tmp = a[0][0] + b[0].x;          \n"
2864                            "    gl_Position = position * tmp;    \n"
2865                            "}";
2866         }
2867
2868         virtual long Run()
2869         {
2870                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2871                 glBindAttribLocation(program, 0, "position");
2872                 LinkProgram(program);
2873
2874                 long error = NO_ERROR;
2875
2876                 std::map<std::string, GLuint> indicesU;
2877                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
2878                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
2879
2880                 GLenum props[]  = { GL_IS_ROW_MAJOR };
2881                 GLint  expected[] = { 1 };
2882                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, props, 1, expected, error);
2883
2884                 GLenum  prop = GL_MATRIX_STRIDE;
2885                 GLsizei len;
2886                 GLint   res;
2887                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
2888                 if (res < 1)
2889                 {
2890                         m_context.getTestContext().getLog()
2891                                 << tcu::TestLog::Message
2892                                 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_MATRIX_STRIDE\n"
2893                                 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
2894                 }
2895                 prop = GL_OFFSET;
2896                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
2897                 if (res < 0)
2898                 {
2899                         m_context.getTestContext().getLog()
2900                                 << tcu::TestLog::Message << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_OFFSET\n"
2901                                 << "Expected value not less than 0, got " << res << tcu::TestLog::EndMessage;
2902                 }
2903                 prop = GL_ARRAY_STRIDE;
2904                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, 1024, &len, &res);
2905                 if (res < 1)
2906                 {
2907                         m_context.getTestContext().getLog()
2908                                 << tcu::TestLog::Message
2909                                 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_ARRAY_STRIDE\n"
2910                                 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
2911                 }
2912
2913                 glDeleteProgram(program);
2914                 return error;
2915         }
2916 };
2917
2918 class ArrayNames : public SimpleShaders
2919 {
2920
2921         virtual std::string Title()
2922         {
2923                 return "Array Names Test";
2924         }
2925
2926         virtual std::string ShadersDesc()
2927         {
2928                 return "fallthrough fragment shader and a vertex shader with array of vec4 uniform used";
2929         }
2930
2931         virtual std::string PurposeExt()
2932         {
2933                 return "\n\n Purpose is to verify that GetProgramResourceLocation match "
2934                            "name strings correctly.\n";
2935         }
2936
2937         virtual std::string VertexShader()
2938         {
2939                 return "#version 310 es                      \n"
2940                            "in vec4 position;                    \n"
2941                            ""
2942                            "uniform mediump vec4 a[2];           \n"
2943                            ""
2944                            "void main(void)                            \n"
2945                            "{                                          \n"
2946                            "    gl_Position = position + a[0] + a[1];  \n"
2947                            "}";
2948         }
2949
2950         virtual long Run()
2951         {
2952                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2953                 glBindAttribLocation(program, 0, "position");
2954                 LinkProgram(program);
2955
2956                 long error = NO_ERROR;
2957
2958                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
2959                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0]", glGetUniformLocation(program, "a"), error);
2960                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[1]", glGetUniformLocation(program, "a[1]"), error);
2961                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[2]", -1, error);
2962                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 + 0]", -1, error);
2963                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0+0]", -1, error);
2964                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[ 0]", -1, error);
2965                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 ]", -1, error);
2966                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\n0]", -1, error);
2967                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\t0]", -1, error);
2968                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[01]", -1, error);
2969                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[00]", -1, error);
2970
2971                 glDeleteProgram(program);
2972                 return error;
2973         }
2974 };
2975
2976 class BuffLength : public SimpleShaders
2977 {
2978
2979         virtual std::string Title()
2980         {
2981                 return "Buff Length Test";
2982         }
2983
2984         virtual std::string ShadersDesc()
2985         {
2986                 return "fallthrough fragment shader and vertex with uniform of vec4 type used";
2987         }
2988
2989         virtual std::string PurposeExt()
2990         {
2991                 return "\n\n Purpose is to verify that bufsize of GetProgramResourceName and "
2992                            "GetProgramResourceiv is respected.\n";
2993         }
2994
2995         virtual std::string VertexShader()
2996         {
2997                 return "#version 310 es                      \n"
2998                            "in vec4 position;                    \n"
2999                            ""
3000                            "uniform mediump vec4 someLongName;         \n"
3001                            ""
3002                            "void main(void)                            \n"
3003                            "{                                          \n"
3004                            "    gl_Position = position + someLongName; \n"
3005                            "}";
3006         }
3007
3008         virtual long Run()
3009         {
3010                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3011                 glBindAttribLocation(program, 0, "position");
3012                 LinkProgram(program);
3013
3014                 long error = NO_ERROR;
3015
3016                 GLuint  index = glGetProgramResourceIndex(program, GL_UNIFORM, "someLongName");
3017                 GLsizei length;
3018                 GLchar  buff[3] = { 'a', 'b', 'c' };
3019                 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, NULL);
3020                 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, buff);
3021                 if (buff[0] != 'a' || buff[1] != 'b' || buff[2] != 'c')
3022                 {
3023                         m_context.getTestContext().getLog()
3024                                 << tcu::TestLog::Message << "ERROR: buff has changed" << tcu::TestLog::EndMessage;
3025                         error = ERROR;
3026                 }
3027                 glGetProgramResourceName(program, GL_UNIFORM, index, 2, &length, buff);
3028                 if (buff[0] != 's' || buff[1] != '\0' || buff[2] != 'c')
3029                 {
3030                         m_context.getTestContext().getLog()
3031                                 << tcu::TestLog::Message << "ERROR: buff different then expected" << tcu::TestLog::EndMessage;
3032                         error = ERROR;
3033                 }
3034                 if (length != 1)
3035                 {
3036                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 1, got "
3037                                                                                                 << length << tcu::TestLog::EndMessage;
3038                         error = ERROR;
3039                 }
3040
3041                 GLint  params[3] = { 1, 2, 3 };
3042                 GLenum props[]   = { GL_NAME_LENGTH,
3043                                                    GL_TYPE,
3044                                                    GL_ARRAY_SIZE,
3045                                                    GL_OFFSET,
3046                                                    GL_BLOCK_INDEX,
3047                                                    GL_ARRAY_STRIDE,
3048                                                    GL_MATRIX_STRIDE,
3049                                                    GL_IS_ROW_MAJOR,
3050                                                    GL_ATOMIC_COUNTER_BUFFER_INDEX,
3051                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
3052                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
3053                                                    GL_REFERENCED_BY_VERTEX_SHADER,
3054                                                    GL_LOCATION };
3055                 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, NULL);
3056                 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, params);
3057                 if (params[0] != 1 || params[1] != 2 || params[2] != 3)
3058                 {
3059                         m_context.getTestContext().getLog()
3060                                 << tcu::TestLog::Message << "ERROR: params has changed" << tcu::TestLog::EndMessage;
3061                         error = ERROR;
3062                 }
3063                 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 2, &length, params);
3064                 if (params[0] != 13 || params[1] != 35666 || params[2] != 3)
3065                 {
3066                         m_context.getTestContext().getLog()
3067                                 << tcu::TestLog::Message << "ERROR: params has incorrect values" << tcu::TestLog::EndMessage;
3068                         error = ERROR;
3069                 }
3070                 if (length != 2)
3071                 {
3072                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 2, got "
3073                                                                                                 << length << tcu::TestLog::EndMessage;
3074                         error = ERROR;
3075                 }
3076
3077                 glDeleteProgram(program);
3078                 return error;
3079         }
3080 };
3081
3082 class NoLocations : public SimpleShaders
3083 {
3084
3085         virtual std::string Title()
3086         {
3087                 return "No Locations Test";
3088         }
3089
3090         virtual std::string ShadersDesc()
3091         {
3092                 return "fragment and vertex shaders with no locations set";
3093         }
3094
3095         virtual std::string VertexShader()
3096         {
3097                 return "#version 310 es                      \n"
3098                            "in vec4 a;                           \n"
3099                            "in vec4 b;                           \n"
3100                            "in vec4 c;                           \n"
3101                            "in vec4 d;                           \n"
3102                            "void main(void)                      \n"
3103                            "{                                    \n"
3104                            "    gl_Position = a + b + c + d;     \n"
3105                            "}";
3106         }
3107
3108         // fragment shader outputs need an explicit location per spec
3109         virtual std::string FragmentShader()
3110         {
3111                 return "#version 310 es                \n"
3112                            "layout (location=0) out mediump vec4 a;            \n"
3113                            "layout (location=1) out mediump vec4 b;            \n"
3114                            "layout (location=2) out mediump vec4 c;            \n"
3115                            "layout (location=3) out mediump vec4 d[1];         \n"
3116                            "void main() {                  \n"
3117                            "    a = vec4(0, 1, 0, 1);      \n"
3118                            "    b = vec4(0, 1, 0, 1);      \n"
3119                            "    c = vec4(0, 1, 0, 1);      \n"
3120                            "    d[0] = vec4(0, 1, 0, 1);   \n"
3121                            "}";
3122         }
3123
3124         virtual long Run()
3125         {
3126                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3127                 glBindAttribLocation(program, 0, "position");
3128                 glLinkProgram(program);
3129
3130                 long error = NO_ERROR;
3131
3132                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 4, error);
3133                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error);
3134                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 4, error);
3135                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
3136
3137                 std::map<std::string, GLuint> indicesI;
3138                 std::map<std::string, GLuint> indicesO;
3139                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "a", error);
3140                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "b", error);
3141                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "c", error);
3142                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "d", error);
3143                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "a", error);
3144                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "b", error);
3145                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "c", error);
3146                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "d[0]", error);
3147
3148                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["a"], "a", error);
3149                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["b"], "b", error);
3150                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["c"], "c", error);
3151                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["d"], "d", error);
3152                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["a"], "a", error);
3153                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
3154                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["c"], "c", error);
3155                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], "d[0]", error);
3156
3157                 std::map<std::string, GLint> locationsI;
3158                 std::map<std::string, GLint> locationsO;
3159                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "a", error);
3160                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "b", error);
3161                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "c", error);
3162                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "d", error);
3163                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "a", error);
3164                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "b", error);
3165                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "c", error);
3166                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "d[0]", error);
3167
3168                 GLenum props[] = { GL_NAME_LENGTH,
3169                                                    GL_TYPE,
3170                                                    GL_ARRAY_SIZE,
3171                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
3172                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
3173                                                    GL_REFERENCED_BY_VERTEX_SHADER };
3174                 GLint expected[] = { 2, 35666, 1, 0, 0, 1 };
3175                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["a"], 6, props, 6, expected, error);
3176                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["b"], 6, props, 6, expected, error);
3177                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["d"], 6, props, 6, expected, error);
3178                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["c"], 6, props, 6, expected, error);
3179                 GLint expected3[] = { 2, 35666, 1, 0, 1, 0 };
3180                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["a"], 6, props, 6, expected3, error);
3181                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["b"], 6, props, 6, expected3, error);
3182                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["c"], 6, props, 6, expected3, error);
3183                 GLint expected4[] = { 5, 35666, 1, 0, 1, 0 };
3184                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], 6, props, 6, expected4, error);
3185
3186                 glDeleteProgram(program);
3187                 return error;
3188         }
3189 };
3190
3191 class OutputBuiltIn : public SimpleShaders
3192 {
3193
3194         virtual std::string Title()
3195         {
3196                 return "Output Built-ins Test";
3197         }
3198
3199         virtual std::string ShadersDesc()
3200         {
3201                 return "fragment shader using built-in variables and a fallthrough vertex shader";
3202         }
3203
3204         virtual std::string Expectations()
3205         {
3206                 return ".\n\n In this case we ask for information about built-in variables for the output interface.";
3207         }
3208
3209         virtual std::string FragmentShader()
3210         {
3211                 return "#version 310 es                            \n"
3212                            "void main(void)                            \n"
3213                            "{                                          \n"
3214                            "    gl_FragDepth = 0.1;                    \n"
3215                            "}";
3216         }
3217
3218         virtual long Run()
3219         {
3220                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), true);
3221
3222                 long error = NO_ERROR;
3223
3224                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
3225                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 13, error);
3226
3227                 std::map<std::string, GLuint> indices;
3228                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "gl_FragDepth", error);
3229
3230                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], "gl_FragDepth", error);
3231
3232                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_FragDepth", -1, error);
3233
3234                 GLenum props[] = { GL_NAME_LENGTH,
3235                                                    GL_TYPE,
3236                                                    GL_ARRAY_SIZE,
3237                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
3238                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
3239                                                    GL_REFERENCED_BY_VERTEX_SHADER,
3240                                                    GL_LOCATION };
3241                 GLint expected[] = { 13, 5126, 1, 0, 1, 0, -1 };
3242                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], DE_LENGTH_OF_ARRAY(props),
3243                                                                    props, DE_LENGTH_OF_ARRAY(expected), expected, error);
3244
3245                 glDeleteProgram(program);
3246                 return error;
3247         }
3248 };
3249
3250 class QueryNotUsed : public SimpleShaders
3251 {
3252
3253         virtual std::string Title()
3254         {
3255                 return "Query Not Used Test";
3256         }
3257
3258         virtual std::string PassCriteria()
3259         {
3260                 return "Data from queries matches the not used program.";
3261         }
3262
3263         virtual std::string Purpose()
3264         {
3265                 return "Verify that program parameter works correctly and proper program is queried when different program is "
3266                            "used.";
3267         }
3268
3269         virtual std::string Method()
3270         {
3271                 return "Create 2 programs, use one of them and query the other, verify the results.";
3272         }
3273
3274         virtual std::string VertexShader2()
3275         {
3276                 return "#version 310 es                      \n"
3277                            "in mediump vec4 p;                   \n"
3278                            "void main(void)                      \n"
3279                            "{                                    \n"
3280                            "    gl_Position = p;                 \n"
3281                            "}";
3282         }
3283
3284         virtual std::string FragmentShader2()
3285         {
3286                 return "#version 310 es                \n"
3287                            "out mediump vec4 c;            \n"
3288                            "void main() {                  \n"
3289                            "    c = vec4(0., 1., 0., 1.);  \n"
3290                            "}";
3291         }
3292
3293         virtual long Run()
3294         {
3295                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3296                 LinkProgram(program);
3297
3298                 GLuint program2 = CreateProgram(VertexShader2().c_str(), FragmentShader2().c_str(), false);
3299                 LinkProgram(program2);
3300                 glUseProgram(program2);
3301
3302                 long error = NO_ERROR;
3303
3304                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
3305                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
3306                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
3307                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
3308
3309                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
3310                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
3311
3312                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
3313                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
3314
3315                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
3316                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
3317
3318                 GLenum props[] = { GL_NAME_LENGTH,
3319                                                    GL_TYPE,
3320                                                    GL_ARRAY_SIZE,
3321                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
3322                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
3323                                                    GL_REFERENCED_BY_VERTEX_SHADER,
3324                                                    GL_LOCATION };
3325                 GLint expected[] = { 9, 35666, 1, 0, 0, 1, 0 };
3326                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, DE_LENGTH_OF_ARRAY(props), props,
3327                                                                    DE_LENGTH_OF_ARRAY(expected), expected, error);
3328
3329                 GLenum props2[] = { GL_NAME_LENGTH,
3330                                                         GL_TYPE,
3331                                                         GL_ARRAY_SIZE,
3332                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
3333                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
3334                                                         GL_REFERENCED_BY_VERTEX_SHADER,
3335                                                         GL_LOCATION };
3336                 GLint expected2[] = { 6, 35666, 1, 0, 1, 0, 0 };
3337                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 7, props2, 7, expected2, error);
3338
3339                 glDeleteProgram(program);
3340                 glDeleteProgram(program2);
3341                 return error;
3342         }
3343 };
3344
3345 class RelinkFailure : public SimpleShaders
3346 {
3347
3348         virtual std::string Title()
3349         {
3350                 return "Relink Failure Test";
3351         }
3352
3353         virtual std::string PassCriteria()
3354         {
3355                 return "INVALID_OPERATION is generated when asking for locations after failed link.";
3356         }
3357
3358         virtual std::string Purpose()
3359         {
3360                 return "Verify that queries behave correctly after failed relink of a program.";
3361         }
3362
3363         virtual std::string Method()
3364         {
3365                 return "Create a program, use it, relink with failure and then verify that INVALID_OPERATION is returned when "
3366                            "asking for locations.";
3367         }
3368
3369         virtual std::string VertexShader()
3370         {
3371                 return "#version 310 es                               \n"
3372                            "in mediump vec4 position;                     \n"
3373                            "in mediump vec3 pos;                          \n"
3374                            "void main(void)                               \n"
3375                            "{                                             \n"
3376                            "    gl_Position = position + vec4(pos, 1.);   \n"
3377                            "}";
3378         }
3379
3380         virtual long Run()
3381         {
3382                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3383                 glBindAttribLocation(program, 0, "position");
3384                 glBindAttribLocation(program, 1, "pos");
3385                 LinkProgram(program);
3386
3387                 long error = NO_ERROR;
3388
3389                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", 1, error);
3390                 glUseProgram(program);
3391
3392                 tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
3393                                                    tcu::Vec4(1, -1, 0, 1) };
3394                 GLuint vao, vbuf;
3395                 glGenVertexArrays(1, &vao);
3396                 glBindVertexArray(vao);
3397                 glGenBuffers(1, &vbuf);
3398                 glBindBuffer(GL_ARRAY_BUFFER, vbuf);
3399                 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
3400                 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
3401                 glEnableVertexAttribArray(0);
3402                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3403
3404                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3405                 glDisableVertexAttribArray(0);
3406                 glDeleteVertexArrays(1, &vao);
3407                 glBindBuffer(GL_ARRAY_BUFFER, 0);
3408                 glDeleteBuffers(1, &vbuf);
3409
3410                 glBindAttribLocation(program, 0, "pos");
3411                 glBindAttribLocation(program, 0, "position");
3412                 const char* varyings[2] = { "q", "z" };
3413                 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
3414                 LinkProgram(program);
3415
3416                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
3417                 ExpectError(GL_INVALID_OPERATION, error);
3418                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", -1, error);
3419                 ExpectError(GL_INVALID_OPERATION, error);
3420                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
3421                 ExpectError(GL_INVALID_OPERATION, error);
3422
3423                 glDeleteProgram(program);
3424                 return error;
3425         }
3426 };
3427
3428 class LinkFailure : public SimpleShaders
3429 {
3430
3431         virtual std::string Title()
3432         {
3433                 return "Link Failure Test";
3434         }
3435
3436         virtual std::string PassCriteria()
3437         {
3438                 return "INVALID_OPERATION is generated when asking for locations after failed link.";
3439         }
3440
3441         virtual std::string Purpose()
3442         {
3443                 return "Verify that queries behave correctly after failed relink of a program with changed sources.";
3444         }
3445
3446         virtual std::string Method()
3447         {
3448                 return "Create a program, use it, relink with failure using different sources and then \n"
3449                            "verify that INVALID_OPERATION is returned when asking for locations.";
3450         }
3451
3452         virtual const char* VertexShader_prop()
3453         {
3454                 return "#version 310 es                      \n"
3455                            "in mediump vec4 posit;               \n"
3456                            "in mediump vec4 p;                   \n"
3457                            "void main(void)                      \n"
3458                            "{                                    \n"
3459                            "    gl_Position = p + posit;         \n"
3460                            "}";
3461         }
3462
3463         virtual const char* FragmentShader_prop()
3464         {
3465                 return "#version 310 es                    \n"
3466                            "out mediump vec4 color;            \n"
3467                            "void main() {                      \n"
3468                            "    color = vec4(0., 1., 0., 1.);  \n"
3469                            "}";
3470         }
3471
3472         virtual const char* VertexShader_fail()
3473         {
3474                 return "#version 310 es                      \n"
3475                            "in mediump vec4 position;            \n"
3476                            "void main(void)                      \n"
3477                            "{                                    \n"
3478                            "    gl_Position = position;          \n"
3479                            "}";
3480         }
3481
3482         virtual long Run()
3483         {
3484                 const GLuint program = glCreateProgram();
3485                 const char*  src_vs  = VertexShader_prop();
3486                 const char*  src_fs  = FragmentShader_prop();
3487                 const char*  src_vsh = VertexShader_fail();
3488
3489                 GLuint sh1 = glCreateShader(GL_VERTEX_SHADER);
3490                 glAttachShader(program, sh1);
3491                 glDeleteShader(sh1);
3492                 glShaderSource(sh1, 1, &src_vs, NULL);
3493                 glCompileShader(sh1);
3494
3495                 GLuint sh2 = glCreateShader(GL_FRAGMENT_SHADER);
3496                 glAttachShader(program, sh2);
3497                 glDeleteShader(sh2);
3498                 glShaderSource(sh2, 1, &src_fs, NULL);
3499                 glCompileShader(sh2);
3500
3501                 glBindAttribLocation(program, 0, "p");
3502                 glBindAttribLocation(program, 1, "posit");
3503                 LinkProgram(program);
3504
3505                 long error = NO_ERROR;
3506
3507                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "posit", 1, error);
3508                 glUseProgram(program);
3509
3510                 tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
3511                                                    tcu::Vec4(1, -1, 0, 1) };
3512                 GLuint vao, vbuf;
3513                 glGenVertexArrays(1, &vao);
3514                 glBindVertexArray(vao);
3515                 glGenBuffers(1, &vbuf);
3516                 glBindBuffer(GL_ARRAY_BUFFER, vbuf);
3517                 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
3518                 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
3519                 glEnableVertexAttribArray(0);
3520                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3521
3522                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3523                 glDisableVertexAttribArray(0);
3524                 glDeleteVertexArrays(1, &vao);
3525                 glBindBuffer(GL_ARRAY_BUFFER, 0);
3526                 glDeleteBuffers(1, &vbuf);
3527
3528                 glDetachShader(program, sh1);
3529                 GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
3530                 glAttachShader(program, vsh);
3531                 glDeleteShader(vsh);
3532                 glShaderSource(vsh, 1, &src_vsh, NULL);
3533                 glCompileShader(vsh);
3534                 const char* varyings[2] = { "q", "z" };
3535                 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
3536                 LinkProgram(program);
3537
3538                 GLint res;
3539                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
3540                 ExpectError(GL_INVALID_OPERATION, error);
3541                 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
3542                 if (res != 0 && res != 1)
3543                 {
3544                         m_context.getTestContext().getLog()
3545                                 << tcu::TestLog::Message << "Error, expected 0 or 1 active resources, got: " << res
3546                                 << tcu::TestLog::EndMessage;
3547                         error = ERROR;
3548                 }
3549                 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, &res);
3550                 if (res != 0 && res != 9)
3551                 {
3552                         m_context.getTestContext().getLog()
3553                                 << tcu::TestLog::Message << "Error, expected 1 or 9 GL_MAX_NAME_LENGTH, got: " << res
3554                                 << tcu::TestLog::EndMessage;
3555                         error = ERROR;
3556                 }
3557                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
3558                 ExpectError(GL_INVALID_OPERATION, error);
3559
3560                 glDeleteProgram(program);
3561                 return error;
3562         }
3563 };
3564 }
3565
3566 ProgramInterfaceQueryTests::ProgramInterfaceQueryTests(glcts::Context& context)
3567         : TestCaseGroup(context, "program_interface_query", "")
3568 {
3569 }
3570
3571 ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests(void)
3572 {
3573 }
3574
3575 void ProgramInterfaceQueryTests::init()
3576 {
3577         using namespace glcts;
3578         addChild(new TestSubcase(m_context, "empty-shaders", TestSubcase::Create<NoShaders>));
3579         addChild(new TestSubcase(m_context, "simple-shaders", TestSubcase::Create<SimpleShaders>));
3580         addChild(new TestSubcase(m_context, "input-types", TestSubcase::Create<InputTypes>));
3581         addChild(new TestSubcase(m_context, "input-built-in", TestSubcase::Create<InputBuiltIn>));
3582         addChild(new TestSubcase(m_context, "input-layout", TestSubcase::Create<InputLayout>));
3583         addChild(new TestSubcase(m_context, "output-layout", TestSubcase::Create<OutputLayout>));
3584         addChild(new TestSubcase(m_context, "output-built-in", TestSubcase::Create<OutputBuiltIn>));
3585         addChild(new TestSubcase(m_context, "uniform-simple", TestSubcase::Create<UniformSimple>));
3586         addChild(new TestSubcase(m_context, "uniform-types", TestSubcase::Create<UniformTypes>));
3587         addChild(new TestSubcase(m_context, "uniform-block-types", TestSubcase::Create<UniformBlockTypes>));
3588         addChild(new TestSubcase(m_context, "transform-feedback-types", TestSubcase::Create<TransformFeedbackTypes>));
3589         addChild(new TestSubcase(m_context, "atomic-counters", TestSubcase::Create<AtomicCounterSimple>));
3590         addChild(
3591                 new TestSubcase(m_context, "atomic-counters-one-buffer", TestSubcase::Create<AtomicCounterSimpleOneBuffer>));
3592         addChild(new TestSubcase(m_context, "ssb-types", TestSubcase::Create<ShaderStorageBlock>));
3593         addChild(new TestSubcase(m_context, "null-length", TestSubcase::Create<NullLength>));
3594         addChild(new TestSubcase(m_context, "arrays-of-arrays", TestSubcase::Create<ArraysOfArrays>));
3595         addChild(new TestSubcase(m_context, "top-level-array", TestSubcase::Create<TopLevelArray>));
3596         addChild(new TestSubcase(m_context, "separate-programs-vertex", TestSubcase::Create<SeparateProgramsVertex>));
3597         addChild(new TestSubcase(m_context, "separate-programs-fragment", TestSubcase::Create<SeparateProgramsFragment>));
3598         addChild(new TestSubcase(m_context, "uniform-block", TestSubcase::Create<UniformBlockAdvanced>));
3599         addChild(new TestSubcase(m_context, "array-names", TestSubcase::Create<ArrayNames>));
3600         addChild(new TestSubcase(m_context, "buff-length", TestSubcase::Create<BuffLength>));
3601         addChild(new TestSubcase(m_context, "no-locations", TestSubcase::Create<NoLocations>));
3602         addChild(new TestSubcase(m_context, "query-not-used", TestSubcase::Create<QueryNotUsed>));
3603         addChild(new TestSubcase(m_context, "relink-failure", TestSubcase::Create<RelinkFailure>));
3604         addChild(new TestSubcase(m_context, "link-failure", TestSubcase::Create<LinkFailure>));
3605         addChild(new TestSubcase(m_context, "compute-shader", TestSubcase::Create<ComputeShaderTest>));
3606         addChild(new TestSubcase(m_context, "invalid-value", TestSubcase::Create<InvalidValueTest>));
3607         addChild(new TestSubcase(m_context, "invalid-operation", TestSubcase::Create<InvalidOperationTest>));
3608         addChild(new TestSubcase(m_context, "invalid-enum", TestSubcase::Create<InvalidEnumTest>));
3609 }
3610 }