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