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