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