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