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