Remove vsnprintf from OpenGL CTS, part 1
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / gl / gl4cProgramInterfaceQueryTests.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 "gl4cProgramInterfaceQueryTests.hpp"
25 #include "glwEnums.hpp"
26 #include "glwFunctions.hpp"
27 #include <cstdarg>
28 #include <map>
29 #include <set>
30
31 namespace gl4cts
32 {
33
34 using namespace glw;
35
36 namespace
37 {
38
39 class PIQBase : public deqp::SubcaseBase
40 {
41
42 public:
43         virtual std::string PassCriteria()
44         {
45                 return "All called functions return expected values.";
46         }
47
48         virtual std::string Purpose()
49         {
50                 return "Verify that the set of tested functions glGetProgram* return\n"
51                            "expected results when used to get data from program\n"
52                            "made of " +
53                            ShadersDesc() + "." + PurposeExt();
54         }
55
56         virtual std::string Method()
57         {
58                 return "Create a program using " + ShadersDesc() +
59                            "\n"
60                            "then use set of tested functions to get an information about it and\n"
61                            "verify that information with the expected data" +
62                            Expectations();
63         }
64
65         virtual long Cleanup()
66         {
67                 glUseProgram(0);
68                 return NO_ERROR;
69         }
70
71         virtual long Setup()
72         {
73                 return NO_ERROR;
74         }
75
76         virtual ~PIQBase()
77         {
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         GLuint CreateProgram(const char* src_vs, const char* src_tcs, const char* src_tes, const char* src_gs,
122                                                  const char* src_fs, bool link)
123         {
124                 const GLuint p = glCreateProgram();
125
126                 if (src_vs)
127                 {
128                         GLuint sh = glCreateShader(GL_VERTEX_SHADER);
129                         glAttachShader(p, sh);
130                         glDeleteShader(sh);
131                         glShaderSource(sh, 1, &src_vs, NULL);
132                         glCompileShader(sh);
133                 }
134                 if (src_tcs)
135                 {
136                         GLuint sh = glCreateShader(GL_TESS_CONTROL_SHADER);
137                         glAttachShader(p, sh);
138                         glDeleteShader(sh);
139                         glShaderSource(sh, 1, &src_tcs, NULL);
140                         glCompileShader(sh);
141                 }
142                 if (src_tes)
143                 {
144                         GLuint sh = glCreateShader(GL_TESS_EVALUATION_SHADER);
145                         glAttachShader(p, sh);
146                         glDeleteShader(sh);
147                         glShaderSource(sh, 1, &src_tes, NULL);
148                         glCompileShader(sh);
149                 }
150                 if (src_gs)
151                 {
152                         GLuint sh = glCreateShader(GL_GEOMETRY_SHADER);
153                         glAttachShader(p, sh);
154                         glDeleteShader(sh);
155                         glShaderSource(sh, 1, &src_gs, NULL);
156                         glCompileShader(sh);
157                 }
158                 if (src_fs)
159                 {
160                         GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
161                         glAttachShader(p, sh);
162                         glDeleteShader(sh);
163                         glShaderSource(sh, 1, &src_fs, NULL);
164                         glCompileShader(sh);
165                 }
166                 if (link)
167                 {
168                         LinkProgram(p);
169                 }
170                 return p;
171         }
172
173         virtual std::string ShadersDesc()
174         {
175                 return "";
176         }
177
178         virtual std::string Expectations()
179         {
180                 return ".";
181         }
182
183         virtual std::string PurposeExt()
184         {
185                 return "";
186         }
187
188         virtual inline void ExpectError(GLenum expected, long& error)
189         {
190                 if (error != NO_ERROR)
191                         return;
192                 GLenum tmp = glGetError();
193                 if (tmp == expected)
194                 {
195                         m_context.getTestContext().getLog()
196                                 << tcu::TestLog::Message << "Found expected error" << tcu::TestLog::EndMessage;
197                         error = NO_ERROR; // Error is expected
198                 }
199                 else
200                 {
201                         error = ERROR;
202                         m_context.getTestContext().getLog() << tcu::TestLog::Message << expected
203                                                                                                 << " error was expected, found: " << tmp << tcu::TestLog::EndMessage;
204                 }
205         }
206
207         virtual inline void VerifyGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, int expected,
208                                                                                                         long& error)
209         {
210                 GLint res;
211                 glGetProgramInterfaceiv(program, programInterface, pname, &res);
212                 if (res != expected)
213                 {
214                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
215                                                                                                 << expected << tcu::TestLog::EndMessage;
216                         error = ERROR;
217                 }
218         }
219
220         virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum programInterface, const std::string& name,
221                                                                                                           GLuint expected, long& error)
222         {
223                 GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str());
224                 if (res != expected)
225                 {
226                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
227                                                                                                 << expected << tcu::TestLog::EndMessage;
228                         error = ERROR;
229                 }
230         }
231
232         virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum                 programInterface,
233                                                                                                           std::map<std::string, GLuint>& indices, const std::string& name,
234                                                                                                           long& error)
235         {
236                 GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str());
237                 if (res == GL_INVALID_INDEX)
238                 {
239                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res
240                                                                                                 << ", expected number other than -1" << tcu::TestLog::EndMessage;
241                         error = ERROR;
242                         return;
243                 }
244                 std::map<std::string, GLuint>::iterator it = indices.begin();
245                 while (it != indices.end())
246                 {
247                         if (it->second == res)
248                         {
249                                 m_context.getTestContext().getLog()
250                                         << tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage;
251                                 error = ERROR;
252                                 return;
253                         }
254                         ++it;
255                 }
256                 indices[name] = res;
257         }
258
259         virtual inline void VerifyGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index,
260                                                                                                          const std::string& expected, long& error)
261         {
262                 GLchar  name[1024] = { '\0' };
263                 GLsizei len;
264                 glGetProgramResourceName(program, programInterface, index, 1024, &len, name);
265                 if (len <= 0 || len > 1023 || name[len - 1] == '\0')
266                 {
267                         m_context.getTestContext().getLog()
268                                 << tcu::TestLog::Message
269                                 << "ERROR: Length in glGetProgramResourceName should not count null terminator!"
270                                 << tcu::TestLog::EndMessage;
271                         error = ERROR;
272                 }
273                 else if (name != expected || name[len] != '\0')
274                 {
275                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << name << ", expected "
276                                                                                                 << expected << tcu::TestLog::EndMessage;
277                         error = ERROR;
278                 }
279         }
280
281         virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum programInterface,
282                                                                                                                  const std::string& name, GLint expected, long& error)
283         {
284                 GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str());
285                 if (res != expected)
286                 {
287                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
288                                                                                                 << expected << tcu::TestLog::EndMessage;
289                         error = ERROR;
290                 }
291         }
292
293         virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum                programInterface,
294                                                                                                                  std::map<std::string, GLint>& locations,
295                                                                                                                  const std::string& name, long& error)
296         {
297                 GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str());
298                 if (res < 0)
299                 {
300                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res
301                                                                                                 << ", expected not less than 0" << tcu::TestLog::EndMessage;
302                         error = ERROR;
303                         return;
304                 }
305                 std::map<std::string, GLint>::iterator it = locations.begin();
306                 while (it != locations.end())
307                 {
308                         if (it->second == res)
309                         {
310                                 m_context.getTestContext().getLog()
311                                         << tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage;
312                                 error = ERROR;
313                                 return;
314                         }
315                         ++it;
316                 }
317                 locations[name] = res;
318         }
319
320         virtual inline void VerifyGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index,
321                                                                                                    GLsizei propCount, const GLenum props[], GLsizei expectedLength,
322                                                                                                    const GLint expected[], long& error)
323         {
324                 const GLsizei bufSize = 1000;
325                 GLsizei           length;
326                 GLint             params[bufSize];
327                 glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, &length, params);
328                 if (length != expectedLength || length <= 0)
329                 {
330                         error = ERROR;
331                         m_context.getTestContext().getLog()
332                                 << tcu::TestLog::Message << "ERROR: Got length " << length << ", expected " << expectedLength
333                                 << "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index
334                                 << tcu::TestLog::EndMessage;
335                         return;
336                 }
337                 for (int i = 0; i < length; ++i)
338                 {
339                         if (params[i] != expected[i])
340                         {
341                                 error = ERROR;
342                                 m_context.getTestContext().getLog()
343                                         << tcu::TestLog::Message << "ERROR: Got " << params[i] << ", expected " << expected[i]
344                                         << " at: " << i << "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index
345                                         << tcu::TestLog::EndMessage;
346                         }
347                 }
348         }
349
350         virtual inline void VerifyGetProgramResourceLocationIndex(GLuint program, GLenum programInterface,
351                                                                                                                           const std::string& name, GLint expected, long& error)
352         {
353                 GLint res = glGetProgramResourceLocationIndex(program, programInterface, name.c_str());
354                 if (res != expected)
355                 {
356                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
357                                                                                                 << expected << "\nCALL: glGetProgramResourceLocationIndex, with "
358                                                                                                 << programInterface << ", " << name << tcu::TestLog::EndMessage;
359                         error = ERROR;
360                 }
361         }
362
363         virtual inline GLint GetProgramivRetValue(GLuint program, GLenum pname)
364         {
365                 GLint ret;
366                 glGetProgramiv(program, pname, &ret);
367                 return ret;
368         }
369
370         static const GLenum interfaces[];
371 };
372
373 const GLenum PIQBase::interfaces[] = { GL_PROGRAM_INPUT,
374                                                                            GL_PROGRAM_OUTPUT,
375                                                                            GL_UNIFORM,
376                                                                            GL_UNIFORM_BLOCK,
377                                                                            GL_BUFFER_VARIABLE,
378                                                                            GL_SHADER_STORAGE_BLOCK,
379                                                                            GL_VERTEX_SUBROUTINE,
380                                                                            GL_TESS_CONTROL_SUBROUTINE,
381                                                                            GL_TESS_EVALUATION_SUBROUTINE,
382                                                                            GL_GEOMETRY_SUBROUTINE,
383                                                                            GL_FRAGMENT_SUBROUTINE,
384                                                                            GL_COMPUTE_SUBROUTINE,
385                                                                            GL_VERTEX_SUBROUTINE_UNIFORM,
386                                                                            GL_TESS_CONTROL_SUBROUTINE_UNIFORM,
387                                                                            GL_TESS_EVALUATION_SUBROUTINE_UNIFORM,
388                                                                            GL_GEOMETRY_SUBROUTINE_UNIFORM,
389                                                                            GL_FRAGMENT_SUBROUTINE_UNIFORM,
390                                                                            GL_COMPUTE_SUBROUTINE_UNIFORM,
391                                                                            GL_TRANSFORM_FEEDBACK_VARYING };
392
393 class NoShaders : public PIQBase
394 {
395
396         virtual std::string Title()
397         {
398                 return "No Shaders Test";
399         }
400
401         virtual std::string ShadersDesc()
402         {
403                 return "no shaders";
404         }
405
406         virtual long Run()
407         {
408                 const GLuint program = glCreateProgram();
409
410                 long error = NO_ERROR;
411                 int  size  = sizeof(PIQBase::interfaces) / sizeof(PIQBase::interfaces[0]);
412
413                 for (int i = 0; i < size; ++i)
414                 {
415                         VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_ACTIVE_RESOURCES, 0, error);
416                         if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER)
417                                 continue;
418                         VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_MAX_NAME_LENGTH, 0, error);
419                 }
420                 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
421                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
422                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
423                 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0,
424                                                                         error);
425                 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0,
426                                                                         error);
427                 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0,
428                                                                         error);
429                 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES,
430                                                                         0, error);
431                 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0,
432                                                                         error);
433                 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0, error);
434
435                 for (int i = 0; i < size; ++i)
436                 {
437                         if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER)
438                                 continue;
439                         VerifyGetProgramResourceIndex(program, PIQBase::interfaces[i], "", GL_INVALID_INDEX, error);
440                 }
441
442                 // can't test GetProgramResourceLocation* here since program has to be linked
443                 // can't test GetProgramResourceiv, need valid index
444
445                 glDeleteProgram(program);
446                 return error;
447         }
448 };
449
450 class SimpleShaders : public PIQBase
451 {
452
453 public:
454         virtual std::string Title()
455         {
456                 return "Simple Shaders Test";
457         }
458
459         virtual std::string ShadersDesc()
460         {
461                 return "fallthrough fragment and vertex shaders";
462         }
463
464         virtual std::string VertexShader()
465         {
466                 return "#version 430                         \n"
467                            "in vec4 position;                    \n"
468                            "void main(void)                      \n"
469                            "{                                    \n"
470                            "    gl_Position = position;          \n"
471                            "}";
472         }
473
474         virtual std::string FragmentShader()
475         {
476                 return "#version 430                   \n"
477                            "out vec4 color;                \n"
478                            "void main() {                  \n"
479                            "    color = vec4(0, 1, 0, 1);  \n"
480                            "}";
481         }
482
483         virtual long Run()
484         {
485                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
486                 glBindAttribLocation(program, 0, "position");
487                 glBindFragDataLocation(program, 0, "color");
488                 LinkProgram(program);
489
490                 long error = NO_ERROR;
491
492                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
493                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
494                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
495                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
496
497                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
498                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
499
500                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
501                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
502
503                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
504                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
505
506                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
507
508                 GLenum props[] = { GL_NAME_LENGTH,
509                                                    GL_TYPE,
510                                                    GL_ARRAY_SIZE,
511                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
512                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
513                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
514                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
515                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
516                                                    GL_REFERENCED_BY_VERTEX_SHADER,
517                                                    GL_LOCATION,
518                                                    GL_IS_PER_PATCH };
519                 GLint expected[] = { 9, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, 0 };
520                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 11, props, 11, expected, error);
521
522                 GLenum props2[] = { GL_NAME_LENGTH,
523                                                         GL_TYPE,
524                                                         GL_ARRAY_SIZE,
525                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
526                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
527                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
528                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
529                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
530                                                         GL_REFERENCED_BY_VERTEX_SHADER,
531                                                         GL_LOCATION,
532                                                         GL_IS_PER_PATCH,
533                                                         GL_LOCATION_INDEX };
534                 GLint expected2[] = { 6, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
535                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 12, props2, 12, expected2, error);
536
537                 glDeleteProgram(program);
538                 return error;
539         }
540 };
541
542 class InputTypes : public SimpleShaders
543 {
544         virtual std::string Title()
545         {
546                 return "Input Types Test";
547         }
548
549         virtual std::string ShadersDesc()
550         {
551                 return "vertex shader with different `in` types and a fallthrough fragment shader";
552         }
553
554         virtual std::string VertexShader()
555         {
556                 return "#version 430                         \n"
557                            "in mat4 a;                           \n"
558                            "in ivec4 b;                          \n"
559                            "in float c[2];                       \n"
560                            "in mat2x3 d[2];                      \n"
561                            "in uvec2 e;                          \n"
562                            "in uint f;                           \n"
563                            "in vec3 g[2];                        \n"
564                            "in int h;                            \n"
565                            "void main(void)                      \n"
566                            "{                                    \n"
567                            "   vec4 pos;                                           \n"
568                            "   pos.w = h + g[0].x + g[1].y + d[1][1].y;            \n"
569                            "   pos.y = b.x * c[0] + c[1] + d[0][0].x;              \n"
570                            "   pos.x = a[0].x + a[1].y + a[2].z + a[3].w;          \n"
571                            "   pos.z = d[0][1].z + e.x * f + d[1][0].z;            \n"
572                            "   gl_Position = pos;                                  \n"
573                            "}";
574         }
575
576         virtual long Run()
577         {
578                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
579                 glBindAttribLocation(program, 0, "a");
580                 glBindAttribLocation(program, 4, "b");
581                 glBindAttribLocation(program, 5, "c");
582                 glBindAttribLocation(program, 7, "d");
583                 glBindAttribLocation(program, 11, "e");
584                 glBindAttribLocation(program, 12, "f");
585                 glBindAttribLocation(program, 13, "g");
586                 glBindAttribLocation(program, 15, "h");
587                 glBindFragDataLocation(program, 0, "color");
588                 LinkProgram(program);
589
590                 long error = NO_ERROR;
591
592                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error);
593                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 5, error);
594
595                 std::map<std::string, GLuint> indices;
596                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error);
597                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error);
598                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c[0]", error);
599                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error);
600                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error);
601                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error);
602                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error);
603                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error);
604
605                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error);
606                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error);
607                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c[0]"], "c[0]", error);
608                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d[0]", error);
609                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error);
610                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error);
611                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g[0]", error);
612                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error);
613
614                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error);
615                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error);
616                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c[0]", 5, error);
617                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error);
618                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c[1]", 6, error);
619                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d[0]", 7, error);
620                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error);
621                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error);
622                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error);
623                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g[0]", 13, error);
624                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error);
625                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g[1]", 14, error);
626                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error);
627
628                 GLenum props[] = { GL_NAME_LENGTH,
629                                                    GL_TYPE,
630                                                    GL_ARRAY_SIZE,
631                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
632                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
633                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
634                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
635                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
636                                                    GL_REFERENCED_BY_VERTEX_SHADER,
637                                                    GL_LOCATION,
638                                                    GL_IS_PER_PATCH };
639                 GLint expected[] = { 2, GL_FLOAT_MAT4, 1, 0, 0, 0, 0, 0, 1, 0, 0 };
640                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 11, props, 11, expected, error);
641                 GLint expected2[] = { 2, GL_INT_VEC4, 1, 0, 0, 0, 0, 0, 1, 4, 0 };
642                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 11, props, 11, expected2, error);
643                 GLint expected3[] = { 5, GL_FLOAT, 2, 0, 0, 0, 0, 0, 1, 5, 0 };
644                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c[0]"], 11, props, 11, expected3, error);
645                 GLint expected4[] = { 5, GL_FLOAT_MAT2x3, 2, 0, 0, 0, 0, 0, 1, 7, 0 };
646                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 11, props, 11, expected4, error);
647                 GLint expected5[] = { 2, GL_UNSIGNED_INT_VEC2, 1, 0, 0, 0, 0, 0, 1, 11, 0 };
648                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 11, props, 11, expected5, error);
649                 GLint expected6[] = { 2, GL_UNSIGNED_INT, 1, 0, 0, 0, 0, 0, 1, 12, 0 };
650                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 11, props, 11, expected6, error);
651                 GLint expected7[] = { 5, GL_FLOAT_VEC3, 2, 0, 0, 0, 0, 0, 1, 13, 0 };
652                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 11, props, 11, expected7, error);
653                 GLint expected8[] = { 2, GL_INT, 1, 0, 0, 0, 0, 0, 1, 15, 0 };
654                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 11, props, 11, expected8, error);
655
656                 glDeleteProgram(program);
657                 return error;
658         }
659 };
660
661 class OutputTypes : public SimpleShaders
662 {
663         virtual std::string Title()
664         {
665                 return "Output Types Test";
666         }
667
668         virtual std::string ShadersDesc()
669         {
670                 return "fragment shader with different `out` types and a fallthrough vertex shader";
671         }
672
673         virtual std::string FragmentShader()
674         {
675                 return "#version 430                   \n"
676                            "out vec3 a[2];                 \n"
677                            "out uint b;                    \n"
678                            "out float c[2];                \n"
679                            "out int d[2];                  \n"
680                            "out vec2 e;                    \n"
681                            "void main() {                  \n"
682                            "    c[1] = -0.6;               \n"
683                            "    d[0] = 0;                  \n"
684                            "    b = 12u;                   \n"
685                            "    c[0] = 1.1;                \n"
686                            "    e = vec2(0, 1);            \n"
687                            "    d[1] = -19;                \n"
688                            "    a[1] = vec3(0, 1, 0);      \n"
689                            "    a[0] = vec3(0, 1, 0);      \n"
690                            "}";
691         }
692
693         virtual long Run()
694         {
695                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
696                 glBindAttribLocation(program, 0, "position");
697                 glBindFragDataLocation(program, 0, "a");
698                 glBindFragDataLocation(program, 2, "b");
699                 glBindFragDataLocation(program, 3, "c");
700                 glBindFragDataLocation(program, 5, "d");
701                 glBindFragDataLocation(program, 7, "e");
702                 LinkProgram(program);
703
704                 long error = NO_ERROR;
705
706                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
707                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
708
709                 std::map<std::string, GLuint> indices;
710                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "a", error);
711                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "b", error);
712                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "c[0]", error);
713                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "d", error);
714                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "e", error);
715
716                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["a"], "a[0]", error);
717                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["b"], "b", error);
718                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["c[0]"], "c[0]", error);
719                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["d"], "d[0]", error);
720                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["e"], "e", error);
721
722                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
723                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a", 0, error);
724                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[1]", 1, error);
725                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "b", 2, error);
726                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c[0]", 3, error);
727                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c", 3, error);
728                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c[1]", 4, error);
729                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d[0]", 5, error);
730                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d", 5, error);
731                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d[1]", 6, error);
732                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "e", 7, error);
733
734                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
735                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "a", 0, error);
736                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "b", 0, error);
737                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "c[0]", 0, error);
738                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "c", 0, error);
739                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "d[0]", 0, error);
740                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "d", 0, error);
741                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "e", 0, error);
742
743                 GLenum props[] = { GL_NAME_LENGTH,
744                                                    GL_TYPE,
745                                                    GL_ARRAY_SIZE,
746                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
747                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
748                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
749                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
750                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
751                                                    GL_REFERENCED_BY_VERTEX_SHADER,
752                                                    GL_LOCATION,
753                                                    GL_IS_PER_PATCH,
754                                                    GL_LOCATION_INDEX };
755                 GLint expected[] = { 5, GL_FLOAT_VEC3, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
756                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["a"], 12, props, 12, expected, error);
757                 GLint expected2[] = { 2, GL_UNSIGNED_INT, 1, 0, 1, 0, 0, 0, 0, 2, 0, 0 };
758                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["b"], 12, props, 12, expected2, error);
759                 GLint expected3[] = { 5, GL_FLOAT, 2, 0, 1, 0, 0, 0, 0, 3, 0, 0 };
760                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["c[0]"], 12, props, 12, expected3, error);
761                 GLint expected4[] = { 5, GL_INT, 2, 0, 1, 0, 0, 0, 0, 5, 0, 0 };
762                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["d"], 12, props, 12, expected4, error);
763                 GLint expected5[] = { 2, GL_FLOAT_VEC2, 1, 0, 1, 0, 0, 0, 0, 7, 0, 0 };
764                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["e"], 12, props, 12, expected5, error);
765
766                 glDeleteProgram(program);
767                 return error;
768         }
769 };
770
771 class OutputLocationIndex : public SimpleShaders
772 {
773         virtual std::string Title()
774         {
775                 return "Output Location Index Test";
776         }
777
778         virtual std::string ShadersDesc()
779         {
780                 return "fragment shader with `out` location index different from 0 and a fallthrough vertex shader";
781         }
782
783         virtual long Run()
784         {
785                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
786                 glBindAttribLocation(program, 0, "position");
787                 glBindFragDataLocationIndexed(program, 0, 1, "color");
788                 LinkProgram(program);
789
790                 long error = NO_ERROR;
791
792                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
793
794                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "color", 1, error);
795
796                 GLenum props[] = { GL_NAME_LENGTH,
797                                                    GL_TYPE,
798                                                    GL_ARRAY_SIZE,
799                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
800                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
801                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
802                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
803                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
804                                                    GL_REFERENCED_BY_VERTEX_SHADER,
805                                                    GL_LOCATION,
806                                                    GL_IS_PER_PATCH,
807                                                    GL_LOCATION_INDEX };
808                 GLint expected[] = { 6, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
809                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 12, props, 12, expected, error);
810
811                 glDeleteProgram(program);
812                 return error;
813         }
814 };
815
816 class InputBuiltIn : public SimpleShaders
817 {
818
819         virtual std::string Title()
820         {
821                 return "Input Built-ins Test";
822         }
823
824         virtual std::string ShadersDesc()
825         {
826                 return "vertex shader using built-in variables and a fallthrough fragment shader";
827         }
828
829         virtual std::string Expectations()
830         {
831                 return ".\n\n In this case we ask for information about built-in variables for the input interface.";
832         }
833
834         virtual std::string VertexShader()
835         {
836                 return "#version 430                         \n"
837                            "void main(void)                      \n"
838                            "{                                    \n"
839                            "    gl_Position = (gl_VertexID + gl_InstanceID) * vec4(0.1);          \n"
840                            "}";
841         }
842
843         virtual long Run()
844         {
845                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
846                 glBindFragDataLocation(program, 0, "color");
847                 LinkProgram(program);
848
849                 long error = NO_ERROR;
850
851                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 2, error);
852                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 14, error);
853
854                 std::map<std::string, GLuint> indices;
855                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_VertexID", error);
856                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_InstanceID", error);
857
858                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], "gl_VertexID", error);
859                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], "gl_InstanceID", error);
860
861                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_VertexID", -1, error);
862                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_InstanceID", -1, error);
863
864                 GLenum props[] = { GL_NAME_LENGTH,
865                                                    GL_TYPE,
866                                                    GL_ARRAY_SIZE,
867                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
868                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
869                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
870                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
871                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
872                                                    GL_REFERENCED_BY_VERTEX_SHADER,
873                                                    GL_LOCATION,
874                                                    GL_IS_PER_PATCH };
875                 GLint expected[] = { 12, GL_INT, 1, 0, 0, 0, 0, 0, 1, -1, 0 };
876                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], 11, props, 11, expected, error);
877                 GLint expected2[] = { 14, GL_INT, 1, 0, 0, 0, 0, 0, 1, -1, 0 };
878                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], 11, props, 11, expected2,
879                                                                    error);
880
881                 glDeleteProgram(program);
882                 return error;
883         }
884 };
885
886 class OutputBuiltIn : public SimpleShaders
887 {
888
889         virtual std::string Title()
890         {
891                 return "Output Built-ins Test";
892         }
893
894         virtual std::string ShadersDesc()
895         {
896                 return "fragment shader using built-in variables and a fallthrough vertex shader";
897         }
898
899         virtual std::string Expectations()
900         {
901                 return ".\n\n In this case we ask for information about built-in variables for the output interface.";
902         }
903
904         virtual std::string FragmentShader()
905         {
906                 return "#version 430                               \n"
907                            "void main(void)                            \n"
908                            "{                                          \n"
909                            "    gl_FragDepth = 0.1;                    \n"
910                            "    gl_SampleMask[0] = 1;                  \n"
911                            "}";
912         }
913
914         virtual long Run()
915         {
916                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), true);
917
918                 long error = NO_ERROR;
919
920                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 2, error);
921                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 17, error);
922
923                 std::map<std::string, GLuint> indices;
924                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "gl_FragDepth", error);
925                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "gl_SampleMask[0]", error);
926
927                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], "gl_FragDepth", error);
928                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["gl_SampleMask[0]"], "gl_SampleMask[0]",
929                                                                          error);
930
931                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_FragDepth", -1, error);
932                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_SampleMask", -1, error);
933                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_SampleMask[0]", -1, error);
934
935                 // spec is not clear what to require here
936                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "gl_FragDepth", -1, error);
937                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "gl_SampleMask", -1, error);
938                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "gl_SampleMask[0]", -1, error);
939
940                 GLenum props[] = { GL_NAME_LENGTH,
941                                                    GL_TYPE,
942                                                    GL_ARRAY_SIZE,
943                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
944                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
945                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
946                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
947                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
948                                                    GL_REFERENCED_BY_VERTEX_SHADER,
949                                                    GL_LOCATION,
950                                                    GL_IS_PER_PATCH,
951                                                    GL_LOCATION_INDEX };
952                 GLint expected[] = { 13, GL_FLOAT, 1, 0, 1, 0, 0, 0, 0, -1, 0, -1 };
953                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], 12, props, 12, expected, error);
954                 GLint expected2[] = { 17, GL_INT, 1, 0, 1, 0, 0, 0, 0, -1, 0, -1 };
955                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["gl_SampleMask[0]"], 12, props, 12, expected2,
956                                                                    error);
957
958                 glDeleteProgram(program);
959                 return error;
960         }
961 };
962
963 class InputLayout : public SimpleShaders
964 {
965         virtual std::string Title()
966         {
967                 return "Input Layout Test";
968         }
969
970         virtual std::string ShadersDesc()
971         {
972                 return "vertex shader with different `in` variables locations set through layout and a fallthrough fragment "
973                            "shader";
974         }
975
976         virtual std::string VertexShader()
977         {
978                 return "#version 430                         \n"
979                            "layout(location = 4) in ivec4 b;     \n"
980                            "layout(location = 7) in mat2x3 d[2]; \n"
981                            "layout(location = 5) in float c[2];  \n"
982                            "layout(location = 12) in uint f;     \n"
983                            "layout(location = 13) in vec3 g[2];  \n"
984                            "layout(location = 0) in mat4 a;      \n"
985                            "layout(location = 15) in int h;      \n"
986                            "layout(location = 11) in uvec2 e;    \n"
987                            "void main(void)                      \n"
988                            "{                                    \n"
989                            "   vec4 pos;                                           \n"
990                            "   pos.w = h + g[0].x + g[1].y + d[1][1].y;            \n"
991                            "   pos.y = b.x * c[0] + c[1] + d[0][0].x;              \n"
992                            "   pos.x = a[0].x + a[1].y + a[2].z + a[3].w;          \n"
993                            "   pos.z = d[0][1].z + e.x * f + d[1][0].z;            \n"
994                            "   gl_Position = pos;                                  \n"
995                            "}";
996         }
997
998         virtual long Run()
999         {
1000                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1001                 glBindFragDataLocation(program, 0, "color");
1002                 LinkProgram(program);
1003
1004                 long error = NO_ERROR;
1005
1006                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error);
1007                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 5, error);
1008
1009                 std::map<std::string, GLuint> indices;
1010                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error);
1011                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error);
1012                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c[0]", error);
1013                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error);
1014                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error);
1015                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error);
1016                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error);
1017                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error);
1018
1019                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error);
1020                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error);
1021                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c[0]"], "c[0]", error);
1022                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d[0]", error);
1023                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error);
1024                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error);
1025                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g[0]", error);
1026                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error);
1027
1028                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error);
1029                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error);
1030                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c[0]", 5, error);
1031                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error);
1032                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c[1]", 6, error);
1033                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d[0]", 7, error);
1034                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error);
1035                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error);
1036                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error);
1037                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g[0]", 13, error);
1038                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error);
1039                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g[1]", 14, error);
1040                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error);
1041
1042                 GLenum props[] = { GL_NAME_LENGTH,
1043                                                    GL_TYPE,
1044                                                    GL_ARRAY_SIZE,
1045                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
1046                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
1047                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
1048                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1049                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1050                                                    GL_REFERENCED_BY_VERTEX_SHADER,
1051                                                    GL_LOCATION,
1052                                                    GL_IS_PER_PATCH };
1053                 GLint expected[] = { 2, GL_FLOAT_MAT4, 1, 0, 0, 0, 0, 0, 1, 0, 0 };
1054                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 11, props, 11, expected, error);
1055                 GLint expected2[] = { 2, GL_INT_VEC4, 1, 0, 0, 0, 0, 0, 1, 4, 0 };
1056                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 11, props, 11, expected2, error);
1057                 GLint expected3[] = { 5, GL_FLOAT, 2, 0, 0, 0, 0, 0, 1, 5, 0 };
1058                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c[0]"], 11, props, 11, expected3, error);
1059                 GLint expected4[] = { 5, GL_FLOAT_MAT2x3, 2, 0, 0, 0, 0, 0, 1, 7, 0 };
1060                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 11, props, 11, expected4, error);
1061                 GLint expected5[] = { 2, GL_UNSIGNED_INT_VEC2, 1, 0, 0, 0, 0, 0, 1, 11, 0 };
1062                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 11, props, 11, expected5, error);
1063                 GLint expected6[] = { 2, GL_UNSIGNED_INT, 1, 0, 0, 0, 0, 0, 1, 12, 0 };
1064                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 11, props, 11, expected6, error);
1065                 GLint expected7[] = { 5, GL_FLOAT_VEC3, 2, 0, 0, 0, 0, 0, 1, 13, 0 };
1066                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 11, props, 11, expected7, error);
1067                 GLint expected8[] = { 2, GL_INT, 1, 0, 0, 0, 0, 0, 1, 15, 0 };
1068                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 11, props, 11, expected8, error);
1069
1070                 glDeleteProgram(program);
1071                 return error;
1072         }
1073 };
1074
1075 class OutputLayout : public SimpleShaders
1076 {
1077         virtual std::string Title()
1078         {
1079                 return "Output Layout Test";
1080         }
1081
1082         virtual std::string ShadersDesc()
1083         {
1084                 return "fragment shader with different `out` variables locations set through layout and a fallthrough vertex "
1085                            "shader";
1086         }
1087
1088         virtual std::string FragmentShader()
1089         {
1090                 return "#version 430                   \n"
1091                            "layout(location = 2) out uint b;                    \n"
1092                            "layout(location = 7) out vec2 e;                    \n"
1093                            "layout(location = 3) out float c[2];                \n"
1094                            "layout(location = 5) out int d[2];                  \n"
1095                            "layout(location = 0) out vec3 a[2];                 \n"
1096                            "void main() {                  \n"
1097                            "    c[1] = -0.6;               \n"
1098                            "    d[0] = 0;                  \n"
1099                            "    b = 12u;                   \n"
1100                            "    c[0] = 1.1;                \n"
1101                            "    e = vec2(0, 1);            \n"
1102                            "    d[1] = -19;                \n"
1103                            "    a[1] = vec3(0, 1, 0);      \n"
1104                            "    a[0] = vec3(0, 1, 0);      \n"
1105                            "}";
1106         }
1107
1108         virtual long Run()
1109         {
1110                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1111                 glBindAttribLocation(program, 0, "position");
1112                 LinkProgram(program);
1113
1114                 long error = NO_ERROR;
1115
1116                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
1117                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
1118
1119                 std::map<std::string, GLuint> indices;
1120                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "a", error);
1121                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "b", error);
1122                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "c[0]", error);
1123                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "d", error);
1124                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "e", error);
1125
1126                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["a"], "a[0]", error);
1127                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["b"], "b", error);
1128                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["c[0]"], "c[0]", error);
1129                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["d"], "d[0]", error);
1130                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["e"], "e", error);
1131
1132                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
1133                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a", 0, error);
1134                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[1]", 1, error);
1135                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "b", 2, error);
1136                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c[0]", 3, error);
1137                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c", 3, error);
1138                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c[1]", 4, error);
1139                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d[0]", 5, error);
1140                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d", 5, error);
1141                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d[1]", 6, error);
1142                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "e", 7, error);
1143
1144                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
1145                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "a", 0, error);
1146                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "b", 0, error);
1147                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "c[0]", 0, error);
1148                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "c", 0, error);
1149                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "d[0]", 0, error);
1150                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "d", 0, error);
1151                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "e", 0, error);
1152
1153                 GLenum props[] = { GL_NAME_LENGTH,
1154                                                    GL_TYPE,
1155                                                    GL_ARRAY_SIZE,
1156                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
1157                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
1158                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
1159                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1160                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1161                                                    GL_REFERENCED_BY_VERTEX_SHADER,
1162                                                    GL_LOCATION,
1163                                                    GL_IS_PER_PATCH,
1164                                                    GL_LOCATION_INDEX };
1165                 GLint expected[] = { 5, GL_FLOAT_VEC3, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
1166                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["a"], 12, props, 12, expected, error);
1167                 GLint expected2[] = { 2, GL_UNSIGNED_INT, 1, 0, 1, 0, 0, 0, 0, 2, 0, 0 };
1168                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["b"], 12, props, 12, expected2, error);
1169                 GLint expected3[] = { 5, GL_FLOAT, 2, 0, 1, 0, 0, 0, 0, 3, 0, 0 };
1170                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["c[0]"], 12, props, 12, expected3, error);
1171                 GLint expected4[] = { 5, GL_INT, 2, 0, 1, 0, 0, 0, 0, 5, 0, 0 };
1172                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["d"], 12, props, 12, expected4, error);
1173                 GLint expected5[] = { 2, GL_FLOAT_VEC2, 1, 0, 1, 0, 0, 0, 0, 7, 0, 0 };
1174                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["e"], 12, props, 12, expected5, error);
1175
1176                 glDeleteProgram(program);
1177                 return error;
1178         }
1179 };
1180
1181 class OutputLayoutIndex : public SimpleShaders
1182 {
1183         virtual std::string Title()
1184         {
1185                 return "Output Layout Index Test";
1186         }
1187
1188         virtual std::string ShadersDesc()
1189         {
1190                 return "fragment shader with different `out` variables fragment color index\n"
1191                            "locations set through layout and a fallthrough vertex shader";
1192         }
1193
1194         virtual std::string FragmentShader()
1195         {
1196                 return "#version 430                   \n"
1197                            "layout(location = 0, index = 1) out vec4 color;                \n"
1198                            "void main() {                  \n"
1199                            "    color = vec4(0, 1, 0, 1);  \n"
1200                            "}";
1201         }
1202
1203         virtual long Run()
1204         {
1205                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1206                 glBindAttribLocation(program, 0, "position");
1207                 LinkProgram(program);
1208
1209                 long error = NO_ERROR;
1210
1211                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
1212
1213                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "color", 1, error);
1214
1215                 GLenum props[] = { GL_NAME_LENGTH,
1216                                                    GL_TYPE,
1217                                                    GL_ARRAY_SIZE,
1218                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
1219                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
1220                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
1221                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1222                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1223                                                    GL_REFERENCED_BY_VERTEX_SHADER,
1224                                                    GL_LOCATION,
1225                                                    GL_IS_PER_PATCH,
1226                                                    GL_LOCATION_INDEX };
1227                 GLint expected[] = { 6, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
1228                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 12, props, 12, expected, error);
1229
1230                 glDeleteProgram(program);
1231                 return error;
1232         }
1233 };
1234
1235 class UniformSimple : public PIQBase
1236 {
1237         virtual std::string Title()
1238         {
1239                 return "Uniform Simple Test";
1240         }
1241
1242         virtual std::string ShadersDesc()
1243         {
1244                 return "fallthrough fragment and vertex shaders with uniforms used";
1245         }
1246
1247         virtual std::string PurposeExt()
1248         {
1249                 return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.";
1250         }
1251
1252         virtual std::string VertexShader()
1253         {
1254                 return "#version 430                         \n"
1255                            "in vec4 position;                    \n"
1256                            "uniform vec4 repos;                  \n"
1257                            "void main(void)                      \n"
1258                            "{                                    \n"
1259                            "    gl_Position = position + repos;  \n"
1260                            "}";
1261         }
1262
1263         virtual std::string FragmentShader()
1264         {
1265                 return "#version 430                   \n"
1266                            "uniform vec4 recolor;          \n"
1267                            "out vec4 color;                \n"
1268                            "void main() {                  \n"
1269                            "    color = vec4(0, 1, 0, 1) + recolor;  \n"
1270                            "}";
1271         }
1272
1273         virtual long Run()
1274         {
1275                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1276                 glBindAttribLocation(program, 0, "position");
1277                 glBindFragDataLocation(program, 0, "color");
1278                 LinkProgram(program);
1279
1280                 long error = NO_ERROR;
1281
1282                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1283                                                                         GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1284                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 8, error);
1285
1286                 std::map<std::string, GLuint> indices;
1287                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "repos", error);
1288                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "recolor", error);
1289
1290                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["repos"], "repos", error);
1291                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["recolor"], "recolor", error);
1292
1293                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "repos", glGetUniformLocation(program, "repos"), error);
1294                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "recolor", glGetUniformLocation(program, "recolor"),
1295                                                                                  error);
1296
1297                 GLenum props[] = { GL_NAME_LENGTH,
1298                                                    GL_TYPE,
1299                                                    GL_ARRAY_SIZE,
1300                                                    GL_OFFSET,
1301                                                    GL_BLOCK_INDEX,
1302                                                    GL_ARRAY_STRIDE,
1303                                                    GL_MATRIX_STRIDE,
1304                                                    GL_IS_ROW_MAJOR,
1305                                                    GL_ATOMIC_COUNTER_BUFFER_INDEX,
1306                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
1307                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
1308                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
1309                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1310                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1311                                                    GL_REFERENCED_BY_VERTEX_SHADER,
1312                                                    GL_LOCATION };
1313                 GLint expected[] = {
1314                         6, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "repos")
1315                 };
1316                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["repos"], 16, props, 16, expected, error);
1317
1318                 GLint expected2[] = {
1319                         8, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "recolor")
1320                 };
1321                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["recolor"], 16, props, 16, expected2, error);
1322
1323                 glDeleteProgram(program);
1324                 return error;
1325         }
1326 };
1327
1328 class UniformTypes : public PIQBase
1329 {
1330         virtual std::string Title()
1331         {
1332                 return "Uniform Types Test";
1333         }
1334
1335         virtual std::string ShadersDesc()
1336         {
1337                 return "fallthrough fragment and vertex shaders with different uniform types used";
1338         }
1339
1340         virtual std::string PurposeExt()
1341         {
1342                 return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.\n";
1343         }
1344
1345         virtual std::string VertexShader()
1346         {
1347                 return "#version 430                         \n"
1348                            "in vec4 position;                    \n"
1349                            "uniform vec4 a;                      \n"
1350                            "uniform ivec3 b;                     \n"
1351                            "uniform uvec2 c[3];                  \n"
1352                            "uniform mat2 g[8];                   \n"
1353                            "uniform mat3x2 i;                    \n"
1354                            "void main(void)                      \n"
1355                            "{                                    \n"
1356                            "    float tmp;                       \n"
1357                            "    tmp =  g[0][1][1] + a.z + b.y + c[0].x;   \n"
1358                            "    tmp += g[1][1][1] + c[1].x;      \n"
1359                            "    tmp += g[2][1][1] + c[2].x;      \n"
1360                            "    for (int i = 3; i < 8; ++i)      \n"
1361                            "        tmp += g[i][1][1];           \n"
1362                            "    tmp = tmp + i[1][1];             \n"
1363                            "    gl_Position = position * tmp;    \n"
1364                            "}";
1365         }
1366
1367         virtual std::string FragmentShader()
1368         {
1369                 return "#version 430                   \n"
1370                            "struct U {                     \n"
1371                            "   bool a[3];                  \n"
1372                            "   vec4 b;                     \n"
1373                            "   mat3 c;                     \n"
1374                            "   float d[2];                 \n"
1375                            "};                             \n"
1376                            "struct UU {                    \n"
1377                            "   U a;                        \n"
1378                            "   U b[2];                     \n"
1379                            "   uvec2 c;                    \n"
1380                            "};                             \n"
1381                            "uniform mat4 d;                \n"
1382                            "uniform mat3 e;                \n"
1383                            "uniform float h;               \n"
1384                            "uniform int f;                 \n"
1385                            "uniform U j;                   \n"
1386                            "uniform UU k;                  \n"
1387                            "uniform UU l[3];               \n"
1388                            "out vec4 color;                \n"
1389                            "void main() {                  \n"
1390                            "    float tmp;                 \n"
1391                            "    tmp = h + f + e[2][2];           \n"
1392                            "    tmp = tmp + d[0][0] + j.b.x;     \n"
1393                            "    tmp = tmp + k.b[0].c[0][0];      \n"
1394                            "    tmp = tmp + l[2].a.c[0][1];      \n"
1395                            "    tmp = tmp + l[2].b[1].d[0];      \n"
1396                            "    tmp = tmp + l[2].b[1].d[1];      \n"
1397                            "    tmp = tmp + l[0].c.x;            \n"
1398                            "    color = vec4(0, 1, 0, 1) * tmp;  \n"
1399                            "}";
1400         }
1401
1402         virtual long Run()
1403         {
1404                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1405                 glBindAttribLocation(program, 0, "position");
1406                 glBindFragDataLocation(program, 0, "color");
1407                 LinkProgram(program);
1408
1409                 long error = NO_ERROR;
1410
1411                 // only active structure members
1412                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1413                                                                         GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1414                 // l[2].b[1].d[0] and \0
1415                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 15, error);
1416
1417                 std::map<std::string, GLuint> indices;
1418                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a", error);
1419                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "b", error);
1420                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "c", error);
1421                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "d", error);
1422                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "e", error);
1423                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "f", error);
1424                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "g", error);
1425                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "h", error);
1426                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "i", error);
1427                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "j.b", error);
1428                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "k.b[0].c", error);
1429                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[0].c", error);
1430                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].b[1].d[0]", error);
1431                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].a.c", error);
1432
1433                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a"], "a", error);
1434                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["b"], "b", error);
1435                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["c"], "c[0]", error);
1436                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["d"], "d", error);
1437                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["e"], "e", error);
1438                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["f"], "f", error);
1439                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["g"], "g[0]", error);
1440                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["h"], "h", error);
1441                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["i"], "i", error);
1442                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["j.b"], "j.b", error);
1443                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["k.b[0].c"], "k.b[0].c", error);
1444                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[0].c"], "l[0].c", error);
1445                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], "l[2].b[1].d[0]", error);
1446                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].a.c"], "l[2].a.c", error);
1447
1448                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
1449                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", glGetUniformLocation(program, "b"), error);
1450                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", glGetUniformLocation(program, "c"), error);
1451                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", glGetUniformLocation(program, "d"), error);
1452                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", glGetUniformLocation(program, "e"), error);
1453                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "f", glGetUniformLocation(program, "f"), error);
1454                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "g", glGetUniformLocation(program, "g"), error);
1455                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "h", glGetUniformLocation(program, "h"), error);
1456                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "i", glGetUniformLocation(program, "i"), error);
1457                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "j.b", glGetUniformLocation(program, "j.b"), error);
1458                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "k.b[0].c", glGetUniformLocation(program, "k.b[0].c"),
1459                                                                                  error);
1460                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[0].c", glGetUniformLocation(program, "l[0].c"), error);
1461                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].b[1].d[0]",
1462                                                                                  glGetUniformLocation(program, "l[2].b[1].d[0]"), error);
1463                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].a.c", glGetUniformLocation(program, "l[2].a.c"),
1464                                                                                  error);
1465
1466                 GLenum props[] = { GL_NAME_LENGTH,
1467                                                    GL_TYPE,
1468                                                    GL_ARRAY_SIZE,
1469                                                    GL_OFFSET,
1470                                                    GL_BLOCK_INDEX,
1471                                                    GL_ARRAY_STRIDE,
1472                                                    GL_MATRIX_STRIDE,
1473                                                    GL_IS_ROW_MAJOR,
1474                                                    GL_ATOMIC_COUNTER_BUFFER_INDEX,
1475                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
1476                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
1477                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
1478                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1479                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1480                                                    GL_REFERENCED_BY_VERTEX_SHADER,
1481                                                    GL_LOCATION };
1482                 GLint expected[] = {
1483                         2, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "a")
1484                 };
1485                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a"], 16, props, 16, expected, error);
1486                 GLint expected2[] = { 2,  GL_INT_VEC3, 1, -1, -1, -1, -1, 0,
1487                                                           -1, 0,                   0, 0,  0,  0,  1,  glGetUniformLocation(program, "b") };
1488                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["b"], 16, props, 16, expected2, error);
1489                 GLint expected3[] = {
1490                         5, GL_UNSIGNED_INT_VEC2, 3, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "c")
1491                 };
1492                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["c"], 16, props, 16, expected3, error);
1493                 GLint expected4[] = {
1494                         2, GL_FLOAT_MAT4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "d")
1495                 };
1496                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["d"], 16, props, 16, expected4, error);
1497                 GLint expected5[] = {
1498                         2, GL_FLOAT_MAT3, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "e")
1499                 };
1500                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["e"], 16, props, 16, expected5, error);
1501                 GLint expected6[] = {
1502                         2, GL_INT, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "f")
1503                 };
1504                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["f"], 16, props, 16, expected6, error);
1505                 GLint expected7[] = {
1506                         5, GL_FLOAT_MAT2, 8, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "g")
1507                 };
1508                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["g"], 16, props, 16, expected7, error);
1509                 GLint expected8[] = { 2,  GL_FLOAT, 1, -1, -1, -1, -1, 0,
1510                                                           -1, 0,                1, 0,  0,  0,  0,  glGetUniformLocation(program, "h") };
1511                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["h"], 16, props, 16, expected8, error);
1512                 GLint expected9[] = {
1513                         2, GL_FLOAT_MAT3x2, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "i")
1514                 };
1515                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["i"], 16, props, 16, expected9, error);
1516                 GLint expected10[] = {
1517                         4, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "j.b")
1518                 };
1519                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["j.b"], 16, props, 16, expected10, error);
1520                 GLint expected11[] = {
1521                         9, GL_FLOAT_MAT3, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "k.b[0].c")
1522                 };
1523                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["k.b[0].c"], 16, props, 16, expected11, error);
1524                 GLint expected12[] = { 7,  GL_UNSIGNED_INT_VEC2,
1525                                                            1,  -1,
1526                                                            -1, -1,
1527                                                            -1, 0,
1528                                                            -1, 0,
1529                                                            1,  0,
1530                                                            0,  0,
1531                                                            0,  glGetUniformLocation(program, "l[0].c") };
1532                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[0].c"], 16, props, 16, expected12, error);
1533                 GLint expected13[] = { 15, GL_FLOAT, 2, -1, -1, -1, -1, 0,
1534                                                            -1, 0,                1, 0,  0,  0,  0,  glGetUniformLocation(program, "l[2].b[1].d[0]") };
1535                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], 16, props, 16, expected13, error);
1536                 GLint expected14[] = {
1537                         9, GL_FLOAT_MAT3, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "l[2].a.c")
1538                 };
1539                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].a.c"], 16, props, 16, expected14, error);
1540
1541                 glDeleteProgram(program);
1542                 return error;
1543         }
1544 };
1545
1546 class UniformBlockTypes : public PIQBase
1547 {
1548         virtual std::string Title()
1549         {
1550                 return "Uniform Block Types Test";
1551         }
1552
1553         virtual std::string ShadersDesc()
1554         {
1555                 return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
1556         }
1557
1558         virtual std::string PurposeExt()
1559         {
1560                 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param.\n";
1561         }
1562
1563         virtual std::string VertexShader()
1564         {
1565                 return "#version 430                         \n"
1566                            "in vec4 position;                    \n"
1567                            ""
1568                            "uniform SimpleBlock {                \n"
1569                            "   mat3x2 a;                         \n"
1570                            "   mat4 b;                           \n"
1571                            "   vec4 c;                           \n"
1572                            "};                                   \n"
1573                            ""
1574                            "uniform NotSoSimpleBlockk {          \n"
1575                            "   ivec2 a[4];                       \n"
1576                            "   mat3 b[2];                        \n"
1577                            "   mat2 c;                           \n"
1578                            "} d;                                 \n"
1579                            ""
1580                            "void main(void)                      \n"
1581                            "{                                    \n"
1582                            "    float tmp;                       \n"
1583                            "    tmp =  a[0][1] * b[1][2] * c.x;  \n"
1584                            "    tmp = tmp + d.a[2].y + d.b[0][1][1] + d.c[1][1];             \n"
1585                            "    gl_Position = position * tmp;    \n"
1586                            "}";
1587         }
1588
1589         virtual std::string FragmentShader()
1590         {
1591                 return "#version 430                   \n"
1592                            "struct U {                     \n"
1593                            "   bool a[3];                  \n"
1594                            "   vec4 b;                     \n"
1595                            "   mat3 c;                     \n"
1596                            "   float d[2];                 \n"
1597                            "};                             \n"
1598                            "struct UU {                    \n"
1599                            "   U a;                        \n"
1600                            "   U b[2];                     \n"
1601                            "   uvec2 c;                    \n"
1602                            "};                             \n"
1603                            ""
1604                            "uniform TrickyBlock {                            \n"
1605                            "   UU a[3];                                      \n"
1606                            "   mat4 b;                                       \n"
1607                            "   uint c;                                       \n"
1608                            "} e[2];                                          \n"
1609                            ""
1610                            "out vec4 color;                                \n"
1611                            "void main() {                                  \n"
1612                            "    float tmp;                                 \n"
1613                            "    tmp = e[0].a[2].b[0].d[1];                 \n"
1614                            "    color = vec4(0, 1, 0, 1) * tmp;            \n"
1615                            "}";
1616         }
1617
1618         virtual long Run()
1619         {
1620                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1621                 glBindAttribLocation(program, 0, "position");
1622                 glBindFragDataLocation(program, 0, "color");
1623                 LinkProgram(program);
1624
1625                 long error = NO_ERROR;
1626
1627                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1628                                                                         GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1629                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, 4, error);
1630                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
1631
1632                 std::map<std::string, GLuint> indicesUB;
1633                 std::map<std::string, GLuint> indicesU;
1634                 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "SimpleBlock", error);
1635                 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "NotSoSimpleBlockk", error);
1636                 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock", error);
1637                 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock[1]", error);
1638                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1639                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1640                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1641                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.a[0]", error);
1642                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.c", error);
1643                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.b[0]", error);
1644                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TrickyBlock.a[2].b[0].d", error);
1645
1646                 glUniformBlockBinding(program, indicesUB["SimpleBlock"], 0);
1647                 glUniformBlockBinding(program, indicesUB["NotSoSimpleBlockk"], 2);
1648                 glUniformBlockBinding(program, indicesUB["TrickyBlock"], 3);
1649                 glUniformBlockBinding(program, indicesUB["TrickyBlock[1]"], 4);
1650
1651                 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], "SimpleBlock", error);
1652                 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], "NotSoSimpleBlockk",
1653                                                                          error);
1654                 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], "TrickyBlock[0]", error);
1655                 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], "TrickyBlock[1]", error);
1656                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1657                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1658                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1659                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.a[0]"], "NotSoSimpleBlockk.a[0]",
1660                                                                          error);
1661                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.c"], "NotSoSimpleBlockk.c",
1662                                                                          error);
1663                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.b[0]"], "NotSoSimpleBlockk.b[0]",
1664                                                                          error);
1665                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"],
1666                                                                          "TrickyBlock.a[2].b[0].d[0]", error);
1667
1668                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1669                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1670                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1671
1672                 GLenum props[] = {
1673                         GL_NAME_LENGTH,
1674                         GL_BUFFER_BINDING,
1675                         GL_REFERENCED_BY_COMPUTE_SHADER,
1676                         GL_REFERENCED_BY_FRAGMENT_SHADER,
1677                         GL_REFERENCED_BY_GEOMETRY_SHADER,
1678                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1679                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1680                         GL_REFERENCED_BY_VERTEX_SHADER,
1681                         GL_BUFFER_DATA_SIZE,
1682                 };
1683                 GLint size;
1684                 glGetActiveUniformBlockiv(program, indicesUB["SimpleBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1685                 GLint expected[] = { 12, 0, 0, 0, 0, 0, 0, 1, size };
1686                 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 9, props, 9, expected, error);
1687                 glGetActiveUniformBlockiv(program, indicesUB["NotSoSimpleBlockk"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1688                 GLint expected2[] = { 18, 2, 0, 0, 0, 0, 0, 1, size };
1689                 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 9, props, 9, expected2,
1690                                                                    error);
1691                 glGetActiveUniformBlockiv(program, indicesUB["TrickyBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1692                 GLint expected3[] = { 15, 3, 0, 1, 0, 0, 0, 0, size };
1693                 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], 9, props, 9, expected3, error);
1694                 GLint expected4[] = { 15, 4, 0, 0, 0, 0, 0, 0, size };
1695                 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], 9, props, 9, expected4,
1696                                                                    error);
1697
1698                 GLenum props2[] = { GL_NAME_LENGTH,
1699                                                         GL_TYPE,
1700                                                         GL_ARRAY_SIZE,
1701                                                         GL_BLOCK_INDEX,
1702                                                         GL_ARRAY_STRIDE,
1703                                                         GL_IS_ROW_MAJOR,
1704                                                         GL_ATOMIC_COUNTER_BUFFER_INDEX,
1705                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
1706                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
1707                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
1708                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1709                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1710                                                         GL_REFERENCED_BY_VERTEX_SHADER,
1711                                                         GL_LOCATION };
1712                 GLint expected5[] = {
1713                         2, GL_FLOAT_MAT3x2, 1, static_cast<GLint>(indicesUB["SimpleBlock"]), 0, 0, -1, 0, 0, 0, 0, 0, 1, -1
1714                 };
1715                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 14, props2, 14, expected5, error);
1716                 GLenum props3[] = { GL_NAME_LENGTH,
1717                                                         GL_TYPE,
1718                                                         GL_ARRAY_SIZE,
1719                                                         GL_BLOCK_INDEX,
1720                                                         GL_MATRIX_STRIDE,
1721                                                         GL_IS_ROW_MAJOR,
1722                                                         GL_ATOMIC_COUNTER_BUFFER_INDEX,
1723                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
1724                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
1725                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
1726                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1727                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1728                                                         GL_REFERENCED_BY_VERTEX_SHADER,
1729                                                         GL_LOCATION };
1730                 GLint expected6[] = { 27, GL_FLOAT, 2, static_cast<GLint>(indicesUB["TrickyBlock"]), 0, 0, -1, 0, 1, 0, 0,
1731                                                           0,  0,                -1 };
1732                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"], 14, props3, 14, expected6,
1733                                                                    error);
1734
1735                 GLenum                   prop   = GL_ACTIVE_VARIABLES;
1736                 const GLsizei   bufSize = 1000;
1737                 GLsizei                  length;
1738                 GLint                    param[bufSize];
1739                 std::set<GLuint> exp;
1740                 exp.insert(indicesU["a"]);
1741                 exp.insert(indicesU["b"]);
1742                 exp.insert(indicesU["c"]);
1743                 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 1, &prop, bufSize, &length, param);
1744                 for (int i = 0; i < length; ++i)
1745                 {
1746                         if (exp.find(param[i]) == exp.end())
1747                         {
1748                                 m_context.getTestContext().getLog()
1749                                         << tcu::TestLog::Message
1750                                         << "Unexpected index found in active variables of SimpleBlock: " << param[i]
1751                                         << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1752                                         << tcu::TestLog::EndMessage;
1753                                 glDeleteProgram(program);
1754                                 return ERROR;
1755                         }
1756                         else if (length != 3)
1757                         {
1758                                 m_context.getTestContext().getLog()
1759                                         << tcu::TestLog::Message
1760                                         << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK\n"
1761                                         << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1762                                 glDeleteProgram(program);
1763                                 return ERROR;
1764                         }
1765                 }
1766                 std::set<GLuint> exp2;
1767                 exp2.insert(indicesU["NotSoSimpleBlockk.a[0]"]);
1768                 exp2.insert(indicesU["NotSoSimpleBlockk.b[0]"]);
1769                 exp2.insert(indicesU["NotSoSimpleBlockk.c"]);
1770                 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 1, &prop, bufSize, &length,
1771                                                            param);
1772                 for (int i = 0; i < length; ++i)
1773                 {
1774                         if (exp2.find(param[i]) == exp2.end())
1775                         {
1776                                 m_context.getTestContext().getLog()
1777                                         << tcu::TestLog::Message
1778                                         << "Unexpected index found in active variables of NotSoSimpleBlockk: " << param[i]
1779                                         << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1780                                         << tcu::TestLog::EndMessage;
1781                                 glDeleteProgram(program);
1782                                 return ERROR;
1783                         }
1784                         else if (length != 3)
1785                         {
1786                                 m_context.getTestContext().getLog()
1787                                         << tcu::TestLog::Message
1788                                         << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1789                                         << "\nExpected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1790                                 glDeleteProgram(program);
1791                                 return ERROR;
1792                         }
1793                 }
1794
1795                 GLint res;
1796                 glGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
1797                 if (res < 3)
1798                 {
1799                         m_context.getTestContext().getLog()
1800                                 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!"
1801                                 << tcu::TestLog::EndMessage;
1802                         glDeleteProgram(program);
1803                         return ERROR;
1804                 }
1805
1806                 glDeleteProgram(program);
1807                 return error;
1808         }
1809 };
1810
1811 class TransformFeedbackTypes : public SimpleShaders
1812 {
1813         virtual std::string Title()
1814         {
1815                 return "Transform Feedback Varying Types";
1816         }
1817
1818         virtual std::string ShadersDesc()
1819         {
1820                 return "fallthrough fragment and vertex shaders with different types of out variables used";
1821         }
1822
1823         virtual std::string PurposeExt()
1824         {
1825                 return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n";
1826         }
1827
1828         virtual std::string VertexShader()
1829         {
1830                 return "#version 430                         \n"
1831                            "in vec4 position;                    \n"
1832                            ""
1833                            "flat out ivec4 a;                    \n"
1834                            "out float b[2];                      \n"
1835                            "flat out uvec2 c;                    \n"
1836                            "flat out uint d;                     \n"
1837                            "out vec3 e[2];                       \n"
1838                            "flat out int f;                      \n"
1839                            ""
1840                            "void main(void)                      \n"
1841                            "{                                    \n"
1842                            "   vec4 pos;                         \n"
1843                            "   a = ivec4(1);                     \n"
1844                            "   b[0] = 1.1;                       \n"
1845                            "   b[1] = 1.1;                       \n"
1846                            "   c = uvec2(1u);                    \n"
1847                            "   d = 1u;                           \n"
1848                            "   e[0] = vec3(1.1);                 \n"
1849                            "   e[1] = vec3(1.1);                 \n"
1850                            "   f = 1;                            \n"
1851                            "   gl_Position = position;           \n"
1852                            "}";
1853         }
1854
1855         virtual long Run()
1856         {
1857                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1858                 glBindAttribLocation(program, 0, "position");
1859                 const char* varyings[6] = { "a", "b[0]", "b[1]", "c", "d", "e" };
1860                 glTransformFeedbackVaryings(program, 6, varyings, GL_INTERLEAVED_ATTRIBS);
1861                 LinkProgram(program);
1862
1863                 long error = NO_ERROR;
1864
1865                 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 6, error);
1866                 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 5, error);
1867
1868                 std::map<std::string, GLuint> indices;
1869                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error);
1870                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[0]", error);
1871                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[1]", error);
1872                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error);
1873                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error);
1874                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error);
1875
1876                 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error);
1877                 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], "b[0]", error);
1878                 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], "b[1]", error);
1879                 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error);
1880                 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error);
1881                 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error);
1882
1883                 GLenum props[]  = { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE };
1884                 GLint  expected[] = { 2, GL_INT_VEC4, 1 };
1885                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error);
1886                 GLint expected2[] = { 5, GL_FLOAT, 1 };
1887                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], 3, props, 3, expected2,
1888                                                                    error);
1889                 GLint expected3[] = { 5, GL_FLOAT, 1 };
1890                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], 3, props, 3, expected3,
1891                                                                    error);
1892                 GLint expected4[] = { 2, GL_UNSIGNED_INT_VEC2, 1 };
1893                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected4, error);
1894                 GLint expected5[] = { 2, GL_UNSIGNED_INT, 1 };
1895                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected5, error);
1896                 GLint expected6[] = { 2, GL_FLOAT_VEC3, 2 };
1897                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected6, error);
1898
1899                 glDeleteProgram(program);
1900                 return error;
1901         }
1902 };
1903
1904 class AtomicCounterSimple : public SimpleShaders
1905 {
1906 public:
1907         virtual std::string Title()
1908         {
1909                 return "Atomic Counter Buffer Simple Test";
1910         }
1911
1912         virtual std::string ShadersDesc()
1913         {
1914                 return "fallthrough fragment and vertex shaders with atomic counters used";
1915         }
1916
1917         virtual std::string PurposeExt()
1918         {
1919                 return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1920         }
1921
1922         virtual std::string FragmentShader()
1923         {
1924                 return "#version 430                   \n"
1925                            "out vec4 color;                \n"
1926                            ""
1927                            "layout (binding = 1, offset = 0) uniform atomic_uint a;    \n"
1928                            "layout (binding = 2, offset = 0) uniform atomic_uint b;    \n"
1929                            "layout (binding = 2, offset = 4) uniform atomic_uint c;    \n"
1930                            "layout (binding = 5, offset = 0) uniform atomic_uint d[3]; \n"
1931                            "layout (binding = 5, offset = 12) uniform atomic_uint e;   \n"
1932                            ""
1933                            "void main() {                                                         \n"
1934                            "   uint x = atomicCounterIncrement(d[0]) + atomicCounterIncrement(a); \n"
1935                            "   uint y = atomicCounterIncrement(d[1]) + atomicCounterIncrement(b); \n"
1936                            "   uint z = atomicCounterIncrement(d[2]) + atomicCounterIncrement(c); \n"
1937                            "   uint w = atomicCounterIncrement(e);                                \n"
1938                            "   color = vec4(float(x), float(y), float(z), float(w));              \n"
1939                            "}";
1940         }
1941
1942         virtual long Run()
1943         {
1944                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1945                 glBindAttribLocation(program, 0, "position");
1946                 glBindFragDataLocation(program, 0, "color");
1947                 LinkProgram(program);
1948
1949                 long error = NO_ERROR;
1950
1951                 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 3, error);
1952                 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 2, error);
1953
1954                 std::map<std::string, GLuint> indicesU;
1955                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1956                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1957                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1958                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "d", error);
1959                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "e", error);
1960
1961                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1962                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1963                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1964                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["d"], "d[0]", error);
1965                 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["e"], "e", error);
1966
1967                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1968                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1969                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1970                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", -1, error);
1971                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", -1, error);
1972                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[0]", -1, error);
1973                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[1]", -1, error);
1974                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[2]", -1, error);
1975
1976                 GLenum            prop  = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1977                 const GLsizei bufSize = 1000;
1978                 GLsizei           length;
1979                 GLint             res;
1980                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1981
1982                 GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES, GL_ACTIVE_VARIABLES };
1983                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1984                 GLint expected[] = { 1, 4, 1, static_cast<GLint>(indicesU["a"]) };
1985                 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 4, props, 4, expected, error);
1986
1987                 GLenum props2[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES };
1988                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1989                 GLint expected2[] = { 2, 8, 2 };
1990                 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1991                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["c"], 1, &prop, bufSize, &length, &res);
1992                 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1993
1994                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1995                 GLint expected3[] = { 5, 16, 2 };
1996                 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1997                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["e"], 1, &prop, bufSize, &length, &res);
1998                 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1999
2000                 GLenum                   prop2 = GL_ACTIVE_VARIABLES;
2001                 GLint                    param[bufSize];
2002                 std::set<GLuint> exp;
2003                 exp.insert(indicesU["b"]);
2004                 exp.insert(indicesU["c"]);
2005                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
2006                 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
2007                 for (int i = 0; i < length; ++i)
2008                 {
2009                         if (exp.find(param[i]) == exp.end() || length != 2)
2010                         {
2011                                 m_context.getTestContext().getLog()
2012                                         << tcu::TestLog::Message << "Length: " << length
2013                                         << "\nUnexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
2014                                         << tcu::TestLog::EndMessage;
2015                                 glDeleteProgram(program);
2016                                 return ERROR;
2017                         }
2018                 }
2019                 m_context.getTestContext().getLog()
2020                         << tcu::TestLog::Message << "GL_ACTIVE_VARIABLES ok for 1st ATOMIC_COUNTER_BUFFER"
2021                         << tcu::TestLog::EndMessage;
2022                 std::set<GLuint> exp2;
2023                 GLint                    param2[bufSize];
2024                 exp2.insert(indicesU["d"]);
2025                 exp2.insert(indicesU["e"]);
2026                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
2027                 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param2);
2028                 for (int i = 0; i < length; ++i)
2029                 {
2030                         if (exp2.find(param2[i]) == exp2.end() || length != 2)
2031                         {
2032                                 m_context.getTestContext().getLog()
2033                                         << tcu::TestLog::Message << "Length: " << length
2034                                         << "\nUnexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param2[i]
2035                                         << tcu::TestLog::EndMessage;
2036                                 glDeleteProgram(program);
2037                                 return ERROR;
2038                         }
2039                 }
2040
2041                 glDeleteProgram(program);
2042                 return error;
2043         }
2044 };
2045
2046 class SubroutinesBase : public SimpleShaders
2047 {
2048 protected:
2049         virtual std::string ShadersDesc()
2050         {
2051                 return "fallthrough vertex, geometry, tesselation and fragment shaders with subroutines used";
2052         }
2053
2054         virtual std::string VertexShader()
2055         {
2056                 return "#version 430                         \n"
2057                            "in vec4 position;                    \n"
2058                            ""
2059                            "subroutine vec4 a_t();               \n"
2060                            "subroutine uniform a_t a;            \n"
2061                            "subroutine(a_t) vec4 x() {           \n"
2062                            "   return vec4(1);                   \n"
2063                            "}                                    \n"
2064                            "subroutine(a_t) vec4 y() {           \n"
2065                            "   return vec4(0);                   \n"
2066                            "}                                    \n"
2067                            "void main(void)                      \n"
2068                            "{                                    \n"
2069                            "   gl_Position = a();                \n"
2070                            "}";
2071         }
2072
2073         virtual std::string TessControlShader()
2074         {
2075                 return "#version 430                                                  \n"
2076                            "layout(vertices = 3) out;                                     \n"
2077                            ""
2078                            "subroutine vec4 a_t();               \n"
2079                            "subroutine uniform a_t a;            \n"
2080                            "subroutine(a_t) vec4 x() {           \n"
2081                            "   return vec4(1);                   \n"
2082                            "}                                    \n"
2083                            ""
2084                            "void main() {                                                                   \n"
2085                            "   gl_out[gl_InvocationID].gl_Position = a();                                   \n"
2086                            "   gl_TessLevelInner[0] = 1.0;                                                  \n"
2087                            "   gl_TessLevelInner[1] = 1.0;                                                  \n"
2088                            "   gl_TessLevelOuter[0] = 1.0;                                                  \n"
2089                            "   gl_TessLevelOuter[1] = 1.0;                                                  \n"
2090                            "   gl_TessLevelOuter[2] = 1.0;                                                  \n"
2091                            "}";
2092         };
2093
2094         virtual std::string TessEvalShader()
2095         {
2096                 return "#version 430                                                  \n"
2097                            "layout(triangles, equal_spacing) in;                          \n"
2098                            ""
2099                            "subroutine vec4 a_t();               \n"
2100                            "subroutine uniform a_t a;            \n"
2101                            "subroutine(a_t) vec4 x() {           \n"
2102                            "   return vec4(1);                   \n"
2103                            "}                                    \n"
2104                            ""
2105                            "void main() {                                \n"
2106                            "   vec4 p0 = gl_in[0].gl_Position;           \n"
2107                            "   vec4 p1 = gl_in[1].gl_Position;           \n"
2108                            "   vec4 p2 = gl_in[2].gl_Position;           \n"
2109                            "   vec3 p = gl_TessCoord.xyz;                \n"
2110                            "   gl_Position = a();                        \n"
2111                            "}";
2112         }
2113
2114         virtual std::string GeometryShader()
2115         {
2116                 return "#version 430                                                  \n"
2117                            "layout(triangles) in;                                         \n"
2118                            "layout(triangle_strip, max_vertices = 4) out;                 \n"
2119                            ""
2120                            "subroutine vec4 a_t();               \n"
2121                            "subroutine uniform a_t a;            \n"
2122                            "subroutine(a_t) vec4 x() {           \n"
2123                            "   return vec4(1);                   \n"
2124                            "}                                    \n"
2125                            ""
2126                            "void main() {                              \n"
2127                            "   gl_Position = vec4(-1, 1, 0, 1);        \n"
2128                            "   EmitVertex();                           \n"
2129                            "   gl_Position = vec4(-1, -1, 0, 1);       \n"
2130                            "   EmitVertex();                           \n"
2131                            "   gl_Position = vec4(1, 1, 0, 1);         \n"
2132                            "   EmitVertex();                           \n"
2133                            "   gl_Position = a();                      \n"
2134                            "   EmitVertex();                           \n"
2135                            "   EndPrimitive();                         \n"
2136                            "}";
2137         }
2138
2139         virtual std::string FragmentShader()
2140         {
2141                 return "#version 430                   \n"
2142                            "out vec4 color;                \n"
2143                            ""
2144                            "subroutine vec4 a_t();               \n"
2145                            "subroutine uniform a_t a;            \n"
2146                            "subroutine(a_t) vec4 x() {           \n"
2147                            "   return vec4(1);                   \n"
2148                            "}                                    \n"
2149                            ""
2150                            "void main() {                             \n"
2151                            "   color = a();                           \n"
2152                            "}";
2153         }
2154
2155         virtual void inline VerifyVS(GLuint program, long& error)
2156         {
2157                 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE, GL_ACTIVE_RESOURCES, 2, error);
2158                 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2159
2160                 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2161                 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2162                 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 2, error);
2163
2164                 std::map<std::string, GLuint> indicesS;
2165                 VerifyGetProgramResourceIndex(program, GL_VERTEX_SUBROUTINE, indicesS, "x", error);
2166                 VerifyGetProgramResourceIndex(program, GL_VERTEX_SUBROUTINE, indicesS, "y", error);
2167                 std::map<std::string, GLuint> indicesU;
2168                 VerifyGetProgramResourceIndex(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU, "a", error);
2169
2170                 VerifyGetProgramResourceName(program, GL_VERTEX_SUBROUTINE, indicesS["x"], "x", error);
2171                 VerifyGetProgramResourceName(program, GL_VERTEX_SUBROUTINE, indicesS["y"], "y", error);
2172                 VerifyGetProgramResourceName(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU["a"], "a", error);
2173
2174                 VerifyGetProgramResourceLocation(program, GL_VERTEX_SUBROUTINE_UNIFORM, "a",
2175                                                                                  glGetSubroutineUniformLocation(program, GL_VERTEX_SHADER, "a"), error);
2176
2177                 GLenum propsS[] = { GL_NAME_LENGTH };
2178                 GLint  expectedS[] = { 2 };
2179                 VerifyGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE, indicesS["x"], 1, propsS, 1, expectedS, error);
2180                 VerifyGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE, indicesS["y"], 1, propsS, 1, expectedS, error);
2181
2182                 GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION };
2183                 GLint  expectedU[] = { 2, 1, 2, glGetSubroutineUniformLocation(program, GL_VERTEX_SHADER, "a") };
2184                 VerifyGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU["a"], 4, propsU, 4, expectedU,
2185                                                                    error);
2186
2187                 GLenum                   prop   = GL_COMPATIBLE_SUBROUTINES;
2188                 const GLsizei   bufSize = 1000;
2189                 GLint                    param[bufSize];
2190                 GLsizei                  length;
2191                 std::set<GLuint> exp;
2192                 exp.insert(indicesS["x"]);
2193                 exp.insert(indicesS["y"]);
2194                 glGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, param);
2195                 for (int i = 0; i < length; ++i)
2196                 {
2197                         if (exp.find(param[i]) == exp.end() || length != 2)
2198                         {
2199                                 m_context.getTestContext().getLog()
2200                                         << tcu::TestLog::Message << "Length: " << length
2201                                         << "\nUnexpected index/length found in active variables of GL_VERTEX_SUBROUTINE_UNIFORM: "
2202                                         << param[i] << tcu::TestLog::EndMessage;
2203                                 error = ERROR;
2204                         }
2205                 }
2206         }
2207
2208         virtual void inline VerifyTCS(GLuint program, long& error)
2209         {
2210                 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2211                 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2212
2213                 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2214                 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2215                 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 1,
2216                                                                         error);
2217
2218                 std::map<std::string, GLuint> indicesTS;
2219                 VerifyGetProgramResourceIndex(program, GL_TESS_CONTROL_SUBROUTINE, indicesTS, "x", error);
2220                 std::map<std::string, GLuint> indicesTU;
2221                 VerifyGetProgramResourceIndex(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2222
2223                 VerifyGetProgramResourceName(program, GL_TESS_CONTROL_SUBROUTINE, indicesTS["x"], "x", error);
2224                 VerifyGetProgramResourceName(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2225
2226                 VerifyGetProgramResourceLocation(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, "a",
2227                                                                                  glGetSubroutineUniformLocation(program, GL_TESS_CONTROL_SHADER, "a"), error);
2228
2229                 GLenum propsS[] = { GL_NAME_LENGTH };
2230                 GLint  expectedS[] = { 2 };
2231                 VerifyGetProgramResourceiv(program, GL_TESS_CONTROL_SUBROUTINE, static_cast<GLint>(indicesTS["x"]), 1, propsS,
2232                                                                    1, expectedS, error);
2233
2234                 GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2235                                                         GL_COMPATIBLE_SUBROUTINES };
2236                 GLint expectedU[] = { 2, 1, 1, glGetSubroutineUniformLocation(program, GL_TESS_CONTROL_SHADER, "a"),
2237                                                           static_cast<GLint>(indicesTS["x"]) };
2238                 VerifyGetProgramResourceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5, expectedU,
2239                                                                    error);
2240         }
2241 };
2242
2243 class SubroutinesVertex : public SubroutinesBase
2244 {
2245         virtual std::string Title()
2246         {
2247                 return "Vertex Shader Subroutines Test";
2248         }
2249
2250         virtual std::string PurposeExt()
2251         {
2252                 return "\n\n Purpose is to verify calls using *VERTEX_SUBROUTINE* as an interface params.\n";
2253         }
2254
2255         virtual long Run()
2256         {
2257                 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2258                                                                            GeometryShader().c_str(), FragmentShader().c_str(), false);
2259                 glBindAttribLocation(program, 0, "position");
2260                 glBindFragDataLocation(program, 0, "color");
2261                 LinkProgram(program);
2262                 long error = NO_ERROR;
2263
2264                 VerifyVS(program, error);
2265
2266                 glDeleteProgram(program);
2267                 return error;
2268         }
2269 };
2270
2271 class SubroutinesTessControl : public SubroutinesBase
2272 {
2273         virtual std::string Title()
2274         {
2275                 return "Tess Control Subroutines Test";
2276         }
2277
2278         virtual std::string PurposeExt()
2279         {
2280                 return "\n\n Purpose is to verify calls using *TESS_CONTROL_SUBROUTINE* as an interface params.\n";
2281         }
2282
2283         virtual long Run()
2284         {
2285                 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2286                                                                            GeometryShader().c_str(), FragmentShader().c_str(), false);
2287                 glBindAttribLocation(program, 0, "position");
2288                 glBindFragDataLocation(program, 0, "color");
2289                 LinkProgram(program);
2290                 long error = NO_ERROR;
2291
2292                 VerifyTCS(program, error);
2293
2294                 glDeleteProgram(program);
2295                 return error;
2296         }
2297 };
2298
2299 class SubroutinesTessEval : public SubroutinesBase
2300 {
2301         virtual std::string Title()
2302         {
2303                 return "Tess Evaluation Subroutines Test";
2304         }
2305
2306         virtual std::string PurposeExt()
2307         {
2308                 return "\n\n Purpose is to verify calls using *TESS_EVALUATION_SUBROUTINE* as an interface params.\n";
2309         }
2310
2311         virtual void inline VerifyTES(GLuint program, long& error)
2312         {
2313                 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2314                 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2315
2316                 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2317                 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2318                 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES,
2319                                                                         1, error);
2320
2321                 std::map<std::string, GLuint> indicesTS;
2322                 VerifyGetProgramResourceIndex(program, GL_TESS_EVALUATION_SUBROUTINE, indicesTS, "x", error);
2323                 std::map<std::string, GLuint> indicesTU;
2324                 VerifyGetProgramResourceIndex(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2325
2326                 VerifyGetProgramResourceName(program, GL_TESS_EVALUATION_SUBROUTINE, indicesTS["x"], "x", error);
2327                 VerifyGetProgramResourceName(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2328
2329                 VerifyGetProgramResourceLocation(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, "a",
2330                                                                                  glGetSubroutineUniformLocation(program, GL_TESS_EVALUATION_SHADER, "a"),
2331                                                                                  error);
2332
2333                 GLenum propsS[] = { GL_NAME_LENGTH };
2334                 GLint  expectedS[] = { 2 };
2335                 VerifyGetProgramResourceiv(program, GL_TESS_EVALUATION_SUBROUTINE, indicesTS["x"], 1, propsS, 1, expectedS,
2336                                                                    error);
2337
2338                 GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2339                                                         GL_COMPATIBLE_SUBROUTINES };
2340                 GLint expectedU[] = { 2, 1, 1, glGetSubroutineUniformLocation(program, GL_TESS_EVALUATION_SHADER, "a"),
2341                                                           static_cast<GLint>(indicesTS["x"]) };
2342                 VerifyGetProgramResourceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5,
2343                                                                    expectedU, error);
2344         }
2345
2346         virtual long Run()
2347         {
2348                 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2349                                                                            GeometryShader().c_str(), FragmentShader().c_str(), false);
2350                 glBindAttribLocation(program, 0, "position");
2351                 glBindFragDataLocation(program, 0, "color");
2352                 LinkProgram(program);
2353                 long error = NO_ERROR;
2354
2355                 VerifyTES(program, error);
2356
2357                 glDeleteProgram(program);
2358                 return error;
2359         }
2360 };
2361
2362 class SubroutinesGeometry : public SubroutinesBase
2363 {
2364         virtual std::string Title()
2365         {
2366                 return "Geometry Shader Subroutines Test";
2367         }
2368
2369         virtual std::string PurposeExt()
2370         {
2371                 return "\n\n Purpose is to verify calls using *GEOMETRY_SUBROUTINE* as an interface params.\n";
2372         }
2373
2374         virtual void inline VerifyGEO(GLuint program, long& error)
2375         {
2376                 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2377                 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2378
2379                 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2380                 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2381                 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 1,
2382                                                                         error);
2383
2384                 std::map<std::string, GLuint> indicesTS;
2385                 VerifyGetProgramResourceIndex(program, GL_GEOMETRY_SUBROUTINE, indicesTS, "x", error);
2386                 std::map<std::string, GLuint> indicesTU;
2387                 VerifyGetProgramResourceIndex(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2388
2389                 VerifyGetProgramResourceName(program, GL_GEOMETRY_SUBROUTINE, indicesTS["x"], "x", error);
2390                 VerifyGetProgramResourceName(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2391
2392                 VerifyGetProgramResourceLocation(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, "a",
2393                                                                                  glGetSubroutineUniformLocation(program, GL_GEOMETRY_SHADER, "a"), error);
2394
2395                 GLenum propsS[] = { GL_NAME_LENGTH };
2396                 GLint  expectedS[] = { 2 };
2397                 VerifyGetProgramResourceiv(program, GL_GEOMETRY_SUBROUTINE, indicesTS["x"], 1, propsS, 1, expectedS, error);
2398
2399                 GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2400                                                         GL_COMPATIBLE_SUBROUTINES };
2401                 GLint expectedU[] = { 2, 1, 1, glGetSubroutineUniformLocation(program, GL_GEOMETRY_SHADER, "a"),
2402                                                           static_cast<GLint>(indicesTS["x"]) };
2403                 VerifyGetProgramResourceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5, expectedU,
2404                                                                    error);
2405         }
2406
2407         virtual long Run()
2408         {
2409                 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2410                                                                            GeometryShader().c_str(), FragmentShader().c_str(), false);
2411                 glBindAttribLocation(program, 0, "position");
2412                 glBindFragDataLocation(program, 0, "color");
2413                 LinkProgram(program);
2414                 long error = NO_ERROR;
2415
2416                 VerifyGEO(program, error);
2417
2418                 glDeleteProgram(program);
2419                 return error;
2420         }
2421 };
2422
2423 class SubroutinesFragment : public SubroutinesBase
2424 {
2425         virtual std::string Title()
2426         {
2427                 return "Fragment Shader Subroutines Test";
2428         }
2429
2430         virtual std::string PurposeExt()
2431         {
2432                 return "\n\n Purpose is to verify calls using *FRAGMENT_SUBROUTINE* as an interface params.\n";
2433         }
2434
2435         virtual void inline VerifyFS(GLuint program, long& error)
2436         {
2437                 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2438                 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2439
2440                 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2441                 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2442                 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 1,
2443                                                                         error);
2444
2445                 std::map<std::string, GLuint> indicesTS;
2446                 VerifyGetProgramResourceIndex(program, GL_FRAGMENT_SUBROUTINE, indicesTS, "x", error);
2447                 std::map<std::string, GLuint> indicesTU;
2448                 VerifyGetProgramResourceIndex(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2449
2450                 VerifyGetProgramResourceName(program, GL_FRAGMENT_SUBROUTINE, indicesTS["x"], "x", error);
2451                 VerifyGetProgramResourceName(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2452
2453                 VerifyGetProgramResourceLocation(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, "a",
2454                                                                                  glGetSubroutineUniformLocation(program, GL_FRAGMENT_SHADER, "a"), error);
2455
2456                 GLenum propsS[] = { GL_NAME_LENGTH };
2457                 GLint  expectedS[] = { 2 };
2458                 VerifyGetProgramResourceiv(program, GL_FRAGMENT_SUBROUTINE, indicesTS["x"], 1, propsS, 1, expectedS, error);
2459
2460                 GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2461                                                         GL_COMPATIBLE_SUBROUTINES };
2462                 GLint expectedU[] = { 2, 1, 1, glGetSubroutineUniformLocation(program, GL_FRAGMENT_SHADER, "a"),
2463                                                           static_cast<GLint>(indicesTS["x"]) };
2464                 VerifyGetProgramResourceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5, expectedU,
2465                                                                    error);
2466         }
2467
2468         virtual long Run()
2469         {
2470                 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2471                                                                            GeometryShader().c_str(), FragmentShader().c_str(), false);
2472                 glBindAttribLocation(program, 0, "position");
2473                 glBindFragDataLocation(program, 0, "color");
2474                 LinkProgram(program);
2475                 long error = NO_ERROR;
2476
2477                 VerifyFS(program, error);
2478
2479                 glDeleteProgram(program);
2480                 return error;
2481         }
2482 };
2483
2484 class SoubroutinesCompute : public PIQBase
2485 {
2486         virtual std::string Title()
2487         {
2488                 return "Compute Shader Subroutines Test";
2489         }
2490
2491         virtual std::string ShadersDesc()
2492         {
2493                 return "compute shader with subroutines used";
2494         }
2495
2496         virtual std::string PurposeExt()
2497         {
2498                 return "\n\n Purpose is to verify calls using *COMPUTE_SUBROUTINE* as an interface params.\n";
2499         }
2500
2501         virtual std::string ComputeShader()
2502         {
2503                 return "layout(local_size_x = 1, local_size_y = 1) in; \n"
2504
2505                            "layout(std430) buffer Output {                 \n"
2506                            "  vec4 data;                                   \n"
2507                            "} g_out;                                       \n"
2508                            ""
2509                            "subroutine vec4 a_t();               \n"
2510                            "subroutine uniform a_t a;            \n"
2511                            "subroutine(a_t) vec4 ax() {          \n"
2512                            "   return vec4(1);                   \n"
2513                            "}                                    \n"
2514                            "subroutine(a_t) vec4 ay() {          \n"
2515                            "   return vec4(0);                   \n"
2516                            "}                                    \n"
2517                            ""
2518                            "subroutine vec4 b_t();               \n"
2519                            "subroutine uniform b_t b[3];         \n"
2520                            "subroutine(b_t) vec4 bx() {          \n"
2521                            "   return vec4(1);                   \n"
2522                            "}                                    \n"
2523                            "subroutine(b_t) vec4 by() {          \n"
2524                            "   return vec4(0);                   \n"
2525                            "}                                    \n"
2526                            "subroutine(b_t) vec4 bz() {          \n"
2527                            "   return vec4(-1);                   \n"
2528                            "}                                    \n"
2529                            ""
2530                            "void main() {                                    \n"
2531                            "   g_out.data = a() + b[0]() + b[1]() + b[2]();  \n"
2532                            "}";
2533         }
2534
2535         GLuint CreateComputeProgram(const std::string& cs)
2536         {
2537                 const GLuint p = glCreateProgram();
2538
2539                 const char* const kGLSLVer = "#version 430 core\n";
2540
2541                 if (!cs.empty())
2542                 {
2543                         const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
2544                         glAttachShader(p, sh);
2545                         glDeleteShader(sh);
2546                         const char* const src[2] = { kGLSLVer, cs.c_str() };
2547                         glShaderSource(sh, 2, src, NULL);
2548                         glCompileShader(sh);
2549                 }
2550
2551                 return p;
2552         }
2553
2554         bool CheckProgram(GLuint program, bool* compile_error = NULL)
2555         {
2556                 GLint compile_status = GL_TRUE;
2557                 GLint status;
2558                 glGetProgramiv(program, GL_LINK_STATUS, &status);
2559
2560                 if (status == GL_FALSE)
2561                 {
2562                         GLint attached_shaders;
2563                         glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
2564
2565                         if (attached_shaders > 0)
2566                         {
2567                                 std::vector<GLuint> shaders(attached_shaders);
2568                                 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
2569
2570                                 for (GLint i = 0; i < attached_shaders; ++i)
2571                                 {
2572                                         GLenum type;
2573                                         glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
2574                                         switch (type)
2575                                         {
2576                                         case GL_VERTEX_SHADER:
2577                                                 m_context.getTestContext().getLog()
2578                                                         << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
2579                                                 break;
2580                                         case GL_TESS_CONTROL_SHADER:
2581                                                 m_context.getTestContext().getLog()
2582                                                         << tcu::TestLog::Message << "*** Tessellation Control Shader ***"
2583                                                         << tcu::TestLog::EndMessage;
2584                                                 break;
2585                                         case GL_TESS_EVALUATION_SHADER:
2586                                                 m_context.getTestContext().getLog()
2587                                                         << tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
2588                                                         << tcu::TestLog::EndMessage;
2589                                                 break;
2590                                         case GL_GEOMETRY_SHADER:
2591                                                 m_context.getTestContext().getLog()
2592                                                         << tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
2593                                                 break;
2594                                         case GL_FRAGMENT_SHADER:
2595                                                 m_context.getTestContext().getLog()
2596                                                         << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
2597                                                 break;
2598                                         case GL_COMPUTE_SHADER:
2599                                                 m_context.getTestContext().getLog()
2600                                                         << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
2601                                                 break;
2602                                         default:
2603                                                 m_context.getTestContext().getLog()
2604                                                         << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
2605                                         }
2606
2607                                         GLint res;
2608                                         glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
2609                                         if (res != GL_TRUE)
2610                                                 compile_status = res;
2611
2612                                         // shader source
2613                                         GLint length;
2614                                         glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
2615                                         if (length > 0)
2616                                         {
2617                                                 std::vector<GLchar> source(length);
2618                                                 glGetShaderSource(shaders[i], length, NULL, &source[0]);
2619                                                 m_context.getTestContext().getLog()
2620                                                         << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
2621                                         }
2622
2623                                         // shader info log
2624                                         glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
2625                                         if (length > 0)
2626                                         {
2627                                                 std::vector<GLchar> log(length);
2628                                                 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
2629                                                 m_context.getTestContext().getLog()
2630                                                         << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
2631                                         }
2632                                 }
2633                         }
2634
2635                         // program info log
2636                         GLint length;
2637                         glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
2638                         if (length > 0)
2639                         {
2640                                 std::vector<GLchar> log(length);
2641                                 glGetProgramInfoLog(program, length, NULL, &log[0]);
2642                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
2643                         }
2644                 }
2645
2646                 if (compile_error)
2647                         *compile_error = (compile_status == GL_TRUE ? false : true);
2648                 if (compile_status != GL_TRUE)
2649                         return false;
2650                 return status == GL_TRUE ? true : false;
2651         }
2652
2653         virtual void inline VerifyCompute(GLuint program, long& error)
2654         {
2655                 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE, GL_ACTIVE_RESOURCES, 5, error);
2656                 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE, GL_MAX_NAME_LENGTH, 3, error);
2657
2658                 GLint res;
2659                 glGetProgramStageiv(program, GL_COMPUTE_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &res);
2660                 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, res, error);
2661                 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 5, error);
2662                 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 3,
2663                                                                         error);
2664
2665                 std::map<std::string, GLuint> indicesTS;
2666                 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "ax", error);
2667                 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "ay", error);
2668                 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "bx", error);
2669                 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "by", error);
2670                 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "bz", error);
2671                 std::map<std::string, GLuint> indicesTU;
2672                 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2673                 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU, "b[0]", error);
2674
2675                 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["ax"], "ax", error);
2676                 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["ay"], "ay", error);
2677                 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["bx"], "bx", error);
2678                 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["by"], "by", error);
2679                 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["bz"], "bz", error);
2680                 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2681                 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["b[0]"], "b[0]", error);
2682
2683                 VerifyGetProgramResourceLocation(program, GL_COMPUTE_SUBROUTINE_UNIFORM, "a",
2684                                                                                  glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "a"), error);
2685                 VerifyGetProgramResourceLocation(program, GL_COMPUTE_SUBROUTINE_UNIFORM, "b",
2686                                                                                  glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "b"), error);
2687
2688                 GLenum propsS[] = { GL_NAME_LENGTH };
2689                 GLint  expectedS[] = { 3 };
2690                 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["ax"], 1, propsS, 1, expectedS, error);
2691                 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["ay"], 1, propsS, 1, expectedS, error);
2692                 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["bx"], 1, propsS, 1, expectedS, error);
2693                 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["by"], 1, propsS, 1, expectedS, error);
2694                 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["bz"], 1, propsS, 1, expectedS, error);
2695
2696                 GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION };
2697                 GLint  expectedU[] = { 2, 1, 2, glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "a") };
2698                 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["a"], 4, propsU, 4, expectedU,
2699                                                                    error);
2700                 GLint expectedU2[] = { 5, 3, 3, glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "b") };
2701                 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["b[0]"], 4, propsU, 4, expectedU2,
2702                                                                    error);
2703         }
2704
2705         virtual long Run()
2706         {
2707                 GLuint program = CreateComputeProgram(ComputeShader());
2708                 glLinkProgram(program);
2709                 if (!CheckProgram(program))
2710                 {
2711                         glDeleteProgram(program);
2712                         return ERROR;
2713                 }
2714                 glUseProgram(program);
2715
2716                 long error = NO_ERROR;
2717
2718                 VerifyCompute(program, error);
2719
2720                 glDeleteProgram(program);
2721                 return error;
2722         }
2723 };
2724
2725 class InvalidValueTest : public SimpleShaders
2726 {
2727         virtual std::string Title()
2728         {
2729                 return "Invalid Value Test";
2730         }
2731
2732         virtual std::string PassCriteria()
2733         {
2734                 return "GL_INVALID_VALUE error is generated after every function call.";
2735         }
2736
2737         virtual std::string Purpose()
2738         {
2739                 return "Verify that wrong use of functions generates GL_INVALID_VALUE as described in spec.";
2740         }
2741
2742         virtual std::string Method()
2743         {
2744                 return "Call functions with invalid values and check if GL_INVALID_VALUE was generated.";
2745         }
2746
2747         virtual long Run()
2748         {
2749                 long error = NO_ERROR;
2750
2751                 GLint   res;
2752                 GLsizei len;
2753                 GLchar  name[100] = { '\0' };
2754                 GLenum  props[1]  = { GL_NAME_LENGTH };
2755
2756                 m_context.getTestContext().getLog()
2757                         << tcu::TestLog::Message << "Case 1: <program> not a name of shader/program object"
2758                         << tcu::TestLog::EndMessage;
2759                 glGetProgramInterfaceiv(1337u, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2760                 ExpectError(GL_INVALID_VALUE, error);
2761                 glGetProgramResourceIndex(31337u, GL_PROGRAM_INPUT, "pie");
2762                 ExpectError(GL_INVALID_VALUE, error);
2763                 glGetProgramResourceName(1337u, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2764                 ExpectError(GL_INVALID_VALUE, error);
2765                 glGetProgramResourceiv(1337u, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2766                 ExpectError(GL_INVALID_VALUE, error);
2767                 glGetProgramResourceLocation(1337u, GL_PROGRAM_INPUT, "pie");
2768                 ExpectError(GL_INVALID_VALUE, error);
2769                 glGetProgramResourceLocationIndex(1337u, GL_PROGRAM_OUTPUT, "pie");
2770                 ExpectError(GL_INVALID_VALUE, error);
2771                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2772
2773                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2774                 glBindAttribLocation(program, 0, "position");
2775                 glBindFragDataLocation(program, 0, "color");
2776                 LinkProgram(program);
2777
2778                 m_context.getTestContext().getLog()
2779                         << tcu::TestLog::Message
2780                         << "Case 2: <index> is greater than the number of the active resources in GetProgramResourceName"
2781                         << tcu::TestLog::EndMessage;
2782                 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 3000, 1024, &len, name);
2783                 ExpectError(GL_INVALID_VALUE, error);
2784                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2785
2786                 m_context.getTestContext().getLog()
2787                         << tcu::TestLog::Message << "Case 3: <propCount> is zero in GetProgramResourceiv"
2788                         << tcu::TestLog::EndMessage;
2789                 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 0, props, 1024, &len, &res);
2790                 ExpectError(GL_INVALID_VALUE, error);
2791                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3 finished" << tcu::TestLog::EndMessage;
2792
2793                 std::string str = "position";
2794                 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, -100, NULL, const_cast<char*>(str.c_str()));
2795                 ExpectError(GL_INVALID_VALUE, error);
2796                 GLenum prop = GL_NAME_LENGTH;
2797                 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, &prop, -100, &len, &res);
2798                 ExpectError(GL_INVALID_VALUE, error);
2799
2800                 glDeleteProgram(program);
2801                 return error;
2802         }
2803 };
2804
2805 class InvalidEnumTest : public AtomicCounterSimple
2806 {
2807         virtual std::string Title()
2808         {
2809                 return "Invalid Enum Test";
2810         }
2811
2812         virtual std::string PassCriteria()
2813         {
2814                 return "GL_INVALID_ENUM error is generated after every function call.";
2815         }
2816
2817         virtual std::string Purpose()
2818         {
2819                 return "Verify that wrong use of functions generates GL_INVALID_ENUM as described in spec.";
2820         }
2821
2822         virtual std::string Method()
2823         {
2824                 return "Call functions with invalid enums and check if GL_INVALID_ENUM was generated.";
2825         }
2826
2827         virtual long Run()
2828         {
2829                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2830                 glBindAttribLocation(program, 0, "position");
2831                 glBindFragDataLocation(program, 0, "color");
2832                 LinkProgram(program);
2833
2834                 long error = NO_ERROR;
2835
2836                 GLint   res;
2837                 GLsizei len;
2838                 GLchar  name[100] = { '\0' };
2839                 GLenum  props[1]  = { GL_TEXTURE_1D };
2840
2841                 m_context.getTestContext().getLog()
2842                         << tcu::TestLog::Message << "Case 1: <programInterface> is ATOMIC_COUNTER_BUFFER "
2843                         << "in GetProgramResourceIndex or GetProgramResourceName" << tcu::TestLog::EndMessage;
2844                 glGetProgramResourceIndex(program, GL_ATOMIC_COUNTER_BUFFER, name);
2845                 ExpectError(GL_INVALID_ENUM, error);
2846                 glGetProgramResourceName(program, GL_ATOMIC_COUNTER_BUFFER, 0, 1024, &len, name);
2847                 ExpectError(GL_INVALID_ENUM, error);
2848                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2849
2850                 m_context.getTestContext().getLog()
2851                         << tcu::TestLog::Message << "Case 2: <props> is not a property name supported by "
2852                         << "the command GetProgramResourceiv" << tcu::TestLog::EndMessage;
2853                 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2854                 ExpectError(GL_INVALID_ENUM, error);
2855                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2856
2857                 glGetProgramResourceLocation(program, GL_ATOMIC_COUNTER_BUFFER, "position");
2858                 ExpectError(GL_INVALID_ENUM, error);
2859
2860                 glDeleteProgram(program);
2861                 return error;
2862         }
2863 };
2864
2865 class InvalidOperationTest : public SimpleShaders
2866 {
2867         virtual std::string Title()
2868         {
2869                 return "Invalid Operation Test";
2870         }
2871
2872         virtual std::string PassCriteria()
2873         {
2874                 return "GL_INVALID_OPERATION error is generated after every function call.";
2875         }
2876
2877         virtual std::string Purpose()
2878         {
2879                 return "Verify that wrong use of functions generates GL_INVALID_OPERATION as described in spec.";
2880         }
2881
2882         virtual std::string Method()
2883         {
2884                 return "Perform invalid operation and check if GL_INVALID_OPERATION was generated.";
2885         }
2886
2887         virtual long Run()
2888         {
2889                 long error = NO_ERROR;
2890
2891                 GLuint program  = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2892                 GLuint program2 = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2893                 glBindAttribLocation(program, 0, "position");
2894                 glBindFragDataLocation(program, 0, "color");
2895                 LinkProgram(program);
2896
2897                 const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
2898                 GLint            res;
2899                 GLsizei          len;
2900                 GLchar           name[100] = { '\0' };
2901                 GLenum           props[1]  = { GL_OFFSET };
2902
2903                 m_context.getTestContext().getLog()
2904                         << tcu::TestLog::Message << "Case 1: <program> is the name of a shader object" << tcu::TestLog::EndMessage;
2905                 glGetProgramInterfaceiv(sh, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2906                 ExpectError(GL_INVALID_OPERATION, error);
2907                 glGetProgramResourceIndex(sh, GL_PROGRAM_INPUT, "pie");
2908                 ExpectError(GL_INVALID_OPERATION, error);
2909                 glGetProgramResourceName(sh, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2910                 ExpectError(GL_INVALID_OPERATION, error);
2911                 glGetProgramResourceiv(sh, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2912                 ExpectError(GL_INVALID_OPERATION, error);
2913                 glGetProgramResourceLocation(sh, GL_PROGRAM_INPUT, "pie");
2914                 ExpectError(GL_INVALID_OPERATION, error);
2915                 glGetProgramResourceLocationIndex(sh, GL_PROGRAM_OUTPUT, "pie");
2916                 ExpectError(GL_INVALID_OPERATION, error);
2917                 glDeleteShader(sh);
2918                 m_context.getTestContext().getLog()
2919                         << tcu::TestLog::Message << "Case 1 finished\n"
2920                         << "Case 2: <pname> is not supported in GetProgramInterfacei" << tcu::TestLog::EndMessage;
2921
2922                 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2923                 ExpectError(GL_INVALID_OPERATION, error);
2924                 m_context.getTestContext().getLog()
2925                         << tcu::TestLog::Message << "Case 2 finished\n"
2926                         << "Case 3: <props> is not supported in GetProgramResourceiv" << tcu::TestLog::EndMessage;
2927
2928                 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2929                 ExpectError(GL_INVALID_OPERATION, error);
2930                 m_context.getTestContext().getLog()
2931                         << tcu::TestLog::Message << "Case 3 finished\n"
2932                         << "Case 4: <program> has not been linked in GetProgramResourceLocation/GetProgramResourceLocationIndex"
2933                         << tcu::TestLog::EndMessage;
2934
2935                 glGetProgramResourceLocation(program2, GL_PROGRAM_INPUT, "pie");
2936                 ExpectError(GL_INVALID_OPERATION, error);
2937                 glGetProgramResourceLocationIndex(program2, GL_PROGRAM_OUTPUT, "pie");
2938                 ExpectError(GL_INVALID_OPERATION, error);
2939                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 4 finished\n" << tcu::TestLog::EndMessage;
2940
2941                 glDeleteProgram(program);
2942                 glDeleteProgram(program2);
2943                 return error;
2944         }
2945 };
2946
2947 class ShaderStorageBlock : public SimpleShaders
2948 {
2949         virtual std::string Title()
2950         {
2951                 return "Shader Storage Block Test";
2952         }
2953
2954         virtual std::string ShadersDesc()
2955         {
2956                 return "fallthrough fragment and vertex shaders with different types of storage blocks used";
2957         }
2958
2959         virtual std::string PurposeExt()
2960         {
2961                 return "\n\n Purpose is to verify calls using GL_BUFFER_VARIABLE and GL_SHADER_STORAGE_BLOCK as an interface "
2962                            "params.\n";
2963         }
2964
2965         virtual std::string FragmentShader()
2966         {
2967                 return "#version 430                   \n"
2968                            ""
2969                            "struct U {                     \n"
2970                            "   bool a[3];                  \n"
2971                            "   mediump vec4 b;             \n"
2972                            "   mediump mat3 c;             \n"
2973                            "   mediump float d[2];         \n"
2974                            "};                             \n"
2975                            ""
2976                            "struct UU {                    \n"
2977                            "   U a;                        \n"
2978                            "   U b[2];                     \n"
2979                            "   uvec2 c;                    \n"
2980                            "};                             \n"
2981                            ""
2982                            "layout(binding=4) buffer TrickyBuffer {          \n"
2983                            "   UU a[3];                                      \n"
2984                            "   mediump mat4 b;                               \n"
2985                            "   uint c;                                       \n"
2986                            "} e[2];                                          \n"
2987                            ""
2988                            "layout(binding = 0) buffer SimpleBuffer {        \n"
2989                            "   mediump mat3x2 a;                             \n"
2990                            "   mediump mat4 b;                               \n"
2991                            "   mediump vec4 c;                               \n"
2992                            "};                                               \n"
2993                            ""
2994                            "layout(binding = 1) buffer NotSoSimpleBuffer {   \n"
2995                            "   ivec2 a[4];                                   \n"
2996                            "   mediump mat3 b[2];                            \n"
2997                            "   mediump mat2 c;                               \n"
2998                            "} d;                                             \n"
2999                            ""
3000                            "out mediump vec4 color;                          \n"
3001                            ""
3002                            "void main() {                                    \n"
3003                            "    mediump float tmp;                           \n"
3004                            "    mediump float tmp2;                          \n"
3005                            "    tmp = e[0].a[0].b[0].d[0] * float(e[1].c);   \n"
3006                            "    tmp2 = a[0][0] * b[0][0] * c.x;                                \n"
3007                            "    tmp2 = tmp2 + float(d.a[0].y) + d.b[0][0][0] + d.c[0][0];      \n"
3008                            "    color = vec4(0, 1, 0, 1) * tmp * tmp2;                         \n"
3009                            "}";
3010         }
3011
3012         virtual long Run()
3013         {
3014                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3015                 glBindAttribLocation(program, 0, "position");
3016                 glBindFragDataLocation(program, 0, "color");
3017                 LinkProgram(program);
3018
3019                 long error = NO_ERROR;
3020
3021                 GLint res;
3022                 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 28, error);
3023                 glGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &res);
3024                 if (res < 7)
3025                 {
3026                         m_context.getTestContext().getLog()
3027                                 << tcu::TestLog::Message
3028                                 << "Error on: glGetProgramInterfaceiv, if: GL_BUFFER_VARIABLE, param: GL_ACTIVE_RESOURCES\n"
3029                                 << "Expected value greater or equal to 7, got " << res << tcu::TestLog::EndMessage;
3030                         error = ERROR;
3031                 }
3032                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 4, error);
3033                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
3034
3035                 std::map<std::string, GLuint> indicesSSB;
3036                 std::map<std::string, GLuint> indicesBV;
3037                 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
3038                 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "NotSoSimpleBuffer", error);
3039                 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer", error);
3040                 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer[1]", error);
3041                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a", error);
3042                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "b", error);
3043                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "c", error);
3044                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.a[0]", error);
3045                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.c", error);
3046                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.b[0]", error);
3047                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.a[0].b[0].d", error);
3048                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.b", error);
3049                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.c", error);
3050
3051                 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer",
3052                                                                          error);
3053                 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"],
3054                                                                          "NotSoSimpleBuffer", error);
3055                 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], "TrickyBuffer[0]",
3056                                                                          error);
3057                 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], "TrickyBuffer[1]",
3058                                                                          error);
3059                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
3060                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["b"], "b", error);
3061                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["c"], "c", error);
3062                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.a[0]"],
3063                                                                          "NotSoSimpleBuffer.a[0]", error);
3064                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.c"],
3065                                                                          "NotSoSimpleBuffer.c", error);
3066                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.b[0]"],
3067                                                                          "NotSoSimpleBuffer.b[0]", error);
3068                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"],
3069                                                                          "TrickyBuffer.a[0].b[0].d[0]", error);
3070                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.b"], "TrickyBuffer.b", error);
3071                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.c"], "TrickyBuffer.c", error);
3072
3073                 GLenum props[] = { GL_NAME_LENGTH,
3074                                                    GL_BUFFER_BINDING,
3075                                                    GL_NUM_ACTIVE_VARIABLES,
3076                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
3077                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
3078                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
3079                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3080                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3081                                                    GL_REFERENCED_BY_VERTEX_SHADER };
3082                 GLint expected[] = { 13, 0, 3, 0, 1, 0, 0, 0, 0 };
3083                 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 9, props, 9, expected,
3084                                                                    error);
3085
3086                 GLenum props2[] = { GL_NAME_LENGTH,
3087                                                         GL_BUFFER_BINDING,
3088                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
3089                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
3090                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
3091                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3092                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3093                                                         GL_REFERENCED_BY_VERTEX_SHADER };
3094                 GLint expected2[] = { 18, 1, 0, 1, 0, 0, 0, 0 };
3095                 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 8, props2, 8,
3096                                                                    expected2, error);
3097                 GLint expected3[] = { 16, 4, 0, 1, 0, 0, 0, 0 };
3098                 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], 8, props2, 8,
3099                                                                    expected3, error);
3100                 GLint expected4[] = { 16, 5, 0, 1, 0, 0, 0, 0 };
3101                 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], 8, props2, 8,
3102                                                                    expected4, error);
3103
3104                 GLenum props3[] = { GL_NAME_LENGTH,
3105                                                         GL_TYPE,
3106                                                         GL_ARRAY_SIZE,
3107                                                         GL_BLOCK_INDEX,
3108                                                         GL_ARRAY_STRIDE,
3109                                                         GL_IS_ROW_MAJOR,
3110                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
3111                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
3112                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
3113                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3114                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3115                                                         GL_REFERENCED_BY_VERTEX_SHADER,
3116                                                         GL_TOP_LEVEL_ARRAY_SIZE,
3117                                                         GL_TOP_LEVEL_ARRAY_STRIDE };
3118                 GLint expected5[] = {
3119                         2, GL_FLOAT_MAT3x2, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 0, 1, 0, 0, 0, 0, 1, 0
3120                 };
3121                 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a"], 14, props3, 14, expected5, error);
3122
3123                 GLenum props4[] = { GL_NAME_LENGTH,
3124                                                         GL_TYPE,
3125                                                         GL_ARRAY_SIZE,
3126                                                         GL_BLOCK_INDEX,
3127                                                         GL_MATRIX_STRIDE,
3128                                                         GL_IS_ROW_MAJOR,
3129                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
3130                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
3131                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
3132                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3133                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3134                                                         GL_REFERENCED_BY_VERTEX_SHADER,
3135                                                         GL_TOP_LEVEL_ARRAY_SIZE };
3136                 GLint expected6[] = {
3137                         28, GL_FLOAT, 2, static_cast<GLint>(indicesSSB["TrickyBuffer"]), 0, 0, 0, 1, 0, 0, 0, 0, 3
3138                 };
3139                 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"], 13, props4, 13,
3140                                                                    expected6, error);
3141
3142                 GLenum                   prop   = GL_ACTIVE_VARIABLES;
3143                 const GLsizei   bufSize = 1000;
3144                 GLsizei                  length;
3145                 GLint                    param[bufSize];
3146                 std::set<GLuint> exp;
3147                 exp.insert(indicesBV["a"]);
3148                 exp.insert(indicesBV["b"]);
3149                 exp.insert(indicesBV["c"]);
3150                 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 1, &prop, bufSize, &length,
3151                                                            param);
3152                 for (int i = 0; i < length; ++i)
3153                 {
3154                         if (exp.find(param[i]) == exp.end())
3155                         {
3156                                 m_context.getTestContext().getLog()
3157                                         << tcu::TestLog::Message
3158                                         << "Unexpected index found in active variables of SimpleBuffer: " << param[i]
3159                                         << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
3160                                            "GL_SHADER_STORAGE_BLOCK"
3161                                         << tcu::TestLog::EndMessage;
3162                                 glDeleteProgram(program);
3163                                 return ERROR;
3164                         }
3165                         else if (length != 3)
3166                         {
3167                                 m_context.getTestContext().getLog()
3168                                         << tcu::TestLog::Message << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES "
3169                                                                                                 "interface: GL_SHADER_STORAGE_BLOCK\n"
3170                                         << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
3171                                 glDeleteProgram(program);
3172                                 return ERROR;
3173                         }
3174                 }
3175                 std::set<GLuint> exp2;
3176                 exp2.insert(indicesBV["NotSoSimpleBuffer.a[0]"]);
3177                 exp2.insert(indicesBV["NotSoSimpleBuffer.b[0]"]);
3178                 exp2.insert(indicesBV["NotSoSimpleBuffer.c"]);
3179                 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 1, &prop, bufSize,
3180                                                            &length, param);
3181                 for (int i = 0; i < length; ++i)
3182                 {
3183                         if (exp2.find(param[i]) == exp2.end())
3184                         {
3185                                 m_context.getTestContext().getLog()
3186                                         << tcu::TestLog::Message
3187                                         << "Unexpected index found in active variables of NotSoSimpleBuffer: " << param[i]
3188                                         << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
3189                                            "GL_SHADER_STORAGE_BLOCK"
3190                                         << tcu::TestLog::EndMessage;
3191                                 glDeleteProgram(program);
3192                                 return ERROR;
3193                         }
3194                         else if (length != 3)
3195                         {
3196                                 m_context.getTestContext().getLog()
3197                                         << tcu::TestLog::Message << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES "
3198                                                                                                 "interface: GL_SHADER_STORAGE_BLOCK\n"
3199                                         << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
3200                                 glDeleteProgram(program);
3201                                 return ERROR;
3202                         }
3203                 }
3204
3205                 glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
3206                 if (res < 3)
3207                 {
3208                         m_context.getTestContext().getLog()
3209                                 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!\n"
3210                                 << "Call: glGetProgramInterfaceiv, interface: GL_SHADER_STORAGE_BLOCK" << tcu::TestLog::EndMessage;
3211                         return ERROR;
3212                 }
3213
3214                 glDeleteProgram(program);
3215                 return error;
3216         }
3217 };
3218
3219 class TransformFeedbackBuiltin : public SimpleShaders
3220 {
3221         virtual std::string Title()
3222         {
3223                 return "Transform Feedback Built-in Variables";
3224         }
3225
3226         virtual std::string ShadersDesc()
3227         {
3228                 return "fallthrough fragment and vertex shaders with different types of out variables used";
3229         }
3230
3231         virtual std::string PurposeExt()
3232         {
3233                 return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param with"
3234                            " built-in variables (gl_NextBuffer, gl_SkipComponents) used.\n";
3235         }
3236
3237         virtual std::string VertexShader()
3238         {
3239                 return "#version 430                         \n"
3240                            "in vec4 position;                    \n"
3241                            ""
3242                            "out ivec4 a;                         \n"
3243                            "out uvec2 c;                         \n"
3244                            "out uint d;                          \n"
3245                            "out int f;                           \n"
3246                            "out uint e;                          \n"
3247                            "out int g;                           \n"
3248                            ""
3249                            "void main(void)                      \n"
3250                            "{                                    \n"
3251                            "   vec4 pos;                         \n"
3252                            "   a = ivec4(1);                     \n"
3253                            "   c = uvec2(1u);                    \n"
3254                            "   d = 1u;                           \n"
3255                            "   f = 1;                            \n"
3256                            "   e = 1u;                           \n"
3257                            "   g = 1;                            \n"
3258                            "   gl_Position = position;           \n"
3259                            "}";
3260         }
3261
3262         virtual long Run()
3263         {
3264                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3265                 glBindAttribLocation(program, 0, "position");
3266                 glBindFragDataLocation(program, 0, "color");
3267                 const char* varyings[11] = { "a", "gl_NextBuffer",              "c", "gl_SkipComponents1", "d", "gl_SkipComponents2",
3268                                                                          "f", "gl_SkipComponents3", "e", "gl_SkipComponents4", "g" };
3269                 glTransformFeedbackVaryings(program, 11, varyings, GL_INTERLEAVED_ATTRIBS);
3270                 LinkProgram(program);
3271
3272                 long error = NO_ERROR;
3273
3274                 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 11, error);
3275                 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 19, error);
3276
3277                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_NextBuffer", GL_INVALID_INDEX, error);
3278                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents1", GL_INVALID_INDEX,
3279                                                                           error);
3280                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents2", GL_INVALID_INDEX,
3281                                                                           error);
3282                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents3", GL_INVALID_INDEX,
3283                                                                           error);
3284                 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents4", GL_INVALID_INDEX,
3285                                                                           error);
3286
3287                 std::map<std::string, GLuint> indices;
3288                 for (int i = 0; i < 11; i++)
3289                 {
3290                         GLsizei length;
3291                         GLchar  name[1024] = { '\0' };
3292                         glGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, i, 1024, &length, name);
3293                         indices[name] = i;
3294                 }
3295
3296                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Indices of builtins:\n"
3297                                                                                         << indices["gl_NextBuffer"] << ", " << indices["gl_SkipComponents1"] << ", "
3298                                                                                         << indices["gl_SkipComponents2"] << ", " << indices["gl_SkipComponents3"]
3299                                                                                         << ", " << indices["gl_SkipComponents4"] << tcu::TestLog::EndMessage;
3300
3301                 GLenum props[]  = { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE };
3302                 GLint  expected[] = { 14, GL_NONE, 0 };
3303                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_NextBuffer"], 3, props, 3,
3304                                                                    expected, error);
3305                 GLint expected2[] = { 19, GL_NONE, 1 };
3306                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents1"], 3, props, 3,
3307                                                                    expected2, error);
3308                 GLint expected3[] = { 19, GL_NONE, 2 };
3309                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents2"], 3, props, 3,
3310                                                                    expected3, error);
3311                 GLint expected4[] = { 19, GL_NONE, 3 };
3312                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents3"], 3, props, 3,
3313                                                                    expected4, error);
3314                 GLint expected5[] = { 19, GL_NONE, 4 };
3315                 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents4"], 3, props, 3,
3316                                                                    expected5, error);
3317
3318                 glDeleteProgram(program);
3319                 return error;
3320         }
3321 };
3322
3323 class NullLength : public SimpleShaders
3324 {
3325
3326         virtual std::string Title()
3327         {
3328                 return "NULL Length Test";
3329         }
3330
3331         virtual std::string PurposeExt()
3332         {
3333                 return "\n\n Purpose is to verify that GetProgramResourceName with null length doesn't return length (doesn't "
3334                            "crash).\n";
3335         }
3336
3337         virtual std::string VertexShader()
3338         {
3339                 return "#version 430                         \n"
3340                            "in vec4 position;                    \n"
3341                            "void main(void)                      \n"
3342                            "{                                    \n"
3343                            "    gl_Position = position;          \n"
3344                            "}";
3345         }
3346
3347         virtual std::string FragmentShader()
3348         {
3349                 return "#version 430                   \n"
3350                            "out vec4 color;                \n"
3351                            "void main() {                  \n"
3352                            "    color = vec4(0, 1, 0, 1);  \n"
3353                            "}";
3354         }
3355
3356         virtual long Run()
3357         {
3358                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3359                 glBindAttribLocation(program, 0, "position");
3360                 glBindFragDataLocation(program, 0, "color");
3361                 LinkProgram(program);
3362
3363                 GLchar name[1024] = { '\0' };
3364                 GLuint index      = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color");
3365                 GLenum prop               = GL_ARRAY_SIZE;
3366                 GLint  res;
3367                 glGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, 1024, NULL, name);
3368                 glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &prop, 1, NULL, &res);
3369
3370                 std::string expected = "color";
3371                 if (name != expected)
3372                 {
3373                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected name: " << expected
3374                                                                                                 << ", got: " << name << tcu::TestLog::EndMessage;
3375                         glDeleteProgram(program);
3376                         return ERROR;
3377                 }
3378                 else if (res != 1)
3379                 {
3380                         m_context.getTestContext().getLog()
3381                                 << tcu::TestLog::Message << "Expected array_size: 1, got: " << res << tcu::TestLog::EndMessage;
3382                         glDeleteProgram(program);
3383                         return ERROR;
3384                 }
3385
3386                 glDeleteProgram(program);
3387                 return NO_ERROR;
3388         }
3389 };
3390
3391 class ArraysOfArrays : public SimpleShaders
3392 {
3393
3394         virtual std::string Title()
3395         {
3396                 return "Arrays Of Arrays Test";
3397         }
3398
3399         virtual std::string ShadersDesc()
3400         {
3401                 return "fallthrough fragment and vertex shaders with multi dimensional uniform array used";
3402         }
3403
3404         virtual std::string PurposeExt()
3405         {
3406                 return "\n\n Purpose is to verify that feature works correctly with arrays_of_arrays extension.\n";
3407         }
3408
3409         virtual std::string VertexShader()
3410         {
3411                 return "#version 430                         \n"
3412                            "in vec4 position;                    \n"
3413                            "uniform vec4 a[3][4][5];             \n"
3414                            "void main(void)                      \n"
3415                            "{                                    \n"
3416                            "    gl_Position = position;          \n"
3417                            "    for (int i = 0; i < 5; ++i)      \n"
3418                            "        gl_Position += a[2][1][i];   \n"
3419                            "}";
3420         }
3421
3422         virtual std::string FragmentShader()
3423         {
3424                 return "#version 430                   \n"
3425                            "out vec4 color;                \n"
3426                            "void main() {                  \n"
3427                            "    color = vec4(0, 1, 0, 1);  \n"
3428                            "}";
3429         }
3430
3431         virtual long Run()
3432         {
3433                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3434                 glBindAttribLocation(program, 0, "position");
3435                 glBindFragDataLocation(program, 0, "color");
3436                 LinkProgram(program);
3437
3438                 long error = NO_ERROR;
3439
3440                 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 11, error);
3441
3442                 std::map<std::string, GLuint> indices;
3443                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a[2][1]", error);
3444                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, "a[2][1][0]", indices["a[2][1]"], error);
3445
3446                 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a[2][1]"], "a[2][1][0]", error);
3447
3448                 GLenum props[] = { GL_NAME_LENGTH,
3449                                                    GL_TYPE,
3450                                                    GL_ARRAY_SIZE,
3451                                                    GL_OFFSET,
3452                                                    GL_BLOCK_INDEX,
3453                                                    GL_ARRAY_STRIDE,
3454                                                    GL_MATRIX_STRIDE,
3455                                                    GL_IS_ROW_MAJOR,
3456                                                    GL_ATOMIC_COUNTER_BUFFER_INDEX,
3457                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
3458                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
3459                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
3460                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3461                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3462                                                    GL_REFERENCED_BY_VERTEX_SHADER,
3463                                                    GL_LOCATION };
3464                 GLint expected[] = {
3465                         11, GL_FLOAT_VEC4, 5, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "a[2][1]")
3466                 };
3467                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a[2][1]"], 16, props, 16, expected, error);
3468
3469                 glDeleteProgram(program);
3470                 return error;
3471         }
3472 };
3473
3474 class TopLevelArray : public SimpleShaders
3475 {
3476
3477         virtual std::string Title()
3478         {
3479                 return "Top Level Array Test";
3480         }
3481
3482         virtual std::string ShadersDesc()
3483         {
3484                 return "fallthrough fragment and vertex shaders with multi dimensional array used inside storage block";
3485         }
3486
3487         virtual std::string PurposeExt()
3488         {
3489                 return "\n\n Purpose is to verify that feature works correctly when querying for GL_TOP_LEVEL_ARRAY_SIZE\n"
3490                            " and GL_TOP_LEVEL_ARRAY_STRIDE extension.\n";
3491         }
3492
3493         virtual std::string FragmentShader()
3494         {
3495                 return "#version 430                   \n"
3496                            "buffer Block {                       \n"
3497                            "   vec4 a[5][4][3];                  \n"
3498                            "};                                   \n"
3499                            "out vec4 color;                             \n"
3500                            "void main() {                               \n"
3501                            "    color = vec4(0, 1, 0, 1) + a[0][0][0];  \n"
3502                            "}";
3503         }
3504
3505         virtual long Run()
3506         {
3507                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3508                 glBindAttribLocation(program, 0, "position");
3509                 glBindFragDataLocation(program, 0, "color");
3510                 LinkProgram(program);
3511
3512                 long error = NO_ERROR;
3513
3514                 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 11, error);
3515                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 6, error);
3516                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
3517
3518                 std::map<std::string, GLuint> indicesSSB;
3519                 std::map<std::string, GLuint> indicesBV;
3520                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a[0][0]", error);
3521                 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Block", error);
3522
3523                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], "a[0][0][0]", error);
3524                 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Block"], "Block", error);
3525
3526                 GLenum props3[] = { GL_NAME_LENGTH,
3527                                                         GL_TYPE,
3528                                                         GL_ARRAY_SIZE,
3529                                                         GL_BLOCK_INDEX,
3530                                                         GL_IS_ROW_MAJOR,
3531                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
3532                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
3533                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
3534                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3535                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3536                                                         GL_REFERENCED_BY_VERTEX_SHADER,
3537                                                         GL_TOP_LEVEL_ARRAY_SIZE };
3538                 GLint expected5[] = { 11, GL_FLOAT_VEC4, 3, static_cast<GLint>(indicesSSB["Block"]), 0, 0, 1, 0, 0, 0, 0, 5 };
3539                 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 12, props3, 12, expected5, error);
3540
3541                 GLenum  prop = GL_TOP_LEVEL_ARRAY_STRIDE;
3542                 GLsizei len;
3543                 GLint   res;
3544                 glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 1, &prop, 1024, &len, &res);
3545                 if (res <= 0)
3546                 {
3547                         m_context.getTestContext().getLog()
3548                                 << tcu::TestLog::Message
3549                                 << "Call: glGetProgramResourceiv, interface: GL_BUFFER_VARIABLE, param: GL_TOP_LEVEL_ARRAY_STRIDE\n"
3550                                 << "Expected value greater than 0, got: " << res << tcu::TestLog::EndMessage;
3551                         glDeleteProgram(program);
3552                         return ERROR;
3553                 }
3554
3555                 glDeleteProgram(program);
3556                 return error;
3557         }
3558 };
3559
3560 class SeparateProgramsVertex : public SimpleShaders
3561 {
3562 public:
3563         virtual std::string Title()
3564         {
3565                 return "Separate Program Vertex Shader Test";
3566         }
3567
3568         virtual std::string ShadersDesc()
3569         {
3570                 return "vertex shader as separate shader object";
3571         }
3572
3573         virtual std::string PurposeExt()
3574         {
3575                 return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
3576                            "functionality.\n";
3577         }
3578
3579         virtual GLuint CreateShaderProgram(GLenum type, GLsizei count, const GLchar** strings)
3580         {
3581                 GLuint program = glCreateShaderProgramv(type, count, strings);
3582                 GLint  status  = GL_TRUE;
3583                 glGetProgramiv(program, GL_LINK_STATUS, &status);
3584                 if (status == GL_FALSE)
3585                 {
3586                         GLsizei length;
3587                         GLchar  log[1024];
3588                         glGetProgramInfoLog(program, sizeof(log), &length, log);
3589                         if (length > 1)
3590                         {
3591                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
3592                                                                                                         << log << tcu::TestLog::EndMessage;
3593                         }
3594                 }
3595                 return program;
3596         }
3597
3598         virtual long Run()
3599         {
3600                 long error = NO_ERROR;
3601
3602                 const char* srcVS = "#version 430 core                          \n"
3603                                                         "layout(location = 0) in vec4 in_vertex;    \n"
3604                                                         ""
3605                                                         "out Color {                                \n"
3606                                                         "  float r, g, b;                           \n"
3607                                                         "  vec4 iLikePie;                           \n"
3608                                                         "} vs_color;                                \n"
3609                                                         "out gl_PerVertex {                         \n"
3610                                                         "  vec4 gl_Position;                        \n"
3611                                                         "};                                         \n"
3612                                                         ""
3613                                                         "uniform float u;                           \n"
3614                                                         "uniform vec4 v;                            \n"
3615                                                         ""
3616                                                         "void main() {                              \n"
3617                                                         "  gl_Position = in_vertex;                 \n"
3618                                                         "  vs_color.r = u;                          \n"
3619                                                         "  vs_color.g = 0.0;                        \n"
3620                                                         "  vs_color.b = 0.0;                        \n"
3621                                                         "  vs_color.iLikePie = v;                   \n"
3622                                                         "}";
3623
3624                 const GLuint vs = CreateShaderProgram(GL_VERTEX_SHADER, 1, &srcVS);
3625
3626                 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
3627                 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 2, error);
3628                 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 10, error);
3629                 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
3630                 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 15, error);
3631                 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
3632
3633                 std::map<std::string, GLuint> indicesU;
3634                 std::map<std::string, GLuint> indicesI;
3635                 std::map<std::string, GLuint> indicesO;
3636                 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "u", error);
3637                 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "v", error);
3638                 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_INPUT, indicesI, "in_vertex", error);
3639                 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.r", error);
3640                 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.g", error);
3641                 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.b", error);
3642                 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.iLikePie", error);
3643                 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
3644
3645                 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["u"], "u", error);
3646                 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["v"], "v", error);
3647                 VerifyGetProgramResourceName(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], "in_vertex", error);
3648                 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.r"], "Color.r", error);
3649                 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.g"], "Color.g", error);
3650                 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.b"], "Color.b", error);
3651                 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.iLikePie"], "Color.iLikePie", error);
3652                 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
3653
3654                 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "u", glGetUniformLocation(vs, "u"), error);
3655                 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "v", glGetUniformLocation(vs, "v"), error);
3656                 VerifyGetProgramResourceLocation(vs, GL_PROGRAM_INPUT, "in_vertex", 0, error);
3657
3658                 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.r", -1, error);
3659                 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.g", -1, error);
3660                 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.b", -1, error);
3661                 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.iLikePie", -1, error);
3662                 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "gl_Position", -1, error);
3663
3664                 GLenum props[] = { GL_NAME_LENGTH,
3665                                                    GL_TYPE,
3666                                                    GL_ARRAY_SIZE,
3667                                                    GL_OFFSET,
3668                                                    GL_BLOCK_INDEX,
3669                                                    GL_ARRAY_STRIDE,
3670                                                    GL_MATRIX_STRIDE,
3671                                                    GL_IS_ROW_MAJOR,
3672                                                    GL_ATOMIC_COUNTER_BUFFER_INDEX,
3673                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
3674                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
3675                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
3676                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3677                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3678                                                    GL_REFERENCED_BY_VERTEX_SHADER,
3679                                                    GL_LOCATION };
3680                 GLint expected[] = {
3681                         2, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(vs, "v")
3682                 };
3683                 VerifyGetProgramResourceiv(vs, GL_UNIFORM, indicesU["v"], 16, props, 16, expected, error);
3684
3685                 GLenum props2[] = { GL_NAME_LENGTH,
3686                                                         GL_TYPE,
3687                                                         GL_ARRAY_SIZE,
3688                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
3689                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
3690                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
3691                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3692                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3693                                                         GL_REFERENCED_BY_VERTEX_SHADER,
3694                                                         GL_LOCATION,
3695                                                         GL_IS_PER_PATCH };
3696                 GLint expected2[] = { 10, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, 0 };
3697                 VerifyGetProgramResourceiv(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], 11, props2, 11, expected2, error);
3698
3699                 GLenum props3[] = { GL_NAME_LENGTH,
3700                                                         GL_TYPE,
3701                                                         GL_ARRAY_SIZE,
3702                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
3703                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
3704                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
3705                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3706                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3707                                                         GL_REFERENCED_BY_VERTEX_SHADER,
3708                                                         GL_IS_PER_PATCH,
3709                                                         GL_LOCATION_INDEX };
3710                 GLint expected3[] = { 15, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, -1 };
3711                 VerifyGetProgramResourceiv(vs, GL_PROGRAM_OUTPUT, indicesO["Color.iLikePie"], 11, props3, 11, expected3, error);
3712
3713                 glDeleteProgram(vs);
3714                 return error;
3715         }
3716 };
3717
3718 class SeparateProgramsTessControl : public SeparateProgramsVertex
3719 {
3720
3721         virtual std::string Title()
3722         {
3723                 return "Separate Program Tess Control Shader Test";
3724         }
3725
3726         virtual std::string ShadersDesc()
3727         {
3728                 return "tess control shader as separate shader object";
3729         }
3730
3731         virtual std::string PurposeExt()
3732         {
3733                 return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
3734                            "functionality.\n";
3735         }
3736
3737         virtual long Run()
3738         {
3739                 long error = NO_ERROR;
3740
3741                 const char* srcTCS = "#version 430                                                  \n"
3742                                                          "layout(vertices = 3) out;                                     \n"
3743                                                          "layout(location = 0) patch out vec4 data;                     \n"
3744                                                          "out gl_PerVertex {                                            \n"
3745                                                          "   vec4 gl_Position;                                          \n"
3746                                                          "   float gl_PointSize;                                        \n"
3747                                                          "   float gl_ClipDistance[];                                   \n"
3748                                                          "} gl_out[];                                                   \n"
3749                                                          ""
3750                                                          "in Color {                                 \n"
3751                                                          "  float r, g, b;                           \n"
3752                                                          "  vec4 iLikePie;                           \n"
3753                                                          "} vs_color[];                              \n"
3754                                                          ""
3755                                                          "void main() {                                                                   \n"
3756                                                          "   data = vec4(1);                                                              \n"
3757                                                          "   gl_out[gl_InvocationID].gl_Position =                                        \n"
3758                                                          "           vec4(vs_color[0].r, vs_color[0].g, vs_color[0].b, vs_color[0].iLikePie.x + "
3759                                                          "float(gl_InvocationID));       \n"
3760                                                          "   gl_TessLevelInner[0] = 1.0;                                                  \n"
3761                                                          "   gl_TessLevelInner[1] = 1.0;                                                  \n"
3762                                                          "   gl_TessLevelOuter[0] = 1.0;                                                  \n"
3763                                                          "   gl_TessLevelOuter[1] = 1.0;                                                  \n"
3764                                                          "   gl_TessLevelOuter[2] = 1.0;                                                  \n"
3765                                                          "}";
3766
3767                 const GLuint tcs = CreateShaderProgram(GL_TESS_CONTROL_SHADER, 1, &srcTCS);
3768
3769                 // gl_InvocationID should be included
3770                 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 16, error);
3771                 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 5, error);
3772
3773                 std::map<std::string, GLuint> indicesI;
3774                 std::map<std::string, GLuint> indicesO;
3775                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "gl_PerVertex.gl_Position", error);
3776                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "data", error);
3777                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.r", error);
3778                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.g", error);
3779                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.b", error);
3780                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.iLikePie", error);
3781
3782                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_PerVertex.gl_Position"],
3783                                                                          "gl_PerVertex.gl_Position", error);
3784                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["data"], "data", error);
3785                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.r"], "Color.r", error);
3786                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.g"], "Color.g", error);
3787                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.b"], "Color.b", error);
3788                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.iLikePie"], "Color.iLikePie", error);
3789
3790                 GLenum props2[] = { GL_NAME_LENGTH,
3791                                                         GL_TYPE,
3792                                                         GL_ARRAY_SIZE,
3793                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
3794                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
3795                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
3796                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3797                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3798                                                         GL_REFERENCED_BY_VERTEX_SHADER,
3799                                                         GL_IS_PER_PATCH };
3800                 GLint expected2[] = { 15, GL_FLOAT_VEC4, 1, 0, 0, 0, 1, 0, 0, 0 };
3801                 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["Color.iLikePie"], 10, props2, 10, expected2, error);
3802
3803                 GLenum props3[] = { GL_NAME_LENGTH,
3804                                                         GL_TYPE,
3805                                                         GL_ARRAY_SIZE,
3806                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
3807                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
3808                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
3809                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3810                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3811                                                         GL_REFERENCED_BY_VERTEX_SHADER,
3812                                                         GL_IS_PER_PATCH,
3813                                                         GL_LOCATION,
3814                                                         GL_LOCATION_INDEX };
3815                 GLint expected3[] = { 5, GL_FLOAT_VEC4, 1, 0, 0, 0, 1, 0, 0, 1, 0, -1 };
3816                 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["data"], 12, props3, 12, expected3, error);
3817
3818                 glDeleteProgram(tcs);
3819                 return error;
3820         }
3821 };
3822
3823 class SeparateProgramsTessEval : public SeparateProgramsVertex
3824 {
3825
3826         virtual std::string Title()
3827         {
3828                 return "Separate Program Tess Eval Shader Test";
3829         }
3830
3831         virtual std::string ShadersDesc()
3832         {
3833                 return "tess eval shader as separate shader object";
3834         }
3835
3836         virtual long Run()
3837         {
3838                 long error = NO_ERROR;
3839
3840                 const char* srcTCS = "#version 430                                                  \n"
3841                                                          "layout(quads, equal_spacing, ccw) in;                         \n"
3842                                                          "out gl_PerVertex {                                            \n"
3843                                                          "   vec4 gl_Position;                                          \n"
3844                                                          "   float gl_PointSize;                                        \n"
3845                                                          "   float gl_ClipDistance[];                                   \n"
3846                                                          "};                                                            \n"
3847                                                          ""
3848                                                          "in gl_PerVertex {                   \n"
3849                                                          "   vec4 gl_Position;                \n"
3850                                                          "   float gl_PointSize;              \n"
3851                                                          "   float gl_ClipDistance[];         \n"
3852                                                          "} gl_in[];                          \n"
3853                                                          ""
3854                                                          "void main() {                                \n"
3855                                                          "   vec4 p0 = gl_in[0].gl_Position;           \n"
3856                                                          "   vec4 p1 = gl_in[1].gl_Position;           \n"
3857                                                          "   vec4 p2 = gl_in[2].gl_Position;           \n"
3858                                                          "   gl_Position = vec4(p0.x, p1.y, p2.z, p0.x);                 \n"
3859                                                          "}";
3860
3861                 const GLuint tcs = CreateShaderProgram(GL_TESS_EVALUATION_SHADER, 1, &srcTCS);
3862
3863                 std::map<std::string, GLuint> indicesI;
3864                 std::map<std::string, GLuint> indicesO;
3865                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "gl_PerVertex.gl_Position", error);
3866                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
3867
3868                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"],
3869                                                                          "gl_PerVertex.gl_Position", error);
3870                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
3871
3872                 GLenum props2[] = { GL_NAME_LENGTH,
3873                                                         GL_TYPE,
3874                                                         GL_ARRAY_SIZE,
3875                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
3876                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
3877                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
3878                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3879                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3880                                                         GL_REFERENCED_BY_VERTEX_SHADER,
3881                                                         GL_IS_PER_PATCH };
3882                 GLint expected2[] = { 25, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 1, 0, 0 };
3883                 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"], 10, props2, 10,
3884                                                                    expected2, error);
3885
3886                 GLenum props3[] = { GL_NAME_LENGTH,
3887                                                         GL_TYPE,
3888                                                         GL_ARRAY_SIZE,
3889                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
3890                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
3891                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
3892                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3893                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3894                                                         GL_REFERENCED_BY_VERTEX_SHADER,
3895                                                         GL_IS_PER_PATCH,
3896                                                         GL_LOCATION_INDEX };
3897                 GLint expected3[] = { 12, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 1, 0, 0, -1 };
3898                 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], 11, props3, 11, expected3, error);
3899
3900                 glDeleteProgram(tcs);
3901                 return error;
3902         }
3903 };
3904
3905 class SeparateProgramsGeometry : public SeparateProgramsVertex
3906 {
3907
3908         virtual std::string Title()
3909         {
3910                 return "Separate Program Geometry Shader Test";
3911         }
3912
3913         virtual std::string ShadersDesc()
3914         {
3915                 return "geometry shader as separate shader object";
3916         }
3917
3918         virtual long Run()
3919         {
3920                 long error = NO_ERROR;
3921
3922                 const char* srcTCS = "#version 430                                                  \n"
3923                                                          "layout(triangles) in;                                         \n"
3924                                                          "layout(triangle_strip, max_vertices = 4) out;                 \n"
3925                                                          ""
3926                                                          "out gl_PerVertex {                                            \n"
3927                                                          "   vec4 gl_Position;                                          \n"
3928                                                          "   float gl_PointSize;                                        \n"
3929                                                          "   float gl_ClipDistance[];                                   \n"
3930                                                          "};                                                            \n"
3931                                                          ""
3932                                                          "in gl_PerVertex {                                             \n"
3933                                                          "   vec4 gl_Position;                                          \n"
3934                                                          "   float gl_PointSize;                                        \n"
3935                                                          "   float gl_ClipDistance[];                                   \n"
3936                                                          "} gl_in[];                                                    \n"
3937                                                          ""
3938                                                          "void main() {                              \n"
3939                                                          "   gl_Position = vec4(-1, 1, 0, 1);        \n"
3940                                                          "   EmitVertex();                           \n"
3941                                                          "   gl_Position = vec4(-1, -1, 0, 1);       \n"
3942                                                          "   EmitVertex();                           \n"
3943                                                          "   gl_Position = vec4(1, 1, 0, 1);         \n"
3944                                                          "   EmitVertex();                           \n"
3945                                                          "   gl_Position = gl_in[0].gl_Position;     \n"
3946                                                          "   EmitVertex();                           \n"
3947                                                          "   EndPrimitive();                         \n"
3948                                                          "}";
3949
3950                 const GLuint tcs = CreateShaderProgram(GL_GEOMETRY_SHADER, 1, &srcTCS);
3951
3952                 std::map<std::string, GLuint> indicesI;
3953                 std::map<std::string, GLuint> indicesO;
3954                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "gl_PerVertex.gl_Position", error);
3955                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
3956
3957                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"],
3958                                                                          "gl_PerVertex.gl_Position", error);
3959                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
3960
3961                 GLenum props2[] = { GL_NAME_LENGTH,
3962                                                         GL_TYPE,
3963                                                         GL_ARRAY_SIZE,
3964                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
3965                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
3966                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
3967                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3968                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3969                                                         GL_REFERENCED_BY_VERTEX_SHADER,
3970                                                         GL_IS_PER_PATCH };
3971                 GLint expected2[] = { 25, GL_FLOAT_VEC4, 1, 0, 0, 1, 0, 0, 0, 0 };
3972                 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"], 10, props2, 10,
3973                                                                    expected2, error);
3974
3975                 GLenum props3[] = { GL_NAME_LENGTH,
3976                                                         GL_TYPE,
3977                                                         GL_ARRAY_SIZE,
3978                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
3979                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
3980                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
3981                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3982                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3983                                                         GL_REFERENCED_BY_VERTEX_SHADER,
3984                                                         GL_IS_PER_PATCH,
3985                                                         GL_LOCATION_INDEX };
3986                 GLint expected3[] = { 12, GL_FLOAT_VEC4, 1, 0, 0, 1, 0, 0, 0, 0, -1 };
3987                 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], 11, props3, 11, expected3, error);
3988
3989                 glDeleteProgram(tcs);
3990                 return error;
3991         }
3992 };
3993
3994 class SeparateProgramsFragment : public SeparateProgramsVertex
3995 {
3996
3997         virtual std::string Title()
3998         {
3999                 return "Separate Program Fragment Shader Test";
4000         }
4001
4002         virtual std::string ShadersDesc()
4003         {
4004                 return "fragment shader as separate shader object";
4005         }
4006
4007         virtual long Run()
4008         {
4009                 long error = NO_ERROR;
4010
4011                 const char* srcTCS = "#version 430                                     \n"
4012                                                          "out vec4 fs_color;                               \n"
4013                                                          ""
4014                                                          "layout(location = 1) uniform vec4 x;             \n"
4015                                                          ""
4016                                                          "layout(binding = 0) buffer SimpleBuffer {        \n"
4017                                                          "   vec4 a;                                       \n"
4018                                                          "};                                               \n"
4019                                                          ""
4020                                                          "in vec4 vs_color;                                \n"
4021                                                          "void main() {                                    \n"
4022                                                          "   fs_color = vs_color + x + a;                  \n"
4023                                                          "}";
4024
4025                 const GLuint tcs = CreateShaderProgram(GL_FRAGMENT_SHADER, 1, &srcTCS);
4026
4027                 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
4028                 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
4029                 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 9, error);
4030                 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
4031                 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
4032                 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
4033                 VerifyGetProgramInterfaceiv(tcs, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 2, error);
4034                 VerifyGetProgramInterfaceiv(tcs, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, 1, error);
4035                 VerifyGetProgramInterfaceiv(tcs, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
4036                 VerifyGetProgramInterfaceiv(tcs, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 13, error);
4037                 VerifyGetProgramInterfaceiv(tcs, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 1, error);
4038
4039                 std::map<std::string, GLuint> indicesSSB;
4040                 std::map<std::string, GLuint> indicesBV;
4041                 std::map<std::string, GLuint> indicesI;
4042                 std::map<std::string, GLuint> indicesO;
4043                 std::map<std::string, GLuint> indicesU;
4044                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "vs_color", error);
4045                 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "fs_color", error);
4046                 VerifyGetProgramResourceIndex(tcs, GL_UNIFORM, indicesU, "x", error);
4047                 VerifyGetProgramResourceIndex(tcs, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
4048                 VerifyGetProgramResourceIndex(tcs, GL_BUFFER_VARIABLE, indicesBV, "a", error);
4049
4050                 VerifyGetProgramResourceName(tcs, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer", error);
4051                 VerifyGetProgramResourceName(tcs, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
4052                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], "vs_color", error);
4053                 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], "fs_color", error);
4054                 VerifyGetProgramResourceName(tcs, GL_UNIFORM, indicesU["x"], "x", error);
4055
4056                 VerifyGetProgramResourceLocation(tcs, GL_UNIFORM, "x", 1, error);
4057
4058                 GLenum props2[] = { GL_NAME_LENGTH,
4059                                                         GL_TYPE,
4060                                                         GL_ARRAY_SIZE,
4061                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
4062                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
4063                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
4064                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4065                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4066                                                         GL_REFERENCED_BY_VERTEX_SHADER,
4067                                                         GL_IS_PER_PATCH };
4068                 GLint expected2[] = { 9, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0 };
4069                 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], 10, props2, 10, expected2, error);
4070
4071                 GLenum props3[] = { GL_NAME_LENGTH,
4072                                                         GL_TYPE,
4073                                                         GL_ARRAY_SIZE,
4074                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
4075                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
4076                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
4077                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4078                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4079                                                         GL_REFERENCED_BY_VERTEX_SHADER,
4080                                                         GL_IS_PER_PATCH,
4081                                                         GL_LOCATION_INDEX };
4082                 GLint expected3[] = { 9, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0 };
4083                 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], 11, props3, 11, expected3, error);
4084
4085                 GLenum props5[] = { GL_NAME_LENGTH,
4086                                                         GL_TYPE,
4087                                                         GL_ARRAY_SIZE,
4088                                                         GL_OFFSET,
4089                                                         GL_BLOCK_INDEX,
4090                                                         GL_ARRAY_STRIDE,
4091                                                         GL_MATRIX_STRIDE,
4092                                                         GL_IS_ROW_MAJOR,
4093                                                         GL_ATOMIC_COUNTER_BUFFER_INDEX,
4094                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
4095                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
4096                                                         GL_REFERENCED_BY_VERTEX_SHADER,
4097                                                         GL_LOCATION };
4098                 GLint expected5[] = { 2, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 1 };
4099                 VerifyGetProgramResourceiv(tcs, GL_UNIFORM, indicesU["x"], 13, props5, 13, expected5, error);
4100
4101                 GLenum props6[] = { GL_NAME_LENGTH,
4102                                                         GL_BUFFER_BINDING,
4103                                                         GL_NUM_ACTIVE_VARIABLES,
4104                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
4105                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
4106                                                         GL_REFERENCED_BY_VERTEX_SHADER,
4107                                                         GL_ACTIVE_VARIABLES };
4108                 GLint expected6[] = { 13, 0, 1, 0, 1, 0, static_cast<GLint>(indicesBV["a"]) };
4109                 VerifyGetProgramResourceiv(tcs, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 7, props6, 7, expected6,
4110                                                                    error);
4111
4112                 GLenum props7[] = { GL_NAME_LENGTH,
4113                                                         GL_TYPE,
4114                                                         GL_ARRAY_SIZE,
4115                                                         GL_BLOCK_INDEX,
4116                                                         GL_ARRAY_STRIDE,
4117                                                         GL_IS_ROW_MAJOR,
4118                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
4119                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
4120                                                         GL_REFERENCED_BY_VERTEX_SHADER,
4121                                                         GL_TOP_LEVEL_ARRAY_SIZE,
4122                                                         GL_TOP_LEVEL_ARRAY_STRIDE };
4123                 GLint expected7[] = {
4124                         2, GL_FLOAT_VEC4, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 0, 1, 0, 1, 0
4125                 };
4126                 VerifyGetProgramResourceiv(tcs, GL_BUFFER_VARIABLE, indicesBV["a"], 11, props7, 11, expected7, error);
4127
4128                 glDeleteProgram(tcs);
4129                 return error;
4130         }
4131 };
4132
4133 class UniformBlockAdvanced : public SimpleShaders
4134 {
4135         virtual std::string Title()
4136         {
4137                 return "Uniform Block Advanced Test";
4138         }
4139
4140         virtual std::string ShadersDesc()
4141         {
4142                 return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
4143         }
4144
4145         virtual std::string PurposeExt()
4146         {
4147                 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param and\n"
4148                            "verify results of querying offset, strides and row order.\n";
4149         }
4150
4151         virtual std::string VertexShader()
4152         {
4153                 return "#version 430                         \n"
4154                            "in vec4 position;                    \n"
4155                            ""
4156                            "layout(row_major) uniform SimpleBlock {   \n"
4157                            "   mat4 a;                                \n"
4158                            "   vec4 b[10];                            \n"
4159                            "};                                        \n"
4160                            "void main(void)                      \n"
4161                            "{                                    \n"
4162                            "    float tmp;                       \n"
4163                            "    tmp = a[0][0] + b[0].x;          \n"
4164                            "    gl_Position = position * tmp;    \n"
4165                            "}";
4166         }
4167
4168         virtual long Run()
4169         {
4170                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4171                 glBindAttribLocation(program, 0, "position");
4172                 glBindFragDataLocation(program, 0, "color");
4173                 LinkProgram(program);
4174
4175                 long error = NO_ERROR;
4176
4177                 std::map<std::string, GLuint> indicesU;
4178                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
4179                 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
4180
4181                 GLenum props[]  = { GL_IS_ROW_MAJOR };
4182                 GLint  expected[] = { 1 };
4183                 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, props, 1, expected, error);
4184
4185                 GLenum  prop = GL_MATRIX_STRIDE;
4186                 GLsizei len;
4187                 GLint   res;
4188                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
4189                 if (res < 1)
4190                 {
4191                         m_context.getTestContext().getLog()
4192                                 << tcu::TestLog::Message
4193                                 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_MATRIX_STRIDE\n"
4194                                 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
4195                 }
4196                 prop = GL_OFFSET;
4197                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
4198                 if (res < 0)
4199                 {
4200                         m_context.getTestContext().getLog()
4201                                 << tcu::TestLog::Message << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_OFFSET\n"
4202                                 << "Expected value not less than 0, got " << res << tcu::TestLog::EndMessage;
4203                 }
4204                 prop = GL_ARRAY_STRIDE;
4205                 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, 1024, &len, &res);
4206                 if (res < 1)
4207                 {
4208                         m_context.getTestContext().getLog()
4209                                 << tcu::TestLog::Message
4210                                 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_ARRAY_STRIDE\n"
4211                                 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
4212                 }
4213
4214                 glDeleteProgram(program);
4215                 return error;
4216         }
4217 };
4218
4219 class ArrayNames : public SimpleShaders
4220 {
4221
4222         virtual std::string Title()
4223         {
4224                 return "Array Names Test";
4225         }
4226
4227         virtual std::string ShadersDesc()
4228         {
4229                 return "fallthrough fragment shader and a vertex shader with array of vec4 uniform used";
4230         }
4231
4232         virtual std::string PurposeExt()
4233         {
4234                 return "\n\n Purpose is to verify that GetProgramResourceLocation match "
4235                            "name strings correctly.\n";
4236         }
4237
4238         virtual std::string VertexShader()
4239         {
4240                 return "#version 430                         \n"
4241                            "in vec4 position;                    \n"
4242                            ""
4243                            "uniform vec4 a[2];           \n"
4244                            ""
4245                            "void main(void)                            \n"
4246                            "{                                          \n"
4247                            "    gl_Position = position + a[0] + a[1];  \n"
4248                            "}";
4249         }
4250
4251         virtual long Run()
4252         {
4253                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4254                 glBindAttribLocation(program, 0, "position");
4255                 LinkProgram(program);
4256
4257                 long error = NO_ERROR;
4258
4259                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
4260                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0]", glGetUniformLocation(program, "a"), error);
4261                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[1]", glGetUniformLocation(program, "a[1]"), error);
4262                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[2]", -1, error);
4263                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 + 0]", -1, error);
4264                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0+0]", -1, error);
4265                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[ 0]", -1, error);
4266                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 ]", -1, error);
4267                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\n0]", -1, error);
4268                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\t0]", -1, error);
4269                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[01]", -1, error);
4270                 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[00]", -1, error);
4271
4272                 glDeleteProgram(program);
4273                 return error;
4274         }
4275 };
4276
4277 class BuffLength : public SimpleShaders
4278 {
4279
4280         virtual std::string Title()
4281         {
4282                 return "Buff Length Test";
4283         }
4284
4285         virtual std::string ShadersDesc()
4286         {
4287                 return "fallthrough fragment shader and vertex with uniform of vec4 type used";
4288         }
4289
4290         virtual std::string PurposeExt()
4291         {
4292                 return "\n\n Purpose is to verify that bufsize of GetProgramResourceName and "
4293                            "GetProgramResourceiv is respected.\n";
4294         }
4295
4296         virtual std::string VertexShader()
4297         {
4298                 return "#version 430                         \n"
4299                            "in vec4 position;                    \n"
4300                            ""
4301                            "uniform vec4 someLongName;           \n"
4302                            ""
4303                            "void main(void)                            \n"
4304                            "{                                          \n"
4305                            "    gl_Position = position + someLongName; \n"
4306                            "}";
4307         }
4308
4309         virtual long Run()
4310         {
4311                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4312                 glBindAttribLocation(program, 0, "position");
4313                 LinkProgram(program);
4314
4315                 long error = NO_ERROR;
4316
4317                 GLuint  index = glGetProgramResourceIndex(program, GL_UNIFORM, "someLongName");
4318                 GLsizei length;
4319                 GLchar  buff[3] = { 'a', 'b', 'c' };
4320                 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, NULL);
4321                 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, buff);
4322                 if (buff[0] != 'a' || buff[1] != 'b' || buff[2] != 'c')
4323                 {
4324                         m_context.getTestContext().getLog()
4325                                 << tcu::TestLog::Message << "ERROR: buff has changed" << tcu::TestLog::EndMessage;
4326                         error = ERROR;
4327                 }
4328                 glGetProgramResourceName(program, GL_UNIFORM, index, 2, &length, buff);
4329                 if (buff[0] != 's' || buff[1] != '\0' || buff[2] != 'c')
4330                 {
4331                         m_context.getTestContext().getLog()
4332                                 << tcu::TestLog::Message << "ERROR: buff different then expected" << tcu::TestLog::EndMessage;
4333                         error = ERROR;
4334                 }
4335                 if (length != 1)
4336                 {
4337                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 1, got "
4338                                                                                                 << length << tcu::TestLog::EndMessage;
4339                         error = ERROR;
4340                 }
4341
4342                 GLint  params[3] = { 1, 2, 3 };
4343                 GLenum props[]   = { GL_NAME_LENGTH,
4344                                                    GL_TYPE,
4345                                                    GL_ARRAY_SIZE,
4346                                                    GL_OFFSET,
4347                                                    GL_BLOCK_INDEX,
4348                                                    GL_ARRAY_STRIDE,
4349                                                    GL_MATRIX_STRIDE,
4350                                                    GL_IS_ROW_MAJOR,
4351                                                    GL_ATOMIC_COUNTER_BUFFER_INDEX,
4352                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
4353                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
4354                                                    GL_REFERENCED_BY_VERTEX_SHADER,
4355                                                    GL_LOCATION };
4356                 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, NULL);
4357                 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, params);
4358                 if (params[0] != 1 || params[1] != 2 || params[2] != 3)
4359                 {
4360                         m_context.getTestContext().getLog()
4361                                 << tcu::TestLog::Message << "ERROR: params has changed" << tcu::TestLog::EndMessage;
4362                         error = ERROR;
4363                 }
4364                 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 2, &length, params);
4365                 if (params[0] != 13 || params[1] != GL_FLOAT_VEC4 || params[2] != 3)
4366                 {
4367                         m_context.getTestContext().getLog()
4368                                 << tcu::TestLog::Message << "ERROR: params has incorrect values" << tcu::TestLog::EndMessage;
4369                         error = ERROR;
4370                 }
4371                 if (length != 2)
4372                 {
4373                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 2, got "
4374                                                                                                 << length << tcu::TestLog::EndMessage;
4375                         error = ERROR;
4376                 }
4377
4378                 glDeleteProgram(program);
4379                 return error;
4380         }
4381 };
4382
4383 class NoLocations : public SimpleShaders
4384 {
4385
4386         virtual std::string Title()
4387         {
4388                 return "No Locations Test";
4389         }
4390
4391         virtual std::string ShadersDesc()
4392         {
4393                 return "fragment and vertex shaders with no locations set";
4394         }
4395
4396         virtual std::string VertexShader()
4397         {
4398                 return "#version 430                         \n"
4399                            "in vec4 a;                           \n"
4400                            "in vec4 b;                           \n"
4401                            "in vec4 c[1];                        \n"
4402                            "in vec4 d;                           \n"
4403                            "void main(void)                      \n"
4404                            "{                                    \n"
4405                            "    gl_Position = a + b + c[0] + d;  \n"
4406                            "}";
4407         }
4408
4409         virtual std::string FragmentShader()
4410         {
4411                 return "#version 430                   \n"
4412                            "out vec4 a;                    \n"
4413                            "out vec4 b;                    \n"
4414                            "out vec4 c;                    \n"
4415                            "out vec4 d[1];                 \n"
4416                            "void main() {                  \n"
4417                            "    a = vec4(0, 1, 0, 1);      \n"
4418                            "    b = vec4(0, 1, 0, 1);      \n"
4419                            "    c = vec4(0, 1, 0, 1);      \n"
4420                            "    d[0] = vec4(0, 1, 0, 1);   \n"
4421                            "}";
4422         }
4423
4424         virtual long Run()
4425         {
4426                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4427                 glBindAttribLocation(program, 0, "position");
4428                 glLinkProgram(program);
4429
4430                 long error = NO_ERROR;
4431
4432                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 4, error);
4433                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 5, error);
4434                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 4, error);
4435                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
4436
4437                 std::map<std::string, GLuint> indicesI;
4438                 std::map<std::string, GLuint> indicesO;
4439                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "a", error);
4440                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "b", error);
4441                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "c", error);
4442                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "d", error);
4443                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "a", error);
4444                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "b", error);
4445                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "c", error);
4446                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "d[0]", error);
4447
4448                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["a"], "a", error);
4449                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["b"], "b", error);
4450                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["c"], "c[0]", error);
4451                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["d"], "d", error);
4452                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["a"], "a", error);
4453                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
4454                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["c"], "c", error);
4455                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], "d[0]", error);
4456
4457                 std::map<std::string, GLint> locationsI;
4458                 std::map<std::string, GLint> locationsO;
4459                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "a", error);
4460                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "b", error);
4461                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "c", error);
4462                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "d", error);
4463                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "a", error);
4464                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "b", error);
4465                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "c", error);
4466                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "d[0]", error);
4467
4468                 GLenum props[] = { GL_NAME_LENGTH,
4469                                                    GL_TYPE,
4470                                                    GL_ARRAY_SIZE,
4471                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
4472                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
4473                                                    GL_REFERENCED_BY_VERTEX_SHADER };
4474                 GLint expected[] = { 2, GL_FLOAT_VEC4, 1, 0, 0, 1 };
4475                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["a"], 6, props, 6, expected, error);
4476                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["b"], 6, props, 6, expected, error);
4477                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["d"], 6, props, 6, expected, error);
4478                 GLint expected2[] = { 5, GL_FLOAT_VEC4, 1, 0, 0, 1 };
4479                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["c"], 6, props, 6, expected2, error);
4480                 GLint expected3[] = { 2, GL_FLOAT_VEC4, 1, 0, 1, 0 };
4481                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["a"], 6, props, 6, expected3, error);
4482                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["b"], 6, props, 6, expected3, error);
4483                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["c"], 6, props, 6, expected3, error);
4484                 GLint expected4[] = { 5, GL_FLOAT_VEC4, 1, 0, 1, 0 };
4485                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], 6, props, 6, expected4, error);
4486
4487                 glDeleteProgram(program);
4488                 return error;
4489         }
4490 };
4491
4492 class ComputeShaderTest : public PIQBase
4493 {
4494         virtual std::string Title()
4495         {
4496                 return "Compute Shader Test";
4497         }
4498
4499         virtual std::string ShadersDesc()
4500         {
4501                 return "compute shader";
4502         }
4503
4504         virtual std::string ComputeShader()
4505         {
4506                 return "layout(local_size_x = 1, local_size_y = 1) in; \n"
4507                            "layout(std430) buffer Output {                 \n"
4508                            "   vec4 data[];                                \n"
4509                            "} g_out;                                       \n"
4510                            ""
4511                            "void main() {                                   \n"
4512                            "   g_out.data[0] = vec4(1.0, 2.0, 3.0, 4.0);    \n"
4513                            "   g_out.data[100] = vec4(1.0, 2.0, 3.0, 4.0);  \n"
4514                            "}";
4515         }
4516
4517         GLuint CreateComputeProgram(const std::string& cs)
4518         {
4519                 const GLuint p = glCreateProgram();
4520
4521                 const char* const kGLSLVer = "#version 430  core \n";
4522
4523                 if (!cs.empty())
4524                 {
4525                         const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
4526                         glAttachShader(p, sh);
4527                         glDeleteShader(sh);
4528                         const char* const src[2] = { kGLSLVer, cs.c_str() };
4529                         glShaderSource(sh, 2, src, NULL);
4530                         glCompileShader(sh);
4531                 }
4532
4533                 return p;
4534         }
4535
4536         bool CheckProgram(GLuint program, bool* compile_error = NULL)
4537         {
4538                 GLint compile_status = GL_TRUE;
4539                 GLint status;
4540                 glGetProgramiv(program, GL_LINK_STATUS, &status);
4541
4542                 if (status == GL_FALSE)
4543                 {
4544                         GLint attached_shaders;
4545                         glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
4546
4547                         if (attached_shaders > 0)
4548                         {
4549                                 std::vector<GLuint> shaders(attached_shaders);
4550                                 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
4551
4552                                 for (GLint i = 0; i < attached_shaders; ++i)
4553                                 {
4554                                         GLenum type;
4555                                         glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
4556                                         switch (type)
4557                                         {
4558                                         case GL_VERTEX_SHADER:
4559                                                 m_context.getTestContext().getLog()
4560                                                         << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
4561                                                 break;
4562                                         case GL_TESS_CONTROL_SHADER:
4563                                                 m_context.getTestContext().getLog()
4564                                                         << tcu::TestLog::Message << "*** Tessellation Control Shader ***"
4565                                                         << tcu::TestLog::EndMessage;
4566                                                 break;
4567                                         case GL_TESS_EVALUATION_SHADER:
4568                                                 m_context.getTestContext().getLog()
4569                                                         << tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
4570                                                         << tcu::TestLog::EndMessage;
4571                                                 break;
4572                                         case GL_GEOMETRY_SHADER:
4573                                                 m_context.getTestContext().getLog()
4574                                                         << tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
4575                                                 break;
4576                                         case GL_FRAGMENT_SHADER:
4577                                                 m_context.getTestContext().getLog()
4578                                                         << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
4579                                                 break;
4580                                         case GL_COMPUTE_SHADER:
4581                                                 m_context.getTestContext().getLog()
4582                                                         << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
4583                                                 break;
4584                                         default:
4585                                                 m_context.getTestContext().getLog()
4586                                                         << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
4587                                         }
4588
4589                                         GLint res;
4590                                         glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
4591                                         if (res != GL_TRUE)
4592                                                 compile_status = res;
4593
4594                                         // shader source
4595                                         GLint length;
4596                                         glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
4597                                         if (length > 0)
4598                                         {
4599                                                 std::vector<GLchar> source(length);
4600                                                 glGetShaderSource(shaders[i], length, NULL, &source[0]);
4601                                                 m_context.getTestContext().getLog()
4602                                                         << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
4603                                         }
4604
4605                                         // shader info log
4606                                         glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
4607                                         if (length > 0)
4608                                         {
4609                                                 std::vector<GLchar> log(length);
4610                                                 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
4611                                                 m_context.getTestContext().getLog()
4612                                                         << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
4613                                         }
4614                                 }
4615                         }
4616
4617                         // program info log
4618                         GLint length;
4619                         glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
4620                         if (length > 0)
4621                         {
4622                                 std::vector<GLchar> log(length);
4623                                 glGetProgramInfoLog(program, length, NULL, &log[0]);
4624                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
4625                         }
4626                 }
4627
4628                 if (compile_error)
4629                         *compile_error = (compile_status == GL_TRUE ? false : true);
4630                 if (compile_status != GL_TRUE)
4631                         return false;
4632                 return status == GL_TRUE ? true : false;
4633         }
4634
4635         virtual void inline VerifyCompute(GLuint program, long& error)
4636         {
4637                 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 15, error);
4638                 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, 1, error);
4639                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
4640                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 7, error);
4641                 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 1, error);
4642
4643                 std::map<std::string, GLuint> indicesSSB;
4644                 std::map<std::string, GLuint> indicesBV;
4645                 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Output", error);
4646                 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "Output.data", error);
4647
4648                 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], "Output", error);
4649                 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], "Output.data[0]", error);
4650
4651                 GLenum props3[] = { GL_NAME_LENGTH,
4652                                                         GL_BUFFER_BINDING,
4653                                                         GL_NUM_ACTIVE_VARIABLES,
4654                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
4655                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
4656                                                         GL_REFERENCED_BY_VERTEX_SHADER,
4657                                                         GL_ACTIVE_VARIABLES };
4658                 GLint expected3[] = { 7, 0, 1, 1, 0, 0, static_cast<GLint>(indicesBV["Outputa.data"]) };
4659                 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], 7, props3, 7, expected3,
4660                                                                    error);
4661
4662                 GLenum props4[] = { GL_NAME_LENGTH,
4663                                                         GL_TYPE,
4664                                                         GL_ARRAY_SIZE,
4665                                                         GL_BLOCK_INDEX,
4666                                                         GL_IS_ROW_MAJOR,
4667                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
4668                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
4669                                                         GL_REFERENCED_BY_VERTEX_SHADER,
4670                                                         GL_TOP_LEVEL_ARRAY_SIZE };
4671                 GLint expected4[] = { 15, GL_FLOAT_VEC4, 0, static_cast<GLint>(indicesSSB["Output"]), 0, 1, 0, 0, 1 };
4672                 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], 9, props4, 9, expected4,
4673                                                                    error);
4674         }
4675
4676         virtual long Run()
4677         {
4678                 GLuint program = CreateComputeProgram(ComputeShader());
4679                 glLinkProgram(program);
4680                 if (!CheckProgram(program))
4681                 {
4682                         glDeleteProgram(program);
4683                         return ERROR;
4684                 }
4685                 glUseProgram(program);
4686
4687                 long error = NO_ERROR;
4688
4689                 VerifyCompute(program, error);
4690
4691                 glDeleteProgram(program);
4692                 return error;
4693         }
4694 };
4695
4696 class QueryNotUsed : public SimpleShaders
4697 {
4698
4699         virtual std::string Title()
4700         {
4701                 return "Query Not Used Test";
4702         }
4703
4704         virtual std::string PassCriteria()
4705         {
4706                 return "Data from queries matches the not used program.";
4707         }
4708
4709         virtual std::string Purpose()
4710         {
4711                 return "Verify that program parameter works correctly and proper program is queried when different program is "
4712                            "used.";
4713         }
4714
4715         virtual std::string Method()
4716         {
4717                 return "Create 2 programs, use one of them and query the other, verify the results.";
4718         }
4719
4720         virtual std::string VertexShader2()
4721         {
4722                 return "#version 430                         \n"
4723                            "in vec4 p;                           \n"
4724                            "void main(void)                      \n"
4725                            "{                                    \n"
4726                            "    gl_Position = p;                 \n"
4727                            "}";
4728         }
4729
4730         virtual std::string FragmentShader2()
4731         {
4732                 return "#version 430                   \n"
4733                            "out vec4 c;                    \n"
4734                            "void main() {                  \n"
4735                            "    c = vec4(0, 1, 0, 1);      \n"
4736                            "}";
4737         }
4738
4739         virtual long Run()
4740         {
4741                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4742                 glBindAttribLocation(program, 0, "position");
4743                 glBindFragDataLocation(program, 0, "color");
4744                 LinkProgram(program);
4745
4746                 GLuint program2 = CreateProgram(VertexShader2().c_str(), FragmentShader2().c_str(), false);
4747                 glBindAttribLocation(program, 0, "p");
4748                 glBindFragDataLocation(program, 0, "c");
4749                 LinkProgram(program2);
4750                 glUseProgram(program2);
4751
4752                 long error = NO_ERROR;
4753
4754                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
4755                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
4756                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
4757                 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
4758
4759                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
4760                 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
4761
4762                 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
4763                 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
4764
4765                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
4766                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
4767
4768                 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
4769
4770                 GLenum props[] = { GL_NAME_LENGTH,
4771                                                    GL_TYPE,
4772                                                    GL_ARRAY_SIZE,
4773                                                    GL_REFERENCED_BY_COMPUTE_SHADER,
4774                                                    GL_REFERENCED_BY_FRAGMENT_SHADER,
4775                                                    GL_REFERENCED_BY_GEOMETRY_SHADER,
4776                                                    GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4777                                                    GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4778                                                    GL_REFERENCED_BY_VERTEX_SHADER,
4779                                                    GL_LOCATION,
4780                                                    GL_IS_PER_PATCH };
4781                 GLint expected[] = { 9, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, 0 };
4782                 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 11, props, 11, expected, error);
4783
4784                 GLenum props2[] = { GL_NAME_LENGTH,
4785                                                         GL_TYPE,
4786                                                         GL_ARRAY_SIZE,
4787                                                         GL_REFERENCED_BY_COMPUTE_SHADER,
4788                                                         GL_REFERENCED_BY_FRAGMENT_SHADER,
4789                                                         GL_REFERENCED_BY_GEOMETRY_SHADER,
4790                                                         GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4791                                                         GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4792                                                         GL_REFERENCED_BY_VERTEX_SHADER,
4793                                                         GL_LOCATION,
4794                                                         GL_IS_PER_PATCH,
4795                                                         GL_LOCATION_INDEX };
4796                 GLint expected2[] = { 6, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
4797                 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 12, props2, 12, expected2, error);
4798
4799                 glDeleteProgram(program);
4800                 glDeleteProgram(program2);
4801                 return error;
4802         }
4803 };
4804
4805 class RelinkFailure : public SimpleShaders
4806 {
4807
4808         virtual std::string Title()
4809         {
4810                 return "Relink Failure Test";
4811         }
4812
4813         virtual std::string PassCriteria()
4814         {
4815                 return "INVALID_OPERATION is generated when asking for locations after failed link.";
4816         }
4817
4818         virtual std::string Purpose()
4819         {
4820                 return "Verify that queries behave correctly after failed relink of a program.";
4821         }
4822
4823         virtual std::string Method()
4824         {
4825                 return "Create a program, use it, relink with failure and then verify that INVALID_OPERATION is returned when "
4826                            "asking for locations.";
4827         }
4828
4829         virtual std::string VertexShader()
4830         {
4831                 return "#version 430                                  \n"
4832                            "in vec4 position;                             \n"
4833                            "in vec3 pos;                                  \n"
4834                            "void main(void)                               \n"
4835                            "{                                             \n"
4836                            "    gl_Position = position + vec4(pos, 1);    \n"
4837                            "}";
4838         }
4839
4840         virtual long Run()
4841         {
4842                 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4843                 glBindAttribLocation(program, 0, "position");
4844                 glBindAttribLocation(program, 1, "pos");
4845                 glBindFragDataLocation(program, 0, "color");
4846                 LinkProgram(program);
4847
4848                 long error = NO_ERROR;
4849
4850                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", 1, error);
4851                 glUseProgram(program);
4852
4853                 tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
4854                                                    tcu::Vec4(1, -1, 0, 1) };
4855                 GLuint vao, vbuf;
4856                 glGenVertexArrays(1, &vao);
4857                 glBindVertexArray(vao);
4858                 glGenBuffers(1, &vbuf);
4859                 glBindBuffer(GL_ARRAY_BUFFER, vbuf);
4860                 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
4861                 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
4862                 glEnableVertexAttribArray(0);
4863                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4864
4865                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4866                 glDisableVertexAttribArray(0);
4867                 glDeleteVertexArrays(1, &vao);
4868                 glBindBuffer(GL_ARRAY_BUFFER, 0);
4869                 glDeleteBuffers(1, &vbuf);
4870
4871                 glBindAttribLocation(program, 0, "pos");
4872                 glBindAttribLocation(program, 0, "position");
4873                 const char* varyings[2] = { "q", "z" };
4874                 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
4875                 LinkProgram(program);
4876
4877                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
4878                 ExpectError(GL_INVALID_OPERATION, error);
4879                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", -1, error);
4880                 ExpectError(GL_INVALID_OPERATION, error);
4881                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
4882                 ExpectError(GL_INVALID_OPERATION, error);
4883
4884                 glDeleteProgram(program);
4885                 return error;
4886         }
4887 };
4888
4889 class LinkFailure : public SimpleShaders
4890 {
4891
4892         virtual std::string Title()
4893         {
4894                 return "Link Failure Test";
4895         }
4896
4897         virtual std::string PassCriteria()
4898         {
4899                 return "INVALID_OPERATION is generated when asking for locations after failed link.";
4900         }
4901
4902         virtual std::string Purpose()
4903         {
4904                 return "Verify that queries behave correctly after failed relink of a program with changed sources.";
4905         }
4906
4907         virtual std::string Method()
4908         {
4909                 return "Create a program, use it, relink with failure using different sources and then \n"
4910                            "verify that INVALID_OPERATION is returned when asking for locations.";
4911         }
4912
4913         virtual const char* VertexShader_prop()
4914         {
4915                 return "#version 430                         \n"
4916                            "in vec4 posit;                       \n"
4917                            "in vec4 p;                           \n"
4918                            "void main(void)                      \n"
4919                            "{                                    \n"
4920                            "    gl_Position = p + posit;         \n"
4921                            "}";
4922         }
4923
4924         virtual const char* FragmentShader_prop()
4925         {
4926                 return "#version 430                   \n"
4927                            "out vec4 color;                \n"
4928                            "void main() {                  \n"
4929                            "    color = vec4(0, 1, 0, 1);  \n"
4930                            "}";
4931         }
4932
4933         virtual const char* VertexShader_fail()
4934         {
4935                 return "#version 430                         \n"
4936                            "in vec4 position;                    \n"
4937                            "void main(void)                      \n"
4938                            "{                                    \n"
4939                            "    gl_Position = position;          \n"
4940                            "}";
4941         }
4942
4943         virtual long Run()
4944         {
4945                 const GLuint program = glCreateProgram();
4946                 const char*  src_vs  = VertexShader_prop();
4947                 const char*  src_fs  = FragmentShader_prop();
4948                 const char*  src_vsh = VertexShader_fail();
4949
4950                 GLuint sh1 = glCreateShader(GL_VERTEX_SHADER);
4951                 glAttachShader(program, sh1);
4952                 glDeleteShader(sh1);
4953                 glShaderSource(sh1, 1, &src_vs, NULL);
4954                 glCompileShader(sh1);
4955
4956                 GLuint sh2 = glCreateShader(GL_FRAGMENT_SHADER);
4957                 glAttachShader(program, sh2);
4958                 glDeleteShader(sh2);
4959                 glShaderSource(sh2, 1, &src_fs, NULL);
4960                 glCompileShader(sh2);
4961
4962                 glBindAttribLocation(program, 0, "p");
4963                 glBindAttribLocation(program, 1, "posit");
4964                 glBindFragDataLocation(program, 0, "color");
4965                 LinkProgram(program);
4966
4967                 long error = NO_ERROR;
4968
4969                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "posit", 1, error);
4970                 glUseProgram(program);
4971
4972                 tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
4973                                                    tcu::Vec4(1, -1, 0, 1) };
4974                 GLuint vao, vbuf;
4975                 glGenVertexArrays(1, &vao);
4976                 glBindVertexArray(vao);
4977                 glGenBuffers(1, &vbuf);
4978                 glBindBuffer(GL_ARRAY_BUFFER, vbuf);
4979                 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
4980                 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
4981                 glEnableVertexAttribArray(0);
4982                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4983
4984                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4985                 glDisableVertexAttribArray(0);
4986                 glDeleteVertexArrays(1, &vao);
4987                 glBindBuffer(GL_ARRAY_BUFFER, 0);
4988                 glDeleteBuffers(1, &vbuf);
4989
4990                 glDetachShader(program, sh1);
4991                 GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
4992                 glAttachShader(program, vsh);
4993                 glDeleteShader(vsh);
4994                 glShaderSource(vsh, 1, &src_vsh, NULL);
4995                 glCompileShader(vsh);
4996                 const char* varyings[2] = { "q", "z" };
4997                 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
4998                 LinkProgram(program);
4999
5000                 GLint res;
5001                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
5002                 ExpectError(GL_INVALID_OPERATION, error);
5003                 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
5004                 if (res != 0 && res != 1)
5005                 {
5006                         m_context.getTestContext().getLog()
5007                                 << tcu::TestLog::Message << "Error, expected 0 or 1 active resources, got: " << res
5008                                 << tcu::TestLog::EndMessage;
5009                         error = ERROR;
5010                 }
5011                 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, &res);
5012                 if (res != 0 && res != 9)
5013                 {
5014                         m_context.getTestContext().getLog()
5015                                 << tcu::TestLog::Message << "Error, expected 1 or 9 GL_MAX_NAME_LENGTH, got: " << res
5016                                 << tcu::TestLog::EndMessage;
5017                         error = ERROR;
5018                 }
5019                 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
5020                 ExpectError(GL_INVALID_OPERATION, error);
5021
5022                 glDeleteProgram(program);
5023                 return error;
5024         }
5025 };
5026
5027 } // anonymous namespace
5028
5029 ProgramInterfaceQueryTests::ProgramInterfaceQueryTests(deqp::Context& context)
5030         : TestCaseGroup(context, "program_interface_query", "")
5031 {
5032 }
5033
5034 ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests(void)
5035 {
5036 }
5037
5038 void ProgramInterfaceQueryTests::init()
5039 {
5040         using namespace deqp;
5041         addChild(new TestSubcase(m_context, "empty-shaders", TestSubcase::Create<NoShaders>));
5042         addChild(new TestSubcase(m_context, "simple-shaders", TestSubcase::Create<SimpleShaders>));
5043         addChild(new TestSubcase(m_context, "input-types", TestSubcase::Create<InputTypes>));
5044         addChild(new TestSubcase(m_context, "input-built-in", TestSubcase::Create<InputBuiltIn>));
5045         addChild(new TestSubcase(m_context, "input-layout", TestSubcase::Create<InputLayout>));
5046         addChild(new TestSubcase(m_context, "output-types", TestSubcase::Create<OutputTypes>));
5047         addChild(new TestSubcase(m_context, "output-location-index", TestSubcase::Create<OutputLocationIndex>));
5048         addChild(new TestSubcase(m_context, "output-built-in", TestSubcase::Create<OutputBuiltIn>));
5049         addChild(new TestSubcase(m_context, "output-layout", TestSubcase::Create<OutputLayout>));
5050         addChild(new TestSubcase(m_context, "output-layout-index", TestSubcase::Create<OutputLayoutIndex>));
5051         addChild(new TestSubcase(m_context, "uniform-simple", TestSubcase::Create<UniformSimple>));
5052         addChild(new TestSubcase(m_context, "uniform-types", TestSubcase::Create<UniformTypes>));
5053         addChild(new TestSubcase(m_context, "uniform-block-types", TestSubcase::Create<UniformBlockTypes>));
5054         addChild(new TestSubcase(m_context, "transform-feedback-types", TestSubcase::Create<TransformFeedbackTypes>));
5055         addChild(new TestSubcase(m_context, "atomic-counters", TestSubcase::Create<AtomicCounterSimple>));
5056         addChild(new TestSubcase(m_context, "subroutines-vertex", TestSubcase::Create<SubroutinesVertex>));
5057         addChild(new TestSubcase(m_context, "subroutines-tess-control", TestSubcase::Create<SubroutinesTessControl>));
5058         addChild(new TestSubcase(m_context, "subroutines-tess-eval", TestSubcase::Create<SubroutinesTessEval>));
5059         addChild(new TestSubcase(m_context, "subroutines-geometry", TestSubcase::Create<SubroutinesGeometry>));
5060         addChild(new TestSubcase(m_context, "subroutines-fragment", TestSubcase::Create<SubroutinesFragment>));
5061         addChild(new TestSubcase(m_context, "subroutines-compute", TestSubcase::Create<SoubroutinesCompute>));
5062         addChild(new TestSubcase(m_context, "ssb-types", TestSubcase::Create<ShaderStorageBlock>));
5063         addChild(new TestSubcase(m_context, "transform-feedback-built-in", TestSubcase::Create<TransformFeedbackBuiltin>));
5064         addChild(new TestSubcase(m_context, "null-length", TestSubcase::Create<NullLength>));
5065         addChild(new TestSubcase(m_context, "arrays-of-arrays", TestSubcase::Create<ArraysOfArrays>));
5066         addChild(new TestSubcase(m_context, "top-level-array", TestSubcase::Create<TopLevelArray>));
5067         addChild(new TestSubcase(m_context, "separate-programs-vertex", TestSubcase::Create<SeparateProgramsVertex>));
5068         addChild(
5069                 new TestSubcase(m_context, "separate-programs-tess-control", TestSubcase::Create<SeparateProgramsTessControl>));
5070         addChild(new TestSubcase(m_context, "separate-programs-tess-eval", TestSubcase::Create<SeparateProgramsTessEval>));
5071         addChild(new TestSubcase(m_context, "separate-programs-geometry", TestSubcase::Create<SeparateProgramsGeometry>));
5072         addChild(new TestSubcase(m_context, "separate-programs-fragment", TestSubcase::Create<SeparateProgramsFragment>));
5073         addChild(new TestSubcase(m_context, "uniform-block", TestSubcase::Create<UniformBlockAdvanced>));
5074         addChild(new TestSubcase(m_context, "array-names", TestSubcase::Create<ArrayNames>));
5075         addChild(new TestSubcase(m_context, "buff-length", TestSubcase::Create<BuffLength>));
5076         addChild(new TestSubcase(m_context, "no-locations", TestSubcase::Create<NoLocations>));
5077         addChild(new TestSubcase(m_context, "query-not-used", TestSubcase::Create<QueryNotUsed>));
5078         addChild(new TestSubcase(m_context, "relink-failure", TestSubcase::Create<RelinkFailure>));
5079         addChild(new TestSubcase(m_context, "link-failure", TestSubcase::Create<LinkFailure>));
5080         addChild(new TestSubcase(m_context, "compute-shader", TestSubcase::Create<ComputeShaderTest>));
5081         addChild(new TestSubcase(m_context, "invalid-value", TestSubcase::Create<InvalidValueTest>));
5082         addChild(new TestSubcase(m_context, "invalid-operation", TestSubcase::Create<InvalidOperationTest>));
5083         addChild(new TestSubcase(m_context, "invalid-enum", TestSubcase::Create<InvalidEnumTest>));
5084 }
5085
5086 } // gl4cts namespace