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 TransformFeedbackTypesFullArrayCapture : public SimpleShaders
1672 {
Title()1673 	virtual std::string Title()
1674 	{
1675 		return "Transform Feedback Varying Types Without Element Capture";
1676 	}
1677 
ShadersDesc()1678 	virtual std::string ShadersDesc()
1679 	{
1680 		return "fallthrough fragment and vertex shaders with different types of out variables used";
1681 	}
1682 
PurposeExt()1683 	virtual std::string PurposeExt()
1684 	{
1685 		return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n";
1686 	}
1687 
VertexShader()1688 	virtual std::string VertexShader()
1689 	{
1690 		return "#version 310 es                      \n"
1691 			   "in vec4 position;                    \n"
1692 			   ""
1693 			   "flat out highp vec4 a;               \n"
1694 			   "out mediump float b[2];              \n"
1695 			   "flat out highp uvec2 c;              \n"
1696 			   "flat out highp uint d;               \n"
1697 			   "out mediump vec3 e[2];               \n"
1698 			   "flat out int f;                      \n"
1699 			   ""
1700 			   "void main(void)                      \n"
1701 			   "{                                    \n"
1702 			   "   vec4 pos;                         \n"
1703 			   "   a = vec4(1);                      \n"
1704 			   "   b[0] = 1.1;                       \n"
1705 			   "   b[1] = 1.1;                       \n"
1706 			   "   c = uvec2(1u);                    \n"
1707 			   "   d = 1u;                           \n"
1708 			   "   e[0] = vec3(1.1);                 \n"
1709 			   "   e[1] = vec3(1.1);                 \n"
1710 			   "   f = 1;                            \n"
1711 			   "   gl_Position = position;           \n"
1712 			   "}";
1713 	}
1714 
Run()1715 	virtual long Run()
1716 	{
1717 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1718 		glBindAttribLocation(program, 0, "position");
1719 		const char* varyings[5] = { "a", "b", "c", "d", "e" };
1720 		glTransformFeedbackVaryings(program, 5, varyings, GL_INTERLEAVED_ATTRIBS);
1721 		LinkProgram(program);
1722 
1723 		long error = NO_ERROR;
1724 
1725 		VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 5, error);
1726 		VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 2, error);
1727 
1728 		std::map<std::string, GLuint> indices;
1729 		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error);
1730 		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b", error);
1731 		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error);
1732 		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error);
1733 		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error);
1734 
1735 		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error);
1736 		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b"], "b", error);
1737 		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error);
1738 		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error);
1739 		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error);
1740 
1741 		GLenum props[]	= { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE };
1742 		GLint  expected[] = { 2, GL_FLOAT_VEC4, 1 };
1743 		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error);
1744 		GLint expected2[] = { 2, GL_FLOAT, 2 };
1745 		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b"], 3, props, 3, expected2, error);
1746 		GLint expected3[] = { 2, GL_UNSIGNED_INT_VEC2, 1 };
1747 		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected3, error);
1748 		GLint expected4[] = { 2, GL_UNSIGNED_INT, 1 };
1749 		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected4, error);
1750 		GLint expected5[] = { 2, GL_FLOAT_VEC3, 2 };
1751 		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected5, error);
1752 
1753 		glDeleteProgram(program);
1754 		return error;
1755 	}
1756 };
1757 
1758 class AtomicCounterSimple : public ComputeShaderTest
1759 {
1760 public:
Title()1761 	virtual std::string Title()
1762 	{
1763 		return "Atomic Counter Buffer Simple Test";
1764 	}
1765 
ShadersDesc()1766 	virtual std::string ShadersDesc()
1767 	{
1768 		return "compute shader with atomic counters used";
1769 	}
1770 
PurposeExt()1771 	virtual std::string PurposeExt()
1772 	{
1773 		return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1774 	}
1775 
Run()1776 	virtual long Run()
1777 	{
1778 
1779 		GLint max_buffer_bindings = 0;
1780 		glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings);
1781 		if (max_buffer_bindings < 6)
1782 		{
1783 			OutputNotSupported("Test requires at least 6 atomic counter buffer binding points.");
1784 			return NOT_SUPPORTED;
1785 		}
1786 
1787 		const char* const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in;  \n"
1788 									"layout(std430) buffer Output {                  \n"
1789 									"   mediump vec4 data;                           \n"
1790 									"} g_out;                                        \n"
1791 									""
1792 									"layout (binding = 1, offset = 0) uniform highp atomic_uint a;    \n"
1793 									"layout (binding = 2, offset = 0) uniform highp atomic_uint b;    \n"
1794 									"layout (binding = 2, offset = 4) uniform highp atomic_uint c;    \n"
1795 									"layout (binding = 5, offset = 0) uniform highp atomic_uint d[3]; \n"
1796 									"layout (binding = 5, offset = 12) uniform highp atomic_uint e;   \n"
1797 									""
1798 									"void main() {                                                         \n"
1799 									"   uint x = atomicCounterIncrement(d[0]) + atomicCounterIncrement(a); \n"
1800 									"   uint y = atomicCounterIncrement(d[1]) + atomicCounterIncrement(b); \n"
1801 									"   uint z = atomicCounterIncrement(d[2]) + atomicCounterIncrement(c); \n"
1802 									"   uint w = atomicCounterIncrement(e);                                \n"
1803 									"   g_out.data = vec4(float(x), float(y), float(z), float(w));         \n"
1804 									"}";
1805 
1806 		GLuint program = CreateComputeProgram(glsl_cs);
1807 		glLinkProgram(program);
1808 		if (!CheckProgram(program))
1809 		{
1810 			glDeleteProgram(program);
1811 			return ERROR;
1812 		}
1813 		glUseProgram(program);
1814 
1815 		long error = NO_ERROR;
1816 
1817 		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 3, error);
1818 		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 2, error);
1819 
1820 		std::map<std::string, GLuint> indicesU;
1821 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1822 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1823 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1824 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "d", error);
1825 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "e", error);
1826 
1827 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1828 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1829 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1830 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["d"], "d[0]", error);
1831 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["e"], "e", error);
1832 
1833 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1834 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1835 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1836 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", -1, error);
1837 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", -1, error);
1838 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[0]", -1, error);
1839 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[1]", -1, error);
1840 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[2]", -1, error);
1841 
1842 		GLenum		  prop	= GL_ATOMIC_COUNTER_BUFFER_INDEX;
1843 		const GLsizei bufSize = 1000;
1844 		GLsizei		  length;
1845 		GLint		  res;
1846 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1847 
1848 		GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES, GL_ACTIVE_VARIABLES };
1849 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1850 		GLint expected[] = { 1, 4, 1, static_cast<GLint>(indicesU["a"]) };
1851 		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 4, props, 4, expected, error);
1852 
1853 		GLenum props2[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES };
1854 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1855 		GLint expected2[] = { 2, 8, 2 };
1856 		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1857 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["c"], 1, &prop, bufSize, &length, &res);
1858 		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1859 
1860 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1861 		GLint expected3[] = { 5, 16, 2 };
1862 		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1863 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["e"], 1, &prop, bufSize, &length, &res);
1864 		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1865 
1866 		GLenum			 prop2 = GL_ACTIVE_VARIABLES;
1867 		GLint			 param[bufSize];
1868 		std::set<GLuint> exp;
1869 		exp.insert(indicesU["b"]);
1870 		exp.insert(indicesU["c"]);
1871 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1872 		glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
1873 		for (int i = 0; i < length; ++i)
1874 		{
1875 			if (exp.find(param[i]) == exp.end() || length != 2)
1876 			{
1877 				m_context.getTestContext().getLog()
1878 					<< tcu::TestLog::Message << "Length: " << length
1879 					<< "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
1880 					<< tcu::TestLog::EndMessage;
1881 				glDeleteProgram(program);
1882 				return ERROR;
1883 			}
1884 		}
1885 		std::set<GLuint> exp2;
1886 		GLint			 param2[bufSize];
1887 		exp2.insert(indicesU["d"]);
1888 		exp2.insert(indicesU["e"]);
1889 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1890 		glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param2);
1891 		for (int i = 0; i < length; ++i)
1892 		{
1893 			if (exp2.find(param2[i]) == exp2.end() || length != 2)
1894 			{
1895 				m_context.getTestContext().getLog()
1896 					<< tcu::TestLog::Message << "Length: " << length
1897 					<< "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param2[i]
1898 					<< tcu::TestLog::EndMessage;
1899 				glDeleteProgram(program);
1900 				return ERROR;
1901 			}
1902 		}
1903 
1904 		glDeleteProgram(program);
1905 		return error;
1906 	}
1907 };
1908 
1909 class AtomicCounterSimpleOneBuffer : public ComputeShaderTest
1910 {
1911 public:
Title()1912 	virtual std::string Title()
1913 	{
1914 		return "Atomic Counter Buffer Simple One Buffer Test";
1915 	}
1916 
ShadersDesc()1917 	virtual std::string ShadersDesc()
1918 	{
1919 		return "compute shader with atomic counters used";
1920 	}
1921 
PurposeExt()1922 	virtual std::string PurposeExt()
1923 	{
1924 		return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1925 	}
1926 
Run()1927 	virtual long Run()
1928 	{
1929 
1930 		GLint max_buffer_bindings = 0;
1931 		glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings);
1932 		if (max_buffer_bindings < 3)
1933 		{
1934 			OutputNotSupported("Test requires at least 3 atomic counter buffer binding points.");
1935 			return NOT_SUPPORTED;
1936 		}
1937 
1938 		const char* const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in;  \n"
1939 									"layout(std430) buffer Output {                  \n"
1940 									"   mediump vec4 data;                           \n"
1941 									"} g_out;                                        \n"
1942 									""
1943 									"layout (binding = 0, offset = 0) uniform highp atomic_uint a;    \n"
1944 									"layout (binding = 0, offset = 4) uniform highp atomic_uint b[3]; \n"
1945 									"layout (binding = 0, offset = 16) uniform highp atomic_uint c;   \n"
1946 									""
1947 									"void main() {                                                         \n"
1948 									"   uint x = atomicCounterIncrement(b[0]) + atomicCounterIncrement(a); \n"
1949 									"   uint y = atomicCounterIncrement(b[1]) + atomicCounterIncrement(a); \n"
1950 									"   uint z = atomicCounterIncrement(b[2]) + atomicCounterIncrement(a); \n"
1951 									"   uint w = atomicCounterIncrement(c);                                \n"
1952 									"   g_out.data = vec4(float(x), float(y), float(z), float(w));         \n"
1953 									"}";
1954 
1955 		GLuint program = CreateComputeProgram(glsl_cs);
1956 		glLinkProgram(program);
1957 		if (!CheckProgram(program))
1958 		{
1959 			glDeleteProgram(program);
1960 			return ERROR;
1961 		}
1962 		glUseProgram(program);
1963 
1964 		long error = NO_ERROR;
1965 
1966 		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 1, error);
1967 		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 3, error);
1968 
1969 		std::map<std::string, GLuint> indicesU;
1970 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1971 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1972 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1973 
1974 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1975 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b[0]", error);
1976 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1977 
1978 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1979 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1980 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1981 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[0]", -1, error);
1982 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[1]", -1, error);
1983 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[2]", -1, error);
1984 
1985 		GLenum		  prop	= GL_ATOMIC_COUNTER_BUFFER_INDEX;
1986 		const GLsizei bufSize = 1000;
1987 		GLsizei		  length;
1988 		GLint		  res;
1989 
1990 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1991 		if (res != 0)
1992 		{
1993 			m_context.getTestContext().getLog()
1994 				<< tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage;
1995 			glDeleteProgram(program);
1996 			return ERROR;
1997 		}
1998 
1999 		GLenum props[]	= { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES };
2000 		GLint  expected[] = { 0, 20, 3 };
2001 		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props, 3, expected, error);
2002 
2003 		GLenum			 prop2 = GL_ACTIVE_VARIABLES;
2004 		GLint			 param[bufSize];
2005 		std::set<GLuint> exp;
2006 		exp.insert(indicesU["a"]);
2007 		exp.insert(indicesU["b"]);
2008 		exp.insert(indicesU["c"]);
2009 
2010 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
2011 		if (res != 0)
2012 		{
2013 			m_context.getTestContext().getLog()
2014 				<< tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage;
2015 			glDeleteProgram(program);
2016 			return ERROR;
2017 		}
2018 
2019 		glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
2020 		for (int i = 0; i < length; ++i)
2021 		{
2022 			if (exp.find(param[i]) == exp.end() || length != 3)
2023 			{
2024 				m_context.getTestContext().getLog()
2025 					<< tcu::TestLog::Message << "Length: " << length
2026 					<< "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
2027 					<< tcu::TestLog::EndMessage;
2028 				glDeleteProgram(program);
2029 				return ERROR;
2030 			}
2031 		}
2032 
2033 		glDeleteProgram(program);
2034 		return error;
2035 	}
2036 };
2037 
2038 class InvalidValueTest : public SimpleShaders
2039 {
Title()2040 	virtual std::string Title()
2041 	{
2042 		return "Invalid Value Test";
2043 	}
2044 
PassCriteria()2045 	virtual std::string PassCriteria()
2046 	{
2047 		return "GL_INVALID_VALUE error is generated after every function call.";
2048 	}
2049 
Purpose()2050 	virtual std::string Purpose()
2051 	{
2052 		return "Verify that wrong use of functions generates GL_INVALID_VALUE as described in spec.";
2053 	}
2054 
Method()2055 	virtual std::string Method()
2056 	{
2057 		return "Call functions with invalid values and check if GL_INVALID_VALUE was generated.";
2058 	}
2059 
Run()2060 	virtual long Run()
2061 	{
2062 		long error = NO_ERROR;
2063 
2064 		GLint   res;
2065 		GLsizei len		  = 0;
2066 		GLchar  name[100] = { '\0' };
2067 		GLenum  props[1]  = { GL_NAME_LENGTH };
2068 
2069 		m_context.getTestContext().getLog()
2070 			<< tcu::TestLog::Message << "Case 1: <program> not a name of shader/program object"
2071 			<< tcu::TestLog::EndMessage;
2072 		glGetProgramInterfaceiv(1337u, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2073 		ExpectError(GL_INVALID_VALUE, error);
2074 		glGetProgramResourceIndex(31337u, GL_PROGRAM_INPUT, "pie");
2075 		ExpectError(GL_INVALID_VALUE, error);
2076 		glGetProgramResourceName(1337u, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2077 		ExpectError(GL_INVALID_VALUE, error);
2078 		glGetProgramResourceiv(1337u, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2079 		ExpectError(GL_INVALID_VALUE, error);
2080 		glGetProgramResourceLocation(1337u, GL_PROGRAM_INPUT, "pie");
2081 		ExpectError(GL_INVALID_VALUE, error);
2082 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage;
2083 
2084 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2085 		glBindAttribLocation(program, 0, "position");
2086 		LinkProgram(program);
2087 
2088 		m_context.getTestContext().getLog()
2089 			<< tcu::TestLog::Message
2090 			<< "Case 2: <index> is greater than the number of the active resources in GetProgramResourceName"
2091 			<< tcu::TestLog::EndMessage;
2092 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage;
2093 		glGetProgramResourceName(program, GL_PROGRAM_INPUT, 3000, 1024, &len, name);
2094 		ExpectError(GL_INVALID_VALUE, error);
2095 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2: finished" << tcu::TestLog::EndMessage;
2096 
2097 		m_context.getTestContext().getLog()
2098 			<< tcu::TestLog::Message << "Case 3: <propCount> is zero in GetProgramResourceiv"
2099 			<< tcu::TestLog::EndMessage;
2100 		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 0, props, 1024, &len, &res);
2101 		ExpectError(GL_INVALID_VALUE, error);
2102 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3: finished" << tcu::TestLog::EndMessage;
2103 
2104 		std::string str = "position";
2105 		glGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, -100, NULL, const_cast<char*>(str.c_str()));
2106 		ExpectError(GL_INVALID_VALUE, error);
2107 		GLenum prop = GL_NAME_LENGTH;
2108 		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, &prop, -100, &len, &res);
2109 		ExpectError(GL_INVALID_VALUE, error);
2110 
2111 		glDeleteProgram(program);
2112 		return error;
2113 	}
2114 };
2115 
2116 class InvalidEnumTest : public SimpleShaders
2117 {
Title()2118 	virtual std::string Title()
2119 	{
2120 		return "Invalid Enum Test";
2121 	}
2122 
PassCriteria()2123 	virtual std::string PassCriteria()
2124 	{
2125 		return "GL_INVALID_ENUM error is generated after every function call.";
2126 	}
2127 
Purpose()2128 	virtual std::string Purpose()
2129 	{
2130 		return "Verify that wrong use of functions generates GL_INVALID_ENUM as described in spec.";
2131 	}
2132 
Method()2133 	virtual std::string Method()
2134 	{
2135 		return "Call functions with invalid enums and check if GL_INVALID_ENUM was generated.";
2136 	}
2137 
2138 	// make sure at least one atomic counter resource is active
FragmentShader()2139 	virtual std::string FragmentShader()
2140 	{
2141 		return "#version 310 es                                        \n"
2142 			   "layout (binding = 0, offset = 0) uniform highp atomic_uint a;\n"
2143 			   "out mediump vec4 outColor;                             \n"
2144 			   "void main(void) {                                      \n"
2145 			   "   uint b = atomicCounterIncrement(a);                 \n"
2146 			   "   outColor = vec4(float(b));                          \n"
2147 			   "}                                                      \n";
2148 	}
2149 
Run()2150 	virtual long Run()
2151 	{
2152 		GLint max_buffers = 0, max_counters = 0;
2153 		glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &max_buffers);
2154 		glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, &max_counters);
2155 		if (max_buffers < 1 || max_counters < 1)
2156 		{
2157 			OutputNotSupported("Test requires at least 1 atomic counter.");
2158 			return NOT_SUPPORTED;
2159 		}
2160 
2161 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2162 		glBindAttribLocation(program, 0, "position");
2163 		LinkProgram(program);
2164 
2165 		long error = NO_ERROR;
2166 
2167 		GLint   res;
2168 		GLsizei len		  = 0;
2169 		GLchar  name[100] = { '\0' };
2170 		GLenum  props[1]  = { GL_TEXTURE_1D };
2171 
2172 		m_context.getTestContext().getLog()
2173 			<< tcu::TestLog::Message << "Case 1: <programInterface> is ATOMIC_COUNTER_BUFFER in "
2174 										"GetProgramResourceIndex or GetProgramResourceName"
2175 			<< tcu::TestLog::EndMessage;
2176 		glGetProgramResourceIndex(program, GL_ATOMIC_COUNTER_BUFFER, name);
2177 		ExpectError(GL_INVALID_ENUM, error);
2178 		glGetProgramResourceName(program, GL_ATOMIC_COUNTER_BUFFER, 0, 1024, &len, name);
2179 		ExpectError(GL_INVALID_ENUM, error);
2180 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2181 
2182 		m_context.getTestContext().getLog()
2183 			<< tcu::TestLog::Message
2184 			<< "Case 2: <props> is not a property name supported by the command GetProgramResourceiv"
2185 			<< tcu::TestLog::EndMessage;
2186 		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2187 		ExpectError(GL_INVALID_ENUM, error);
2188 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2189 
2190 		glGetProgramResourceLocation(program, GL_ATOMIC_COUNTER_BUFFER, "position");
2191 		ExpectError(GL_INVALID_ENUM, error);
2192 
2193 		glDeleteProgram(program);
2194 		return error;
2195 	}
2196 };
2197 
2198 class InvalidOperationTest : public SimpleShaders
2199 {
Title()2200 	virtual std::string Title()
2201 	{
2202 		return "Invalid Operation Test";
2203 	}
2204 
PassCriteria()2205 	virtual std::string PassCriteria()
2206 	{
2207 		return "GL_INVALID_OPERATION error is generated after every function call.";
2208 	}
2209 
Purpose()2210 	virtual std::string Purpose()
2211 	{
2212 		return "Verify that wrong use of functions generates GL_INVALID_OPERATION as described in spec.";
2213 	}
2214 
Method()2215 	virtual std::string Method()
2216 	{
2217 		return "Perform invalid operation and check if GL_INVALID_OPERATION was generated.";
2218 	}
2219 
Run()2220 	virtual long Run()
2221 	{
2222 		long error = NO_ERROR;
2223 
2224 		GLuint program  = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2225 		GLuint program2 = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2226 		glBindAttribLocation(program, 0, "position");
2227 		LinkProgram(program);
2228 
2229 		const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
2230 		GLint		 res;
2231 		GLsizei		 len	   = 0;
2232 		GLchar		 name[100] = { '\0' };
2233 		GLenum		 props[1]  = { GL_OFFSET };
2234 
2235 		m_context.getTestContext().getLog()
2236 			<< tcu::TestLog::Message << "Case 1: <program> is the name of a shader object" << tcu::TestLog::EndMessage;
2237 		glGetProgramInterfaceiv(sh, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2238 		ExpectError(GL_INVALID_OPERATION, error);
2239 		glGetProgramResourceIndex(sh, GL_PROGRAM_INPUT, "pie");
2240 		ExpectError(GL_INVALID_OPERATION, error);
2241 		glGetProgramResourceName(sh, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2242 		ExpectError(GL_INVALID_OPERATION, error);
2243 		glGetProgramResourceiv(sh, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2244 		ExpectError(GL_INVALID_OPERATION, error);
2245 		glGetProgramResourceLocation(sh, GL_PROGRAM_INPUT, "pie");
2246 		ExpectError(GL_INVALID_OPERATION, error);
2247 		glDeleteShader(sh);
2248 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2249 
2250 		m_context.getTestContext().getLog()
2251 			<< tcu::TestLog::Message << "Case 2: <pname> is not supported in GetProgramInterfaceiv"
2252 			<< tcu::TestLog::EndMessage;
2253 		glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2254 		ExpectError(GL_INVALID_OPERATION, error);
2255 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2256 
2257 		m_context.getTestContext().getLog()
2258 			<< tcu::TestLog::Message << "Case 3: <props> is not supported in GetProgramResourceiv"
2259 			<< tcu::TestLog::EndMessage;
2260 		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2261 		ExpectError(GL_INVALID_OPERATION, error);
2262 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3 finished" << tcu::TestLog::EndMessage;
2263 
2264 		m_context.getTestContext().getLog()
2265 			<< tcu::TestLog::Message << "Case 4: <program> has not been linked in GetProgramResourceLocation"
2266 			<< tcu::TestLog::EndMessage;
2267 		glGetProgramResourceLocation(program2, GL_PROGRAM_INPUT, "pie");
2268 		ExpectError(GL_INVALID_OPERATION, error);
2269 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 4 finished" << tcu::TestLog::EndMessage;
2270 
2271 		glDeleteProgram(program);
2272 		glDeleteProgram(program2);
2273 		return error;
2274 	}
2275 };
2276 
2277 class ShaderStorageBlock : public ComputeShaderTest
2278 {
Title()2279 	virtual std::string Title()
2280 	{
2281 		return "Shader Storage Block Test";
2282 	}
2283 
ShadersDesc()2284 	virtual std::string ShadersDesc()
2285 	{
2286 		return "compute shader different types of storage blocks used";
2287 	}
2288 
PurposeExt()2289 	virtual std::string PurposeExt()
2290 	{
2291 		return "\n\n Purpose is to verify calls using GL_BUFFER_VARIABLE and GL_SHADER_STORAGE_BLOCK as an interface "
2292 			   "params.\n";
2293 	}
2294 
ComputeShader()2295 	virtual std::string ComputeShader()
2296 	{
2297 		return "layout(local_size_x = 1, local_size_y = 1) in;  \n"
2298 			   "layout(std430) buffer Output {                  \n"
2299 			   "   mediump vec4 data;                           \n"
2300 			   "} g_out;                                        \n"
2301 			   ""
2302 			   "struct U {                     \n"
2303 			   "   bool a[3];                  \n"
2304 			   "   mediump vec4 b;                     \n"
2305 			   "   mediump mat3 c;                     \n"
2306 			   "   mediump float d[2];                 \n"
2307 			   "};                             \n"
2308 			   "struct UU {                    \n"
2309 			   "   U a;                        \n"
2310 			   "   U b[2];                     \n"
2311 			   "   uvec2 c;                    \n"
2312 			   "};                             \n"
2313 			   ""
2314 			   "layout(binding=4) buffer TrickyBuffer {          \n"
2315 			   "   UU a[3];                                      \n"
2316 			   "   mediump mat4 b;                               \n"
2317 			   "   uint c;                                       \n"
2318 			   "} e[2];                                          \n"
2319 			   ""
2320 			   "layout(binding = 0) buffer SimpleBuffer {                \n"
2321 			   "   mediump mat3x2 a;                                     \n"
2322 			   "   mediump mat4 b;                                       \n"
2323 			   "   mediump vec4 c;                                       \n"
2324 			   "};                                                       \n"
2325 			   ""
2326 			   "layout(binding = 1) buffer NotSoSimpleBuffer {           \n"
2327 			   "   ivec2 a[4];                                           \n"
2328 			   "   mediump mat3 b[2];                                    \n"
2329 			   "   mediump mat2 c;                                       \n"
2330 			   "} d;                                                     \n"
2331 			   ""
2332 			   "void main() {                                    \n"
2333 			   "    mediump float tmp;                           \n"
2334 			   "    mediump float tmp2;                          \n"
2335 			   "    tmp = e[0].a[0].b[0].d[0] * float(e[1].c);   \n"
2336 			   "    tmp2 = a[0][0] * b[0][0] * c.x;                                \n"
2337 			   "    tmp2 = tmp2 + float(d.a[0].y) + d.b[0][0][0] + d.c[0][0];      \n"
2338 			   "    g_out.data = vec4(0, 1, 0, 1) * tmp * tmp2;                    \n"
2339 			   "}";
2340 	}
2341 
Run()2342 	virtual long Run()
2343 	{
2344 		GLuint program = CreateComputeProgram(ComputeShader());
2345 		glLinkProgram(program);
2346 		if (!CheckProgram(program))
2347 		{
2348 			glDeleteProgram(program);
2349 			return ERROR;
2350 		}
2351 		glUseProgram(program);
2352 
2353 		long error = NO_ERROR;
2354 
2355 		GLint res;
2356 		VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 28, error);
2357 		glGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &res);
2358 		if (res < 7)
2359 		{
2360 			m_context.getTestContext().getLog()
2361 				<< tcu::TestLog::Message
2362 				<< "Error on: glGetProgramInterfaceiv, if: GL_BUFFER_VARIABLE, param: GL_ACTIVE_RESOURCES\n"
2363 				<< "Expected value greater or equal to 7, got " << res << tcu::TestLog::EndMessage;
2364 			glDeleteProgram(program);
2365 			return ERROR;
2366 		}
2367 		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 5, error);
2368 		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
2369 
2370 		std::map<std::string, GLuint> indicesSSB;
2371 		std::map<std::string, GLuint> indicesBV;
2372 		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
2373 		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "NotSoSimpleBuffer", error);
2374 		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer", error);
2375 		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer[1]", error);
2376 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a", error);
2377 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "b", error);
2378 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "c", error);
2379 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.a[0]", error);
2380 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.c", error);
2381 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.b[0]", error);
2382 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.a[0].b[0].d", error);
2383 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.b", error);
2384 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.c", error);
2385 
2386 		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer",
2387 									 error);
2388 		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"],
2389 									 "NotSoSimpleBuffer", error);
2390 		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], "TrickyBuffer[0]",
2391 									 error);
2392 		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], "TrickyBuffer[1]",
2393 									 error);
2394 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
2395 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["b"], "b", error);
2396 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["c"], "c", error);
2397 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.a[0]"],
2398 									 "NotSoSimpleBuffer.a[0]", error);
2399 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.c"],
2400 									 "NotSoSimpleBuffer.c", error);
2401 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.b[0]"],
2402 									 "NotSoSimpleBuffer.b[0]", error);
2403 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"],
2404 									 "TrickyBuffer.a[0].b[0].d[0]", error);
2405 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.b"], "TrickyBuffer.b", error);
2406 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.c"], "TrickyBuffer.c", error);
2407 
2408 		GLenum props[] = { GL_NAME_LENGTH,
2409 						   GL_BUFFER_BINDING,
2410 						   GL_NUM_ACTIVE_VARIABLES,
2411 						   GL_REFERENCED_BY_COMPUTE_SHADER,
2412 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
2413 						   GL_REFERENCED_BY_VERTEX_SHADER };
2414 		GLint expected[] = { 13, 0, 3, 1, 0, 0 };
2415 		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 6, props, 6, expected,
2416 								   error);
2417 		GLenum props2[] = { GL_NAME_LENGTH, GL_BUFFER_BINDING, GL_REFERENCED_BY_COMPUTE_SHADER,
2418 							GL_REFERENCED_BY_FRAGMENT_SHADER, GL_REFERENCED_BY_VERTEX_SHADER };
2419 		GLint expected2[] = { 18, 1, 1, 0, 0 };
2420 		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 5, props2, 5,
2421 								   expected2, error);
2422 		GLint expected3[] = { 16, 4, 1, 0, 0 };
2423 		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], 5, props2, 5,
2424 								   expected3, error);
2425 		GLint expected4[] = { 16, 5, 1, 0, 0 };
2426 		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], 5, props2, 5,
2427 								   expected4, error);
2428 
2429 		GLenum props3[] = { GL_NAME_LENGTH,
2430 							GL_TYPE,
2431 							GL_ARRAY_SIZE,
2432 							GL_BLOCK_INDEX,
2433 							GL_ARRAY_STRIDE,
2434 							GL_IS_ROW_MAJOR,
2435 							GL_REFERENCED_BY_COMPUTE_SHADER,
2436 							GL_REFERENCED_BY_FRAGMENT_SHADER,
2437 							GL_REFERENCED_BY_VERTEX_SHADER,
2438 							GL_TOP_LEVEL_ARRAY_SIZE,
2439 							GL_TOP_LEVEL_ARRAY_STRIDE };
2440 		GLint expected5[] = { 2, 35687, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 1, 0, 0, 1, 0 };
2441 		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a"], 11, props3, 11, expected5, error);
2442 		GLenum props4[] = { GL_NAME_LENGTH,
2443 							GL_TYPE,
2444 							GL_ARRAY_SIZE,
2445 							GL_BLOCK_INDEX,
2446 							GL_MATRIX_STRIDE,
2447 							GL_IS_ROW_MAJOR,
2448 							GL_REFERENCED_BY_COMPUTE_SHADER,
2449 							GL_REFERENCED_BY_FRAGMENT_SHADER,
2450 							GL_REFERENCED_BY_VERTEX_SHADER,
2451 							GL_TOP_LEVEL_ARRAY_SIZE };
2452 		GLint expected6[] = { 28, 5126, 2, static_cast<GLint>(indicesSSB["TrickyBuffer"]), 0, 0, 1, 0, 0, 3 };
2453 		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"], 10, props4, 10,
2454 								   expected6, error);
2455 
2456 		GLenum			 prop	= GL_ACTIVE_VARIABLES;
2457 		const GLsizei	bufSize = 1000;
2458 		GLsizei			 length;
2459 		GLint			 param[bufSize];
2460 		std::set<GLuint> exp;
2461 		exp.insert(indicesBV["a"]);
2462 		exp.insert(indicesBV["b"]);
2463 		exp.insert(indicesBV["c"]);
2464 		glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 1, &prop, bufSize, &length,
2465 							   param);
2466 		for (int i = 0; i < length; ++i)
2467 		{
2468 			if (exp.find(param[i]) == exp.end())
2469 			{
2470 				m_context.getTestContext().getLog()
2471 					<< tcu::TestLog::Message
2472 					<< "Unexpected index found in active variables of SimpleBuffer: " << param[i]
2473 					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
2474 					   "GL_SHADER_STORAGE_BLOCK"
2475 					<< tcu::TestLog::EndMessage;
2476 				glDeleteProgram(program);
2477 				return ERROR;
2478 			}
2479 			else if (length != 3)
2480 			{
2481 				m_context.getTestContext().getLog()
2482 					<< tcu::TestLog::Message
2483 					<< "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK"
2484 					<< "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
2485 				glDeleteProgram(program);
2486 				return ERROR;
2487 			}
2488 		}
2489 		std::set<GLuint> exp2;
2490 		exp2.insert(indicesBV["NotSoSimpleBuffer.a[0]"]);
2491 		exp2.insert(indicesBV["NotSoSimpleBuffer.b[0]"]);
2492 		exp2.insert(indicesBV["NotSoSimpleBuffer.c"]);
2493 		glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 1, &prop, bufSize,
2494 							   &length, param);
2495 		for (int i = 0; i < length; ++i)
2496 		{
2497 			if (exp2.find(param[i]) == exp2.end())
2498 			{
2499 				m_context.getTestContext().getLog()
2500 					<< tcu::TestLog::Message
2501 					<< "Unexpected index found in active variables of NotSoSimpleBuffer: " << param[i]
2502 					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
2503 					   "GL_SHADER_STORAGE_BLOCK"
2504 					<< tcu::TestLog::EndMessage;
2505 				glDeleteProgram(program);
2506 				return ERROR;
2507 			}
2508 			else if (length != 3)
2509 			{
2510 				m_context.getTestContext().getLog()
2511 					<< tcu::TestLog::Message
2512 					<< "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK"
2513 					<< param[i] << "\nExpected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
2514 				glDeleteProgram(program);
2515 				return ERROR;
2516 			}
2517 		}
2518 
2519 		glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2520 		if (res < 3)
2521 		{
2522 			m_context.getTestContext().getLog()
2523 				<< tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!\n"
2524 				<< "Call: glGetProgramInterfaceiv, interface: GL_SHADER_STORAGE_BLOCK" << tcu::TestLog::EndMessage;
2525 			return ERROR;
2526 		}
2527 
2528 		glDeleteProgram(program);
2529 		return error;
2530 	}
2531 };
2532 
2533 class NullLength : public SimpleShaders
2534 {
2535 
Title()2536 	virtual std::string Title()
2537 	{
2538 		return "NULL Length Test";
2539 	}
2540 
PurposeExt()2541 	virtual std::string PurposeExt()
2542 	{
2543 		return "\n\n Purpose is to verify that GetProgramResourceName with null length doesn't return length (doesn't "
2544 			   "crash).\n";
2545 	}
2546 
VertexShader()2547 	virtual std::string VertexShader()
2548 	{
2549 		return "#version 310 es                      \n"
2550 			   "in vec4 position;                    \n"
2551 			   "void main(void)                      \n"
2552 			   "{                                    \n"
2553 			   "    gl_Position = position;          \n"
2554 			   "}";
2555 	}
2556 
FragmentShader()2557 	virtual std::string FragmentShader()
2558 	{
2559 		return "#version 310 es                \n"
2560 			   "out mediump vec4 color;                \n"
2561 			   "void main() {                  \n"
2562 			   "    color = vec4(0, 1, 0, 1);  \n"
2563 			   "}";
2564 	}
2565 
Run()2566 	virtual long Run()
2567 	{
2568 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2569 		glBindAttribLocation(program, 0, "position");
2570 		LinkProgram(program);
2571 
2572 		GLchar name[1024] = { '\0' };
2573 		GLuint index	  = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color");
2574 		GLenum prop		  = GL_ARRAY_SIZE;
2575 		GLint  res;
2576 		glGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, 1024, NULL, name);
2577 		glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &prop, 1, NULL, &res);
2578 
2579 		std::string expected = "color";
2580 		if (name != expected)
2581 		{
2582 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected name: " << expected
2583 												<< ", got: " << name << tcu::TestLog::EndMessage;
2584 			glDeleteProgram(program);
2585 			return ERROR;
2586 		}
2587 		else if (res != 1)
2588 		{
2589 			m_context.getTestContext().getLog()
2590 				<< tcu::TestLog::Message << "Expected array_size: 1, got: " << res << tcu::TestLog::EndMessage;
2591 			glDeleteProgram(program);
2592 			return ERROR;
2593 		}
2594 
2595 		glDeleteProgram(program);
2596 		return NO_ERROR;
2597 	}
2598 };
2599 
2600 class ArraysOfArrays : public SimpleShaders
2601 {
2602 
Title()2603 	virtual std::string Title()
2604 	{
2605 		return "Arrays Of Arrays Test";
2606 	}
2607 
ShadersDesc()2608 	virtual std::string ShadersDesc()
2609 	{
2610 		return "fallthrough fragment and vertex shaders with multi dimensional uniform array used";
2611 	}
2612 
PurposeExt()2613 	virtual std::string PurposeExt()
2614 	{
2615 		return "\n\n Purpose is to verify that feature works correctly with arrays_of_arrays feature.\n";
2616 	}
2617 
VertexShader()2618 	virtual std::string VertexShader()
2619 	{
2620 		return "#version 310 es                      \n"
2621 			   "in vec4 position;                    \n"
2622 			   "uniform mediump vec4 a[3][4][5];             \n"
2623 			   "void main(void)                      \n"
2624 			   "{                                                 \n"
2625 			   "    gl_Position = position + a[2][1][0];          \n"
2626 			   "}";
2627 	}
2628 
FragmentShader()2629 	virtual std::string FragmentShader()
2630 	{
2631 		return "#version 310 es                \n"
2632 			   "out mediump vec4 color;                \n"
2633 			   "void main() {                  \n"
2634 			   "    color = vec4(0, 1, 0, 1);  \n"
2635 			   "}";
2636 	}
2637 
Run()2638 	virtual long Run()
2639 	{
2640 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2641 		glBindAttribLocation(program, 0, "position");
2642 		LinkProgram(program);
2643 
2644 		long error = NO_ERROR;
2645 
2646 		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 11, error);
2647 
2648 		std::map<std::string, GLuint> indices;
2649 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a[2][1]", error);
2650 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, "a[2][1][0]", indices["a[2][1]"], error);
2651 
2652 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a[2][1]"], "a[2][1][0]", error);
2653 
2654 		GLenum props[] = { GL_NAME_LENGTH,
2655 						   GL_TYPE,
2656 						   GL_ARRAY_SIZE,
2657 						   GL_OFFSET,
2658 						   GL_BLOCK_INDEX,
2659 						   GL_ARRAY_STRIDE,
2660 						   GL_MATRIX_STRIDE,
2661 						   GL_IS_ROW_MAJOR,
2662 						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
2663 						   GL_REFERENCED_BY_COMPUTE_SHADER,
2664 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
2665 						   GL_REFERENCED_BY_VERTEX_SHADER,
2666 						   GL_LOCATION };
2667 		GLint expected[] = { 11, 35666, 5, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "a[2][1]") };
2668 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a[2][1]"], 13, props, 13, expected, error);
2669 
2670 		glDeleteProgram(program);
2671 		return error;
2672 	}
2673 };
2674 
2675 class TopLevelArray : public ComputeShaderTest
2676 {
2677 
Title()2678 	virtual std::string Title()
2679 	{
2680 		return "Top Level Array Test";
2681 	}
2682 
ShadersDesc()2683 	virtual std::string ShadersDesc()
2684 	{
2685 		return "compute shader with multi dimensional array used inside storage block";
2686 	}
2687 
PurposeExt()2688 	virtual std::string PurposeExt()
2689 	{
2690 		return "\n\n Purpose is to verify that feature works correctly when querying for GL_TOP_LEVEL_ARRAY_SIZE\n"
2691 			   " and GL_TOP_LEVEL_ARRAY_STRIDE.\n";
2692 	}
2693 
ComputeShader()2694 	virtual std::string ComputeShader()
2695 	{
2696 		return "layout(local_size_x = 1, local_size_y = 1) in; \n"
2697 			   "layout(std430) buffer Outp {                   \n"
2698 			   "   mediump vec4 d;                             \n"
2699 			   "} g_out;                                       \n"
2700 			   ""
2701 			   "buffer Block {                       \n"
2702 			   "   mediump vec4 a[5][4][3];          \n"
2703 			   "};                                   \n"
2704 			   ""
2705 			   "void main(void)                      \n"
2706 			   "{                                    \n"
2707 			   "    g_out.d = a[0][0][0];            \n"
2708 			   "}";
2709 	}
2710 
Run()2711 	virtual long Run()
2712 	{
2713 		GLuint program = CreateComputeProgram(ComputeShader());
2714 		glLinkProgram(program);
2715 		if (!CheckProgram(program))
2716 		{
2717 			glDeleteProgram(program);
2718 			return ERROR;
2719 		}
2720 		glUseProgram(program);
2721 
2722 		long error = NO_ERROR;
2723 
2724 		VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 11, error);
2725 		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 6, error);
2726 		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 2, error);
2727 
2728 		std::map<std::string, GLuint> indicesSSB;
2729 		std::map<std::string, GLuint> indicesBV;
2730 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a[0][0]", error);
2731 		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Block", error);
2732 
2733 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], "a[0][0][0]", error);
2734 		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Block"], "Block", error);
2735 
2736 		GLenum props3[] = { GL_NAME_LENGTH,
2737 							GL_TYPE,
2738 							GL_ARRAY_SIZE,
2739 							GL_BLOCK_INDEX,
2740 							GL_IS_ROW_MAJOR,
2741 							GL_REFERENCED_BY_COMPUTE_SHADER,
2742 							GL_REFERENCED_BY_FRAGMENT_SHADER,
2743 							GL_REFERENCED_BY_VERTEX_SHADER,
2744 							GL_TOP_LEVEL_ARRAY_SIZE };
2745 		GLint expected5[] = { 11, 35666, 3, static_cast<GLint>(indicesSSB["Block"]), 0, 1, 0, 0, 5 };
2746 		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 9, props3, 9, expected5, error);
2747 
2748 		GLenum  prop = GL_TOP_LEVEL_ARRAY_STRIDE;
2749 		GLsizei len;
2750 		GLint   res;
2751 		glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 1, &prop, 1024, &len, &res);
2752 		if (res <= 0)
2753 		{
2754 			m_context.getTestContext().getLog()
2755 				<< tcu::TestLog::Message
2756 				<< "Call: glGetProgramResourceiv, interface: GL_BUFFER_VARIABLE, param: GL_TOP_LEVEL_ARRAY_STRIDE\n"
2757 				<< "Expected value greater than 0, got: " << res << tcu::TestLog::EndMessage;
2758 			glDeleteProgram(program);
2759 			return ERROR;
2760 		}
2761 
2762 		glDeleteProgram(program);
2763 		return error;
2764 	}
2765 };
2766 
2767 class SeparateProgramsVertex : public SimpleShaders
2768 {
2769 public:
Title()2770 	virtual std::string Title()
2771 	{
2772 		return "Separate Program Vertex Shader Test";
2773 	}
2774 
ShadersDesc()2775 	virtual std::string ShadersDesc()
2776 	{
2777 		return "vertex shader as separate shader object";
2778 	}
2779 
PurposeExt()2780 	virtual std::string PurposeExt()
2781 	{
2782 		return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
2783 			   "functionality.\n";
2784 	}
2785 
CreateShaderProgram(GLenum type,GLsizei count,const GLchar ** strings)2786 	virtual GLuint CreateShaderProgram(GLenum type, GLsizei count, const GLchar** strings)
2787 	{
2788 		GLuint program = glCreateShaderProgramv(type, count, strings);
2789 		GLint  status  = GL_TRUE;
2790 		glGetProgramiv(program, GL_LINK_STATUS, &status);
2791 		if (status == GL_FALSE)
2792 		{
2793 			GLsizei length;
2794 			GLchar  log[1024];
2795 			glGetProgramInfoLog(program, sizeof(log), &length, log);
2796 			if (length > 1)
2797 			{
2798 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
2799 													<< log << tcu::TestLog::EndMessage;
2800 			}
2801 		}
2802 		return program;
2803 	}
2804 
Run()2805 	virtual long Run()
2806 	{
2807 		long error = NO_ERROR;
2808 
2809 		const char* srcVS = "#version 310 es                            \n"
2810 							"layout(location = 0) in vec4 in_vertex;    \n"
2811 							""
2812 							"out mediump float r, g, b;                           \n"
2813 							"out mediump vec4 iLikePie;                           \n"
2814 							""
2815 							"uniform mediump float u;                           \n"
2816 							"uniform mediump vec4 v;                            \n"
2817 							""
2818 							"void main() {                     \n"
2819 							"  gl_Position = in_vertex;        \n"
2820 							"  r = u;                          \n"
2821 							"  g = 0.0;                        \n"
2822 							"  b = 0.0;                        \n"
2823 							"  iLikePie = v;                   \n"
2824 							"}";
2825 
2826 		const GLuint vs = CreateShaderProgram(GL_VERTEX_SHADER, 1, &srcVS);
2827 
2828 		VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2829 		VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 2, error);
2830 		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 10, error);
2831 		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
2832 		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 12, error);
2833 		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
2834 
2835 		std::map<std::string, GLuint> indicesU;
2836 		std::map<std::string, GLuint> indicesI;
2837 		std::map<std::string, GLuint> indicesO;
2838 		VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "u", error);
2839 		VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "v", error);
2840 		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_INPUT, indicesI, "in_vertex", error);
2841 		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "r", error);
2842 		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "g", error);
2843 		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "b", error);
2844 		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "iLikePie", error);
2845 		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
2846 
2847 		VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["u"], "u", error);
2848 		VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["v"], "v", error);
2849 		VerifyGetProgramResourceName(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], "in_vertex", error);
2850 		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["r"], "r", error);
2851 		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["g"], "g", error);
2852 		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
2853 		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], "iLikePie", error);
2854 		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
2855 
2856 		VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "u", glGetUniformLocation(vs, "u"), error);
2857 		VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "v", glGetUniformLocation(vs, "v"), error);
2858 		VerifyGetProgramResourceLocation(vs, GL_PROGRAM_INPUT, "in_vertex", 0, error);
2859 
2860 		GLenum props[] = { GL_NAME_LENGTH,
2861 						   GL_TYPE,
2862 						   GL_ARRAY_SIZE,
2863 						   GL_OFFSET,
2864 						   GL_BLOCK_INDEX,
2865 						   GL_ARRAY_STRIDE,
2866 						   GL_MATRIX_STRIDE,
2867 						   GL_IS_ROW_MAJOR,
2868 						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
2869 						   GL_REFERENCED_BY_COMPUTE_SHADER,
2870 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
2871 						   GL_REFERENCED_BY_VERTEX_SHADER,
2872 						   GL_LOCATION };
2873 		GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(vs, "v") };
2874 		VerifyGetProgramResourceiv(vs, GL_UNIFORM, indicesU["v"], 13, props, 13, expected, error);
2875 
2876 		GLenum props2[] = { GL_NAME_LENGTH,
2877 							GL_TYPE,
2878 							GL_ARRAY_SIZE,
2879 							GL_REFERENCED_BY_COMPUTE_SHADER,
2880 							GL_REFERENCED_BY_FRAGMENT_SHADER,
2881 							GL_REFERENCED_BY_VERTEX_SHADER,
2882 							GL_LOCATION };
2883 		GLint expected2[] = { 10, 35666, 1, 0, 0, 1, 0 };
2884 		VerifyGetProgramResourceiv(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], 7, props2, 7, expected2, error);
2885 
2886 		GLenum props3[] = { GL_NAME_LENGTH,
2887 							GL_TYPE,
2888 							GL_ARRAY_SIZE,
2889 							GL_REFERENCED_BY_COMPUTE_SHADER,
2890 							GL_REFERENCED_BY_FRAGMENT_SHADER,
2891 							GL_REFERENCED_BY_VERTEX_SHADER };
2892 		GLint expected3[] = { 9, 35666, 1, 0, 0, 1 };
2893 		VerifyGetProgramResourceiv(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], 6, props3, 6, expected3, error);
2894 
2895 		glDeleteProgram(vs);
2896 		return error;
2897 	}
2898 };
2899 
2900 class SeparateProgramsFragment : public SeparateProgramsVertex
2901 {
2902 
Title()2903 	virtual std::string Title()
2904 	{
2905 		return "Separate Program Fragment Shader Test";
2906 	}
2907 
ShadersDesc()2908 	virtual std::string ShadersDesc()
2909 	{
2910 		return "fragment shader as separate shader object";
2911 	}
2912 
Run()2913 	virtual long Run()
2914 	{
2915 		long error = NO_ERROR;
2916 
2917 		const char* srcTCS = "#version 310 es                                  \n"
2918 							 "out mediump vec4 fs_color;                       \n"
2919 							 ""
2920 							 "layout(location = 1) uniform mediump vec4 x;     \n"
2921 							 ""
2922 							 "in mediump vec4 vs_color;                        \n"
2923 							 "void main() {                                    \n"
2924 							 "   fs_color = vs_color + x;                      \n"
2925 							 "}";
2926 
2927 		const GLuint tcs = CreateShaderProgram(GL_FRAGMENT_SHADER, 1, &srcTCS);
2928 
2929 		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
2930 		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
2931 		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 9, error);
2932 		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
2933 		VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2934 		VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2935 
2936 		std::map<std::string, GLuint> indicesI;
2937 		std::map<std::string, GLuint> indicesO;
2938 		std::map<std::string, GLuint> indicesU;
2939 		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "vs_color", error);
2940 		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "fs_color", error);
2941 		VerifyGetProgramResourceIndex(tcs, GL_UNIFORM, indicesU, "x", error);
2942 
2943 		VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], "vs_color", error);
2944 		VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], "fs_color", error);
2945 		VerifyGetProgramResourceName(tcs, GL_UNIFORM, indicesU["x"], "x", error);
2946 
2947 		VerifyGetProgramResourceLocation(tcs, GL_UNIFORM, "x", 1, error);
2948 
2949 		GLenum props2[] = { GL_NAME_LENGTH,
2950 							GL_TYPE,
2951 							GL_ARRAY_SIZE,
2952 							GL_REFERENCED_BY_COMPUTE_SHADER,
2953 							GL_REFERENCED_BY_FRAGMENT_SHADER,
2954 							GL_REFERENCED_BY_VERTEX_SHADER };
2955 		GLint expected2[] = { 9, 35666, 1, 0, 1, 0 };
2956 		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], 6, props2, 6, expected2, error);
2957 		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], 6, props2, 6, expected2, error);
2958 
2959 		GLenum props[] = { GL_NAME_LENGTH,
2960 						   GL_TYPE,
2961 						   GL_ARRAY_SIZE,
2962 						   GL_OFFSET,
2963 						   GL_BLOCK_INDEX,
2964 						   GL_ARRAY_STRIDE,
2965 						   GL_MATRIX_STRIDE,
2966 						   GL_IS_ROW_MAJOR,
2967 						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
2968 						   GL_REFERENCED_BY_COMPUTE_SHADER,
2969 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
2970 						   GL_REFERENCED_BY_VERTEX_SHADER,
2971 						   GL_LOCATION };
2972 		GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 1 };
2973 		VerifyGetProgramResourceiv(tcs, GL_UNIFORM, indicesU["x"], 13, props, 13, expected, error);
2974 
2975 		glDeleteProgram(tcs);
2976 		return error;
2977 	}
2978 };
2979 
2980 class UniformBlockAdvanced : public SimpleShaders
2981 {
Title()2982 	virtual std::string Title()
2983 	{
2984 		return "Uniform Block Advanced Test";
2985 	}
2986 
ShadersDesc()2987 	virtual std::string ShadersDesc()
2988 	{
2989 		return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
2990 	}
2991 
PurposeExt()2992 	virtual std::string PurposeExt()
2993 	{
2994 		return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param and\n"
2995 			   "verify results of querying offset, strides and row order.\n";
2996 	}
2997 
VertexShader()2998 	virtual std::string VertexShader()
2999 	{
3000 		return "#version 310 es                      \n"
3001 			   "in vec4 position;                    \n"
3002 			   ""
3003 			   "layout(row_major) uniform SimpleBlock {   \n"
3004 			   "   mat4 a;                                \n"
3005 			   "   vec4 b[10];                            \n"
3006 			   "};                                        \n"
3007 			   ""
3008 			   "void main(void)                      \n"
3009 			   "{                                    \n"
3010 			   "    float tmp;                       \n"
3011 			   "    tmp = a[0][0] + b[0].x;          \n"
3012 			   "    gl_Position = position * tmp;    \n"
3013 			   "}";
3014 	}
3015 
Run()3016 	virtual long Run()
3017 	{
3018 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3019 		glBindAttribLocation(program, 0, "position");
3020 		LinkProgram(program);
3021 
3022 		long error = NO_ERROR;
3023 
3024 		std::map<std::string, GLuint> indicesU;
3025 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
3026 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
3027 
3028 		GLenum props[]	= { GL_IS_ROW_MAJOR };
3029 		GLint  expected[] = { 1 };
3030 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, props, 1, expected, error);
3031 
3032 		GLenum  prop = GL_MATRIX_STRIDE;
3033 		GLsizei len;
3034 		GLint   res;
3035 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
3036 		if (res < 1)
3037 		{
3038 			m_context.getTestContext().getLog()
3039 				<< tcu::TestLog::Message
3040 				<< "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_MATRIX_STRIDE\n"
3041 				<< "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
3042 		}
3043 		prop = GL_OFFSET;
3044 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
3045 		if (res < 0)
3046 		{
3047 			m_context.getTestContext().getLog()
3048 				<< tcu::TestLog::Message << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_OFFSET\n"
3049 				<< "Expected value not less than 0, got " << res << tcu::TestLog::EndMessage;
3050 		}
3051 		prop = GL_ARRAY_STRIDE;
3052 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, 1024, &len, &res);
3053 		if (res < 1)
3054 		{
3055 			m_context.getTestContext().getLog()
3056 				<< tcu::TestLog::Message
3057 				<< "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_ARRAY_STRIDE\n"
3058 				<< "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
3059 		}
3060 
3061 		glDeleteProgram(program);
3062 		return error;
3063 	}
3064 };
3065 
3066 class ArrayNames : public SimpleShaders
3067 {
3068 
Title()3069 	virtual std::string Title()
3070 	{
3071 		return "Array Names Test";
3072 	}
3073 
ShadersDesc()3074 	virtual std::string ShadersDesc()
3075 	{
3076 		return "fallthrough fragment shader and a vertex shader with array of vec4 uniform used";
3077 	}
3078 
PurposeExt()3079 	virtual std::string PurposeExt()
3080 	{
3081 		return "\n\n Purpose is to verify that GetProgramResourceLocation match "
3082 			   "name strings correctly.\n";
3083 	}
3084 
VertexShader()3085 	virtual std::string VertexShader()
3086 	{
3087 		return "#version 310 es                      \n"
3088 			   "in vec4 position;                    \n"
3089 			   ""
3090 			   "uniform mediump vec4 a[2];           \n"
3091 			   ""
3092 			   "void main(void)                            \n"
3093 			   "{                                          \n"
3094 			   "    gl_Position = position + a[0] + a[1];  \n"
3095 			   "}";
3096 	}
3097 
Run()3098 	virtual long Run()
3099 	{
3100 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3101 		glBindAttribLocation(program, 0, "position");
3102 		LinkProgram(program);
3103 
3104 		long error = NO_ERROR;
3105 
3106 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
3107 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0]", glGetUniformLocation(program, "a"), error);
3108 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[1]", glGetUniformLocation(program, "a[1]"), error);
3109 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[2]", -1, error);
3110 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 + 0]", -1, error);
3111 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0+0]", -1, error);
3112 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[ 0]", -1, error);
3113 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 ]", -1, error);
3114 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\n0]", -1, error);
3115 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\t0]", -1, error);
3116 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[01]", -1, error);
3117 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[00]", -1, error);
3118 
3119 		glDeleteProgram(program);
3120 		return error;
3121 	}
3122 };
3123 
3124 class BuffLength : public SimpleShaders
3125 {
3126 
Title()3127 	virtual std::string Title()
3128 	{
3129 		return "Buff Length Test";
3130 	}
3131 
ShadersDesc()3132 	virtual std::string ShadersDesc()
3133 	{
3134 		return "fallthrough fragment shader and vertex with uniform of vec4 type used";
3135 	}
3136 
PurposeExt()3137 	virtual std::string PurposeExt()
3138 	{
3139 		return "\n\n Purpose is to verify that bufsize of GetProgramResourceName and "
3140 			   "GetProgramResourceiv is respected.\n";
3141 	}
3142 
VertexShader()3143 	virtual std::string VertexShader()
3144 	{
3145 		return "#version 310 es                      \n"
3146 			   "in vec4 position;                    \n"
3147 			   ""
3148 			   "uniform mediump vec4 someLongName;         \n"
3149 			   ""
3150 			   "void main(void)                            \n"
3151 			   "{                                          \n"
3152 			   "    gl_Position = position + someLongName; \n"
3153 			   "}";
3154 	}
3155 
Run()3156 	virtual long Run()
3157 	{
3158 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3159 		glBindAttribLocation(program, 0, "position");
3160 		LinkProgram(program);
3161 
3162 		long error = NO_ERROR;
3163 
3164 		GLuint  index = glGetProgramResourceIndex(program, GL_UNIFORM, "someLongName");
3165 		GLsizei length;
3166 		GLchar  buff[3] = { 'a', 'b', 'c' };
3167 		glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, NULL);
3168 		glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, buff);
3169 		if (buff[0] != 'a' || buff[1] != 'b' || buff[2] != 'c')
3170 		{
3171 			m_context.getTestContext().getLog()
3172 				<< tcu::TestLog::Message << "ERROR: buff has changed" << tcu::TestLog::EndMessage;
3173 			error = ERROR;
3174 		}
3175 		glGetProgramResourceName(program, GL_UNIFORM, index, 2, &length, buff);
3176 		if (buff[0] != 's' || buff[1] != '\0' || buff[2] != 'c')
3177 		{
3178 			m_context.getTestContext().getLog()
3179 				<< tcu::TestLog::Message << "ERROR: buff different then expected" << tcu::TestLog::EndMessage;
3180 			error = ERROR;
3181 		}
3182 		if (length != 1)
3183 		{
3184 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 1, got "
3185 												<< length << tcu::TestLog::EndMessage;
3186 			error = ERROR;
3187 		}
3188 
3189 		GLint  params[3] = { 1, 2, 3 };
3190 		GLenum props[]   = { GL_NAME_LENGTH,
3191 						   GL_TYPE,
3192 						   GL_ARRAY_SIZE,
3193 						   GL_OFFSET,
3194 						   GL_BLOCK_INDEX,
3195 						   GL_ARRAY_STRIDE,
3196 						   GL_MATRIX_STRIDE,
3197 						   GL_IS_ROW_MAJOR,
3198 						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
3199 						   GL_REFERENCED_BY_COMPUTE_SHADER,
3200 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
3201 						   GL_REFERENCED_BY_VERTEX_SHADER,
3202 						   GL_LOCATION };
3203 		glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, NULL);
3204 		glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, params);
3205 		if (params[0] != 1 || params[1] != 2 || params[2] != 3)
3206 		{
3207 			m_context.getTestContext().getLog()
3208 				<< tcu::TestLog::Message << "ERROR: params has changed" << tcu::TestLog::EndMessage;
3209 			error = ERROR;
3210 		}
3211 		glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 2, &length, params);
3212 		if (params[0] != 13 || params[1] != 35666 || params[2] != 3)
3213 		{
3214 			m_context.getTestContext().getLog()
3215 				<< tcu::TestLog::Message << "ERROR: params has incorrect values" << tcu::TestLog::EndMessage;
3216 			error = ERROR;
3217 		}
3218 		if (length != 2)
3219 		{
3220 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 2, got "
3221 												<< length << tcu::TestLog::EndMessage;
3222 			error = ERROR;
3223 		}
3224 
3225 		glDeleteProgram(program);
3226 		return error;
3227 	}
3228 };
3229 
3230 class NoLocations : public SimpleShaders
3231 {
3232 
Title()3233 	virtual std::string Title()
3234 	{
3235 		return "No Locations Test";
3236 	}
3237 
ShadersDesc()3238 	virtual std::string ShadersDesc()
3239 	{
3240 		return "fragment and vertex shaders with no locations set";
3241 	}
3242 
VertexShader()3243 	virtual std::string VertexShader()
3244 	{
3245 		return "#version 310 es                      \n"
3246 			   "in vec4 a;                           \n"
3247 			   "in vec4 b;                           \n"
3248 			   "in vec4 c;                           \n"
3249 			   "in vec4 d;                           \n"
3250 			   "void main(void)                      \n"
3251 			   "{                                    \n"
3252 			   "    gl_Position = a + b + c + d;     \n"
3253 			   "}";
3254 	}
3255 
3256 	// fragment shader outputs need an explicit location per spec
FragmentShader()3257 	virtual std::string FragmentShader()
3258 	{
3259 		return "#version 310 es                \n"
3260 			   "layout (location=0) out mediump vec4 a;            \n"
3261 			   "layout (location=1) out mediump vec4 b;            \n"
3262 			   "layout (location=2) out mediump vec4 c;            \n"
3263 			   "layout (location=3) out mediump vec4 d[1];         \n"
3264 			   "void main() {                  \n"
3265 			   "    a = vec4(0, 1, 0, 1);      \n"
3266 			   "    b = vec4(0, 1, 0, 1);      \n"
3267 			   "    c = vec4(0, 1, 0, 1);      \n"
3268 			   "    d[0] = vec4(0, 1, 0, 1);   \n"
3269 			   "}";
3270 	}
3271 
Run()3272 	virtual long Run()
3273 	{
3274 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3275 		glBindAttribLocation(program, 0, "position");
3276 		glLinkProgram(program);
3277 
3278 		long error = NO_ERROR;
3279 
3280 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 4, error);
3281 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error);
3282 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 4, error);
3283 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
3284 
3285 		std::map<std::string, GLuint> indicesI;
3286 		std::map<std::string, GLuint> indicesO;
3287 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "a", error);
3288 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "b", error);
3289 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "c", error);
3290 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "d", error);
3291 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "a", error);
3292 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "b", error);
3293 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "c", error);
3294 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "d[0]", error);
3295 
3296 		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["a"], "a", error);
3297 		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["b"], "b", error);
3298 		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["c"], "c", error);
3299 		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["d"], "d", error);
3300 		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["a"], "a", error);
3301 		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
3302 		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["c"], "c", error);
3303 		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], "d[0]", error);
3304 
3305 		std::map<std::string, GLint> locationsI;
3306 		std::map<std::string, GLint> locationsO;
3307 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "a", error);
3308 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "b", error);
3309 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "c", error);
3310 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "d", error);
3311 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "a", error);
3312 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "b", error);
3313 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "c", error);
3314 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "d[0]", error);
3315 
3316 		GLenum props[] = { GL_NAME_LENGTH,
3317 						   GL_TYPE,
3318 						   GL_ARRAY_SIZE,
3319 						   GL_REFERENCED_BY_COMPUTE_SHADER,
3320 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
3321 						   GL_REFERENCED_BY_VERTEX_SHADER };
3322 		GLint expected[] = { 2, 35666, 1, 0, 0, 1 };
3323 		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["a"], 6, props, 6, expected, error);
3324 		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["b"], 6, props, 6, expected, error);
3325 		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["d"], 6, props, 6, expected, error);
3326 		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["c"], 6, props, 6, expected, error);
3327 		GLint expected3[] = { 2, 35666, 1, 0, 1, 0 };
3328 		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["a"], 6, props, 6, expected3, error);
3329 		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["b"], 6, props, 6, expected3, error);
3330 		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["c"], 6, props, 6, expected3, error);
3331 		GLint expected4[] = { 5, 35666, 1, 0, 1, 0 };
3332 		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], 6, props, 6, expected4, error);
3333 
3334 		glDeleteProgram(program);
3335 		return error;
3336 	}
3337 };
3338 
3339 class OutputBuiltIn : public SimpleShaders
3340 {
3341 
Title()3342 	virtual std::string Title()
3343 	{
3344 		return "Output Built-ins Test";
3345 	}
3346 
ShadersDesc()3347 	virtual std::string ShadersDesc()
3348 	{
3349 		return "fragment shader using built-in variables and a fallthrough vertex shader";
3350 	}
3351 
Expectations()3352 	virtual std::string Expectations()
3353 	{
3354 		return ".\n\n In this case we ask for information about built-in variables for the output interface.";
3355 	}
3356 
FragmentShader()3357 	virtual std::string FragmentShader()
3358 	{
3359 		return "#version 310 es                            \n"
3360 			   "void main(void)                            \n"
3361 			   "{                                          \n"
3362 			   "    gl_FragDepth = 0.1;                    \n"
3363 			   "}";
3364 	}
3365 
Run()3366 	virtual long Run()
3367 	{
3368 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), true);
3369 
3370 		long error = NO_ERROR;
3371 
3372 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
3373 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 13, error);
3374 
3375 		std::map<std::string, GLuint> indices;
3376 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "gl_FragDepth", error);
3377 
3378 		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], "gl_FragDepth", error);
3379 
3380 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_FragDepth", -1, error);
3381 
3382 		GLenum props[] = { GL_NAME_LENGTH,
3383 						   GL_TYPE,
3384 						   GL_ARRAY_SIZE,
3385 						   GL_REFERENCED_BY_COMPUTE_SHADER,
3386 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
3387 						   GL_REFERENCED_BY_VERTEX_SHADER,
3388 						   GL_LOCATION };
3389 		GLint expected[] = { 13, 5126, 1, 0, 1, 0, -1 };
3390 		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], DE_LENGTH_OF_ARRAY(props),
3391 								   props, DE_LENGTH_OF_ARRAY(expected), expected, error);
3392 
3393 		glDeleteProgram(program);
3394 		return error;
3395 	}
3396 };
3397 
3398 class QueryNotUsed : public SimpleShaders
3399 {
3400 
Title()3401 	virtual std::string Title()
3402 	{
3403 		return "Query Not Used Test";
3404 	}
3405 
PassCriteria()3406 	virtual std::string PassCriteria()
3407 	{
3408 		return "Data from queries matches the not used program.";
3409 	}
3410 
Purpose()3411 	virtual std::string Purpose()
3412 	{
3413 		return "Verify that program parameter works correctly and proper program is queried when different program is "
3414 			   "used.";
3415 	}
3416 
Method()3417 	virtual std::string Method()
3418 	{
3419 		return "Create 2 programs, use one of them and query the other, verify the results.";
3420 	}
3421 
VertexShader2()3422 	virtual std::string VertexShader2()
3423 	{
3424 		return "#version 310 es                      \n"
3425 			   "in mediump vec4 p;                   \n"
3426 			   "void main(void)                      \n"
3427 			   "{                                    \n"
3428 			   "    gl_Position = p;                 \n"
3429 			   "}";
3430 	}
3431 
FragmentShader2()3432 	virtual std::string FragmentShader2()
3433 	{
3434 		return "#version 310 es                \n"
3435 			   "out mediump vec4 c;            \n"
3436 			   "void main() {                  \n"
3437 			   "    c = vec4(0., 1., 0., 1.);  \n"
3438 			   "}";
3439 	}
3440 
Run()3441 	virtual long Run()
3442 	{
3443 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3444 		LinkProgram(program);
3445 
3446 		GLuint program2 = CreateProgram(VertexShader2().c_str(), FragmentShader2().c_str(), false);
3447 		LinkProgram(program2);
3448 		glUseProgram(program2);
3449 
3450 		long error = NO_ERROR;
3451 
3452 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
3453 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
3454 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
3455 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
3456 
3457 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
3458 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
3459 
3460 		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
3461 		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
3462 
3463 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
3464 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
3465 
3466 		GLenum props[] = { GL_NAME_LENGTH,
3467 						   GL_TYPE,
3468 						   GL_ARRAY_SIZE,
3469 						   GL_REFERENCED_BY_COMPUTE_SHADER,
3470 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
3471 						   GL_REFERENCED_BY_VERTEX_SHADER,
3472 						   GL_LOCATION };
3473 		GLint expected[] = { 9, 35666, 1, 0, 0, 1, 0 };
3474 		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, DE_LENGTH_OF_ARRAY(props), props,
3475 								   DE_LENGTH_OF_ARRAY(expected), expected, error);
3476 
3477 		GLenum props2[] = { GL_NAME_LENGTH,
3478 							GL_TYPE,
3479 							GL_ARRAY_SIZE,
3480 							GL_REFERENCED_BY_COMPUTE_SHADER,
3481 							GL_REFERENCED_BY_FRAGMENT_SHADER,
3482 							GL_REFERENCED_BY_VERTEX_SHADER,
3483 							GL_LOCATION };
3484 		GLint expected2[] = { 6, 35666, 1, 0, 1, 0, 0 };
3485 		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 7, props2, 7, expected2, error);
3486 
3487 		glDeleteProgram(program);
3488 		glDeleteProgram(program2);
3489 		return error;
3490 	}
3491 };
3492 
3493 class RelinkFailure : public SimpleShaders
3494 {
3495 
Title()3496 	virtual std::string Title()
3497 	{
3498 		return "Relink Failure Test";
3499 	}
3500 
PassCriteria()3501 	virtual std::string PassCriteria()
3502 	{
3503 		return "INVALID_OPERATION is generated when asking for locations after failed link.";
3504 	}
3505 
Purpose()3506 	virtual std::string Purpose()
3507 	{
3508 		return "Verify that queries behave correctly after failed relink of a program.";
3509 	}
3510 
Method()3511 	virtual std::string Method()
3512 	{
3513 		return "Create a program, use it, relink with failure and then verify that INVALID_OPERATION is returned when "
3514 			   "asking for locations.";
3515 	}
3516 
VertexShader()3517 	virtual std::string VertexShader()
3518 	{
3519 		return "#version 310 es                               \n"
3520 			   "in mediump vec4 position;                     \n"
3521 			   "in mediump vec3 pos;                          \n"
3522 			   "void main(void)                               \n"
3523 			   "{                                             \n"
3524 			   "    gl_Position = position + vec4(pos, 1.);   \n"
3525 			   "}";
3526 	}
3527 
Run()3528 	virtual long Run()
3529 	{
3530 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3531 		glBindAttribLocation(program, 0, "position");
3532 		glBindAttribLocation(program, 1, "pos");
3533 		LinkProgram(program);
3534 
3535 		long error = NO_ERROR;
3536 
3537 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", 1, error);
3538 		glUseProgram(program);
3539 
3540 		tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
3541 						   tcu::Vec4(1, -1, 0, 1) };
3542 		GLuint vao, vbuf;
3543 		glGenVertexArrays(1, &vao);
3544 		glBindVertexArray(vao);
3545 		glGenBuffers(1, &vbuf);
3546 		glBindBuffer(GL_ARRAY_BUFFER, vbuf);
3547 		glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
3548 		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
3549 		glEnableVertexAttribArray(0);
3550 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3551 
3552 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3553 		glDisableVertexAttribArray(0);
3554 		glDeleteVertexArrays(1, &vao);
3555 		glBindBuffer(GL_ARRAY_BUFFER, 0);
3556 		glDeleteBuffers(1, &vbuf);
3557 
3558 		glBindAttribLocation(program, 0, "pos");
3559 		glBindAttribLocation(program, 0, "position");
3560 		const char* varyings[2] = { "q", "z" };
3561 		glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
3562 		LinkProgram(program);
3563 
3564 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
3565 		ExpectError(GL_INVALID_OPERATION, error);
3566 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", -1, error);
3567 		ExpectError(GL_INVALID_OPERATION, error);
3568 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
3569 		ExpectError(GL_INVALID_OPERATION, error);
3570 
3571 		glDeleteProgram(program);
3572 		return error;
3573 	}
3574 };
3575 
3576 class LinkFailure : public SimpleShaders
3577 {
3578 
Title()3579 	virtual std::string Title()
3580 	{
3581 		return "Link Failure Test";
3582 	}
3583 
PassCriteria()3584 	virtual std::string PassCriteria()
3585 	{
3586 		return "INVALID_OPERATION is generated when asking for locations after failed link.";
3587 	}
3588 
Purpose()3589 	virtual std::string Purpose()
3590 	{
3591 		return "Verify that queries behave correctly after failed relink of a program with changed sources.";
3592 	}
3593 
Method()3594 	virtual std::string Method()
3595 	{
3596 		return "Create a program, use it, relink with failure using different sources and then \n"
3597 			   "verify that INVALID_OPERATION is returned when asking for locations.";
3598 	}
3599 
VertexShader_prop()3600 	virtual const char* VertexShader_prop()
3601 	{
3602 		return "#version 310 es                      \n"
3603 			   "in mediump vec4 posit;               \n"
3604 			   "in mediump vec4 p;                   \n"
3605 			   "void main(void)                      \n"
3606 			   "{                                    \n"
3607 			   "    gl_Position = p + posit;         \n"
3608 			   "}";
3609 	}
3610 
FragmentShader_prop()3611 	virtual const char* FragmentShader_prop()
3612 	{
3613 		return "#version 310 es                    \n"
3614 			   "out mediump vec4 color;            \n"
3615 			   "void main() {                      \n"
3616 			   "    color = vec4(0., 1., 0., 1.);  \n"
3617 			   "}";
3618 	}
3619 
VertexShader_fail()3620 	virtual const char* VertexShader_fail()
3621 	{
3622 		return "#version 310 es                      \n"
3623 			   "in mediump vec4 position;            \n"
3624 			   "void main(void)                      \n"
3625 			   "{                                    \n"
3626 			   "    gl_Position = position;          \n"
3627 			   "}";
3628 	}
3629 
Run()3630 	virtual long Run()
3631 	{
3632 		const GLuint program = glCreateProgram();
3633 		const char*  src_vs  = VertexShader_prop();
3634 		const char*  src_fs  = FragmentShader_prop();
3635 		const char*  src_vsh = VertexShader_fail();
3636 
3637 		GLuint sh1 = glCreateShader(GL_VERTEX_SHADER);
3638 		glAttachShader(program, sh1);
3639 		glDeleteShader(sh1);
3640 		glShaderSource(sh1, 1, &src_vs, NULL);
3641 		glCompileShader(sh1);
3642 
3643 		GLuint sh2 = glCreateShader(GL_FRAGMENT_SHADER);
3644 		glAttachShader(program, sh2);
3645 		glDeleteShader(sh2);
3646 		glShaderSource(sh2, 1, &src_fs, NULL);
3647 		glCompileShader(sh2);
3648 
3649 		glBindAttribLocation(program, 0, "p");
3650 		glBindAttribLocation(program, 1, "posit");
3651 		LinkProgram(program);
3652 
3653 		long error = NO_ERROR;
3654 
3655 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "posit", 1, error);
3656 		glUseProgram(program);
3657 
3658 		tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
3659 						   tcu::Vec4(1, -1, 0, 1) };
3660 		GLuint vao, vbuf;
3661 		glGenVertexArrays(1, &vao);
3662 		glBindVertexArray(vao);
3663 		glGenBuffers(1, &vbuf);
3664 		glBindBuffer(GL_ARRAY_BUFFER, vbuf);
3665 		glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
3666 		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
3667 		glEnableVertexAttribArray(0);
3668 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3669 
3670 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3671 		glDisableVertexAttribArray(0);
3672 		glDeleteVertexArrays(1, &vao);
3673 		glBindBuffer(GL_ARRAY_BUFFER, 0);
3674 		glDeleteBuffers(1, &vbuf);
3675 
3676 		glDetachShader(program, sh1);
3677 		GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
3678 		glAttachShader(program, vsh);
3679 		glDeleteShader(vsh);
3680 		glShaderSource(vsh, 1, &src_vsh, NULL);
3681 		glCompileShader(vsh);
3682 		const char* varyings[2] = { "q", "z" };
3683 		glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
3684 		LinkProgram(program);
3685 
3686 		GLint res;
3687 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
3688 		ExpectError(GL_INVALID_OPERATION, error);
3689 		glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
3690 		if (res != 0 && res != 1)
3691 		{
3692 			m_context.getTestContext().getLog()
3693 				<< tcu::TestLog::Message << "Error, expected 0 or 1 active resources, got: " << res
3694 				<< tcu::TestLog::EndMessage;
3695 			error = ERROR;
3696 		}
3697 		glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, &res);
3698 		if (res != 0 && res != 9)
3699 		{
3700 			m_context.getTestContext().getLog()
3701 				<< tcu::TestLog::Message << "Error, expected 1 or 9 GL_MAX_NAME_LENGTH, got: " << res
3702 				<< tcu::TestLog::EndMessage;
3703 			error = ERROR;
3704 		}
3705 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
3706 		ExpectError(GL_INVALID_OPERATION, error);
3707 
3708 		glDeleteProgram(program);
3709 		return error;
3710 	}
3711 };
3712 }
3713 
ProgramInterfaceQueryTests(glcts::Context & context)3714 ProgramInterfaceQueryTests::ProgramInterfaceQueryTests(glcts::Context& context)
3715 	: TestCaseGroup(context, "program_interface_query", "")
3716 {
3717 }
3718 
~ProgramInterfaceQueryTests(void)3719 ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests(void)
3720 {
3721 }
3722 
init()3723 void ProgramInterfaceQueryTests::init()
3724 {
3725 	using namespace glcts;
3726 	addChild(new TestSubcase(m_context, "empty-shaders", TestSubcase::Create<NoShaders>));
3727 	addChild(new TestSubcase(m_context, "simple-shaders", TestSubcase::Create<SimpleShaders>));
3728 	addChild(new TestSubcase(m_context, "input-types", TestSubcase::Create<InputTypes>));
3729 	addChild(new TestSubcase(m_context, "input-built-in", TestSubcase::Create<InputBuiltIn>));
3730 	addChild(new TestSubcase(m_context, "input-layout", TestSubcase::Create<InputLayout>));
3731 	addChild(new TestSubcase(m_context, "output-layout", TestSubcase::Create<OutputLayout>));
3732 	addChild(new TestSubcase(m_context, "output-built-in", TestSubcase::Create<OutputBuiltIn>));
3733 	addChild(new TestSubcase(m_context, "uniform-simple", TestSubcase::Create<UniformSimple>));
3734 	addChild(new TestSubcase(m_context, "uniform-types", TestSubcase::Create<UniformTypes>));
3735 	addChild(new TestSubcase(m_context, "uniform-block-types", TestSubcase::Create<UniformBlockTypes>));
3736 	addChild(new TestSubcase(m_context, "uniform-block-array", TestSubcase::Create<UniformBlockArray>));
3737 	addChild(new TestSubcase(m_context, "transform-feedback-types", TestSubcase::Create<TransformFeedbackTypes>));
3738 	addChild(new TestSubcase(m_context, "transform-feedback-types-full-array-capture",
3739 							 TestSubcase::Create<TransformFeedbackTypesFullArrayCapture>));
3740 	addChild(new TestSubcase(m_context, "atomic-counters", TestSubcase::Create<AtomicCounterSimple>));
3741 	addChild(
3742 		new TestSubcase(m_context, "atomic-counters-one-buffer", TestSubcase::Create<AtomicCounterSimpleOneBuffer>));
3743 	addChild(new TestSubcase(m_context, "ssb-types", TestSubcase::Create<ShaderStorageBlock>));
3744 	addChild(new TestSubcase(m_context, "null-length", TestSubcase::Create<NullLength>));
3745 	addChild(new TestSubcase(m_context, "arrays-of-arrays", TestSubcase::Create<ArraysOfArrays>));
3746 	addChild(new TestSubcase(m_context, "top-level-array", TestSubcase::Create<TopLevelArray>));
3747 	addChild(new TestSubcase(m_context, "separate-programs-vertex", TestSubcase::Create<SeparateProgramsVertex>));
3748 	addChild(new TestSubcase(m_context, "separate-programs-fragment", TestSubcase::Create<SeparateProgramsFragment>));
3749 	addChild(new TestSubcase(m_context, "uniform-block", TestSubcase::Create<UniformBlockAdvanced>));
3750 	addChild(new TestSubcase(m_context, "array-names", TestSubcase::Create<ArrayNames>));
3751 	addChild(new TestSubcase(m_context, "buff-length", TestSubcase::Create<BuffLength>));
3752 	addChild(new TestSubcase(m_context, "no-locations", TestSubcase::Create<NoLocations>));
3753 	addChild(new TestSubcase(m_context, "query-not-used", TestSubcase::Create<QueryNotUsed>));
3754 	addChild(new TestSubcase(m_context, "relink-failure", TestSubcase::Create<RelinkFailure>));
3755 	addChild(new TestSubcase(m_context, "link-failure", TestSubcase::Create<LinkFailure>));
3756 	addChild(new TestSubcase(m_context, "compute-shader", TestSubcase::Create<ComputeShaderTest>));
3757 	addChild(new TestSubcase(m_context, "invalid-value", TestSubcase::Create<InvalidValueTest>));
3758 	addChild(new TestSubcase(m_context, "invalid-operation", TestSubcase::Create<InvalidOperationTest>));
3759 	addChild(new TestSubcase(m_context, "invalid-enum", TestSubcase::Create<InvalidEnumTest>));
3760 }
3761 }
3762