Home | History | Annotate | Download | only in gles31
      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:
     43 	virtual ~PIQBase()
     44 	{
     45 	}
     46 
     47 	virtual std::string PassCriteria()
     48 	{
     49 		return "All called functions return expected values.";
     50 	}
     51 
     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 
     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 
     69 	virtual long Cleanup()
     70 	{
     71 		glUseProgram(0);
     72 		return NO_ERROR;
     73 	}
     74 
     75 	virtual long Setup()
     76 	{
     77 		return NO_ERROR;
     78 	}
     79 
     80 protected:
     81 	void LinkProgram(GLuint program)
     82 	{
     83 		glLinkProgram(program);
     84 		GLsizei length;
     85 		GLchar  log[1024];
     86 		glGetProgramInfoLog(program, sizeof(log), &length, log);
     87 		if (length > 1)
     88 		{
     89 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
     90 												<< log << tcu::TestLog::EndMessage;
     91 		}
     92 	}
     93 
     94 	GLuint CreateProgram(const char* src_vs, const char* src_fs, bool link)
     95 	{
     96 		const GLuint p = glCreateProgram();
     97 
     98 		if (src_vs)
     99 		{
    100 			GLuint sh = glCreateShader(GL_VERTEX_SHADER);
    101 			glAttachShader(p, sh);
    102 			glDeleteShader(sh);
    103 			glShaderSource(sh, 1, &src_vs, NULL);
    104 			glCompileShader(sh);
    105 		}
    106 		if (src_fs)
    107 		{
    108 			GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
    109 			glAttachShader(p, sh);
    110 			glDeleteShader(sh);
    111 			glShaderSource(sh, 1, &src_fs, NULL);
    112 			glCompileShader(sh);
    113 		}
    114 		if (link)
    115 		{
    116 			LinkProgram(p);
    117 		}
    118 		return p;
    119 	}
    120 
    121 	virtual std::string ShadersDesc()
    122 	{
    123 		return "";
    124 	}
    125 
    126 	virtual std::string Expectations()
    127 	{
    128 		return ".";
    129 	}
    130 
    131 	virtual std::string PurposeExt()
    132 	{
    133 		return "";
    134 	}
    135 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    320 	virtual std::string Title()
    321 	{
    322 		return "No Shaders Test";
    323 	}
    324 
    325 	virtual std::string ShadersDesc()
    326 	{
    327 		return "no shaders";
    328 	}
    329 
    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:
    367 	virtual std::string Title()
    368 	{
    369 		return "Simple Shaders Test";
    370 	}
    371 
    372 	virtual std::string ShadersDesc()
    373 	{
    374 		return "fallthrough fragment and vertex shaders";
    375 	}
    376 
    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 
    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 
    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:
    446 	virtual std::string Title()
    447 	{
    448 		return "Compute Shader Test";
    449 	}
    450 
    451 	virtual std::string ShadersDesc()
    452 	{
    453 		return "compute shader";
    454 	}
    455 
    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 
    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 
    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 
    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 
    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 {
    650 	virtual std::string Title()
    651 	{
    652 		return "Input Types Test";
    653 	}
    654 
    655 	virtual std::string ShadersDesc()
    656 	{
    657 		return "vertex shader with different `in` types and a fallthrough fragment shader";
    658 	}
    659 
    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 
    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 
    762 	virtual std::string Title()
    763 	{
    764 		return "Input Built-ins Test";
    765 	}
    766 
    767 	virtual std::string ShadersDesc()
    768 	{
    769 		return "vertex shader using built-in variables and a fallthrough fragment shader";
    770 	}
    771 
    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 
    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 
    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 {
    825 	virtual std::string Title()
    826 	{
    827 		return "Input Layout Test";
    828 	}
    829 
    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 
    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 
    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 {
    927 	virtual std::string Title()
    928 	{
    929 		return "Output Layout Test";
    930 	}
    931 
    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 
    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 
    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 {
    999 	virtual std::string Title()
   1000 	{
   1001 		return "Uniform Simple Test";
   1002 	}
   1003 
   1004 	virtual std::string ShadersDesc()
   1005 	{
   1006 		return "fallthrough fragment and vertex shaders with uniforms used";
   1007 	}
   1008 
   1009 	virtual std::string PurposeExt()
   1010 	{
   1011 		return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.";
   1012 	}
   1013 
   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 
   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 
   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 {
   1084 	virtual std::string Title()
   1085 	{
   1086 		return "Uniform Types Test";
   1087 	}
   1088 
   1089 	virtual std::string ShadersDesc()
   1090 	{
   1091 		return "fallthrough fragment and vertex shaders with different uniform types used";
   1092 	}
   1093 
   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 
   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 
   1119 	virtual std::string FragmentShader()
   1120 	{
   1121 		return "#version 310 es                \n"
   1122 			   "struct U {                     \n"
   1123 			   "   bool a[3];                  \n"
   1124 			   "   mediump vec4 b;                     \n"
   1125 			   "   mediump mat3 c;                     \n"
   1126 			   "   mediump float d[2];                 \n"
   1127 			   "};                             \n"
   1128 			   "struct UU {                    \n"
   1129 			   "   U a;                        \n"
   1130 			   "   U b[2];                     \n"
   1131 			   "   uvec2 c;                    \n"
   1132 			   "};                             \n"
   1133 			   "uniform mediump mat4 d;                \n"
   1134 			   "uniform mediump mat3 e;                \n"
   1135 			   "uniform mediump float h;               \n"
   1136 			   "uniform int f;                 \n"
   1137 			   "uniform U j;                   \n"
   1138 			   "uniform UU k;                  \n"
   1139 			   "uniform UU l[3];               \n"
   1140 			   "out mediump vec4 color;                \n"
   1141 			   "void main() {                  \n"
   1142 			   "    mediump float tmp;                 \n"
   1143 			   "    tmp = h + float(f) + e[2][2];           \n"
   1144 			   "    tmp = tmp + d[0][0] + j.b.x;     \n"
   1145 			   "    tmp = tmp + k.b[0].c[0][0];      \n"
   1146 			   "    tmp = tmp + l[2].a.c[0][1];      \n"
   1147 			   "    tmp = tmp + l[2].b[1].d[0];      \n"
   1148 			   "    tmp = tmp + float(l[0].c.x);            \n"
   1149 			   "    color = vec4(0, 1, 0, 1) * tmp;  \n"
   1150 			   "}";
   1151 	}
   1152 
   1153 	virtual long Run()
   1154 	{
   1155 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   1156 		glBindAttribLocation(program, 0, "position");
   1157 		LinkProgram(program);
   1158 
   1159 		long error = NO_ERROR;
   1160 
   1161 		// only active structure members
   1162 		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
   1163 									GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
   1164 		// l[2].b[1].d[0] and \0
   1165 		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 15, error);
   1166 
   1167 		std::map<std::string, GLuint> indices;
   1168 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a", error);
   1169 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "b", error);
   1170 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "c", error);
   1171 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "d", error);
   1172 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "e", error);
   1173 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "f", error);
   1174 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "g", error);
   1175 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "h", error);
   1176 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "i", error);
   1177 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "j.b", error);
   1178 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "k.b[0].c", error);
   1179 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[0].c", error);
   1180 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].b[1].d[0]", error);
   1181 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].a.c", error);
   1182 
   1183 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a"], "a", error);
   1184 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["b"], "b", error);
   1185 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["c"], "c[0]", error);
   1186 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["d"], "d", error);
   1187 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["e"], "e", error);
   1188 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["f"], "f", error);
   1189 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["g"], "g[0]", error);
   1190 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["h"], "h", error);
   1191 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["i"], "i", error);
   1192 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["j.b"], "j.b", error);
   1193 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["k.b[0].c"], "k.b[0].c", error);
   1194 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[0].c"], "l[0].c", error);
   1195 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], "l[2].b[1].d[0]", error);
   1196 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].a.c"], "l[2].a.c", error);
   1197 
   1198 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
   1199 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", glGetUniformLocation(program, "b"), error);
   1200 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", glGetUniformLocation(program, "c"), error);
   1201 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", glGetUniformLocation(program, "d"), error);
   1202 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", glGetUniformLocation(program, "e"), error);
   1203 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "f", glGetUniformLocation(program, "f"), error);
   1204 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "g", glGetUniformLocation(program, "g"), error);
   1205 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "h", glGetUniformLocation(program, "h"), error);
   1206 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "i", glGetUniformLocation(program, "i"), error);
   1207 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "j.b", glGetUniformLocation(program, "j.b"), error);
   1208 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "k.b[0].c", glGetUniformLocation(program, "k.b[0].c"),
   1209 										 error);
   1210 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[0].c", glGetUniformLocation(program, "l[0].c"), error);
   1211 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].b[1].d[0]",
   1212 										 glGetUniformLocation(program, "l[2].b[1].d[0]"), error);
   1213 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].a.c", glGetUniformLocation(program, "l[2].a.c"),
   1214 										 error);
   1215 
   1216 		GLenum props[] = { GL_NAME_LENGTH,
   1217 						   GL_TYPE,
   1218 						   GL_ARRAY_SIZE,
   1219 						   GL_OFFSET,
   1220 						   GL_BLOCK_INDEX,
   1221 						   GL_ARRAY_STRIDE,
   1222 						   GL_MATRIX_STRIDE,
   1223 						   GL_IS_ROW_MAJOR,
   1224 						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
   1225 						   GL_REFERENCED_BY_COMPUTE_SHADER,
   1226 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
   1227 						   GL_REFERENCED_BY_VERTEX_SHADER,
   1228 						   GL_LOCATION };
   1229 		GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "a") };
   1230 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a"], 13, props, 13, expected, error);
   1231 		GLint expected2[] = { 2, 35668, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "b") };
   1232 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["b"], 13, props, 13, expected2, error);
   1233 		GLint expected3[] = { 5, 36294, 3, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "c") };
   1234 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["c"], 13, props, 13, expected3, error);
   1235 		GLint expected4[] = { 2, 35676, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "d") };
   1236 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["d"], 13, props, 13, expected4, error);
   1237 		GLint expected5[] = { 2, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "e") };
   1238 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["e"], 13, props, 13, expected5, error);
   1239 		GLint expected6[] = { 2, 5124, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "f") };
   1240 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["f"], 13, props, 13, expected6, error);
   1241 		GLint expected7[] = { 5, 35674, 8, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "g") };
   1242 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["g"], 13, props, 13, expected7, error);
   1243 		GLint expected8[] = { 2, 5126, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "h") };
   1244 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["h"], 13, props, 13, expected8, error);
   1245 		GLint expected9[] = { 2, 35687, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "i") };
   1246 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["i"], 13, props, 13, expected9, error);
   1247 		GLint expected10[] = { 4, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "j.b") };
   1248 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["j.b"], 13, props, 13, expected10, error);
   1249 		GLint expected11[] = { 9, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "k.b[0].c") };
   1250 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["k.b[0].c"], 13, props, 13, expected11, error);
   1251 		GLint expected12[] = { 7, 36294, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[0].c") };
   1252 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[0].c"], 13, props, 13, expected12, error);
   1253 		GLint expected13[] = {
   1254 			15, 5126, 2, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[2].b[1].d[0]")
   1255 		};
   1256 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], 13, props, 13, expected13, error);
   1257 		GLint expected14[] = { 9, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[2].a.c") };
   1258 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].a.c"], 13, props, 13, expected14, error);
   1259 
   1260 		glDeleteProgram(program);
   1261 		return error;
   1262 	}
   1263 };
   1264 
   1265 class UniformBlockTypes : public PIQBase
   1266 {
   1267 	virtual std::string Title()
   1268 	{
   1269 		return "Uniform Block Types Test";
   1270 	}
   1271 
   1272 	virtual std::string ShadersDesc()
   1273 	{
   1274 		return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
   1275 	}
   1276 
   1277 	virtual std::string PurposeExt()
   1278 	{
   1279 		return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param.\n";
   1280 	}
   1281 
   1282 	virtual std::string VertexShader()
   1283 	{
   1284 		return "#version 310 es                      \n"
   1285 			   "in vec4 position;                    \n"
   1286 			   ""
   1287 			   "uniform SimpleBlock {                \n"
   1288 			   "   mediump mat3x2 a;                         \n"
   1289 			   "   mediump mat4 b;                           \n"
   1290 			   "   vec4 c;                           \n"
   1291 			   "};                                   \n"
   1292 			   ""
   1293 			   "uniform NotSoSimpleBlockk {          \n"
   1294 			   "   ivec2 a[4];                       \n"
   1295 			   "   mediump mat3 b[2];                        \n"
   1296 			   "   mediump mat2 c;                           \n"
   1297 			   "} d;                                         \n"
   1298 			   ""
   1299 			   "void main(void)                                               \n"
   1300 			   "{                                                             \n"
   1301 			   "    mediump float tmp;                                        \n"
   1302 			   "    tmp =  a[0][1] * b[1][2] * c.x;                           \n"
   1303 			   "    tmp = tmp + float(d.a[2].y) + d.b[0][1][1] + d.c[1][1];   \n"
   1304 			   "    gl_Position = position * tmp;                             \n"
   1305 			   "}";
   1306 	}
   1307 
   1308 	virtual std::string FragmentShader()
   1309 	{
   1310 		return "#version 310 es                \n"
   1311 			   "struct U {                     \n"
   1312 			   "   bool a[3];                  \n"
   1313 			   "   mediump vec4 b;                     \n"
   1314 			   "   mediump mat3 c;                     \n"
   1315 			   "   mediump float d[2];                 \n"
   1316 			   "};                             \n"
   1317 			   "struct UU {                    \n"
   1318 			   "   U a;                        \n"
   1319 			   "   U b[2];                     \n"
   1320 			   "   uvec2 c;                    \n"
   1321 			   "};                             \n"
   1322 			   ""
   1323 			   "uniform TrickyBlock {                            \n"
   1324 			   "   UU a[3];                                      \n"
   1325 			   "   mediump mat4 b;                               \n"
   1326 			   "   uint c;                                       \n"
   1327 			   "} e[2];                                          \n"
   1328 			   ""
   1329 			   "out mediump vec4 color;                        \n"
   1330 			   "void main() {                                  \n"
   1331 			   "    mediump float tmp;                         \n"
   1332 			   "    tmp = e[0].a[2].b[0].d[1] * float(e[1].c); \n"
   1333 			   "    color = vec4(0, 1, 0, 1) * tmp;            \n"
   1334 			   "}";
   1335 	}
   1336 
   1337 	virtual long Run()
   1338 	{
   1339 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   1340 		glBindAttribLocation(program, 0, "position");
   1341 		LinkProgram(program);
   1342 
   1343 		long error = NO_ERROR;
   1344 
   1345 		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
   1346 									GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
   1347 		VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, 4, error);
   1348 		VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
   1349 
   1350 		std::map<std::string, GLuint> indicesUB;
   1351 		std::map<std::string, GLuint> indicesU;
   1352 		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "SimpleBlock", error);
   1353 		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "NotSoSimpleBlockk", error);
   1354 		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock", error);
   1355 		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock[1]", error);
   1356 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
   1357 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
   1358 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
   1359 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.a[0]", error);
   1360 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.c", error);
   1361 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.b[0]", error);
   1362 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TrickyBlock.a[2].b[0].d", error);
   1363 
   1364 		glUniformBlockBinding(program, indicesUB["SimpleBlock"], 0);
   1365 		glUniformBlockBinding(program, indicesUB["NotSoSimpleBlockk"], 2);
   1366 		glUniformBlockBinding(program, indicesUB["TrickyBlock"], 3);
   1367 		glUniformBlockBinding(program, indicesUB["TrickyBlock[1]"], 4);
   1368 
   1369 		VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], "SimpleBlock", error);
   1370 		VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], "NotSoSimpleBlockk",
   1371 									 error);
   1372 		VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], "TrickyBlock[0]", error);
   1373 		VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], "TrickyBlock[1]", error);
   1374 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
   1375 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
   1376 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
   1377 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.a[0]"], "NotSoSimpleBlockk.a[0]",
   1378 									 error);
   1379 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.c"], "NotSoSimpleBlockk.c",
   1380 									 error);
   1381 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.b[0]"], "NotSoSimpleBlockk.b[0]",
   1382 									 error);
   1383 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"],
   1384 									 "TrickyBlock.a[2].b[0].d[0]", error);
   1385 
   1386 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
   1387 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
   1388 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
   1389 
   1390 		GLenum props[] = {
   1391 			GL_NAME_LENGTH,
   1392 			GL_BUFFER_BINDING,
   1393 			GL_REFERENCED_BY_COMPUTE_SHADER,
   1394 			GL_REFERENCED_BY_FRAGMENT_SHADER,
   1395 			GL_REFERENCED_BY_VERTEX_SHADER,
   1396 			GL_BUFFER_DATA_SIZE,
   1397 		};
   1398 		GLint size;
   1399 		glGetActiveUniformBlockiv(program, indicesUB["SimpleBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
   1400 		GLint expected[] = { 12, 0, 0, 0, 1, size };
   1401 		VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 6, props, 6, expected, error);
   1402 		glGetActiveUniformBlockiv(program, indicesUB["NotSoSimpleBlockk"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
   1403 		GLint expected2[] = { 18, 2, 0, 0, 1, size };
   1404 		VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 6, props, 6, expected2,
   1405 								   error);
   1406 		glGetActiveUniformBlockiv(program, indicesUB["TrickyBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
   1407 		GLint expected3[] = { 15, 3, 0, 1, 0, size };
   1408 		VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], 6, props, 6, expected3, error);
   1409 		GLint expected4[] = { 15, 4, 0, 1, 0, size };
   1410 		VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], 6, props, 6, expected4,
   1411 								   error);
   1412 
   1413 		GLenum props2[] = { GL_NAME_LENGTH,
   1414 							GL_TYPE,
   1415 							GL_ARRAY_SIZE,
   1416 							GL_BLOCK_INDEX,
   1417 							GL_ARRAY_STRIDE,
   1418 							GL_IS_ROW_MAJOR,
   1419 							GL_ATOMIC_COUNTER_BUFFER_INDEX,
   1420 							GL_REFERENCED_BY_COMPUTE_SHADER,
   1421 							GL_REFERENCED_BY_FRAGMENT_SHADER,
   1422 							GL_REFERENCED_BY_VERTEX_SHADER,
   1423 							GL_LOCATION };
   1424 		GLint expected5[] = { 2, 35687, 1, static_cast<GLint>(indicesUB["SimpleBlock"]), 0, 0, -1, 0, 0, 1, -1 };
   1425 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 11, props2, 11, expected5, error);
   1426 		GLenum props3[] = { GL_NAME_LENGTH,
   1427 							GL_TYPE,
   1428 							GL_ARRAY_SIZE,
   1429 							GL_BLOCK_INDEX,
   1430 							GL_MATRIX_STRIDE,
   1431 							GL_IS_ROW_MAJOR,
   1432 							GL_ATOMIC_COUNTER_BUFFER_INDEX,
   1433 							GL_REFERENCED_BY_COMPUTE_SHADER,
   1434 							GL_REFERENCED_BY_FRAGMENT_SHADER,
   1435 							GL_REFERENCED_BY_VERTEX_SHADER,
   1436 							GL_LOCATION };
   1437 		GLint expected6[] = { 27, 5126, 2, static_cast<GLint>(indicesUB["TrickyBlock"]), 0, 0, -1, 0, 1, 0, -1 };
   1438 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"], 11, props3, 11, expected6,
   1439 								   error);
   1440 
   1441 		GLenum			 prop	= GL_ACTIVE_VARIABLES;
   1442 		const GLsizei	bufSize = 1000;
   1443 		GLsizei			 length;
   1444 		GLint			 param[bufSize];
   1445 		std::set<GLuint> exp;
   1446 		exp.insert(indicesU["a"]);
   1447 		exp.insert(indicesU["b"]);
   1448 		exp.insert(indicesU["c"]);
   1449 		glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 1, &prop, bufSize, &length, param);
   1450 		for (int i = 0; i < length; ++i)
   1451 		{
   1452 			if (exp.find(param[i]) == exp.end())
   1453 			{
   1454 				m_context.getTestContext().getLog()
   1455 					<< tcu::TestLog::Message
   1456 					<< "Unexpected index found in active variables of SimpleBlock: " << param[i]
   1457 					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
   1458 					<< tcu::TestLog::EndMessage;
   1459 				glDeleteProgram(program);
   1460 				return ERROR;
   1461 			}
   1462 			else if (length != 3)
   1463 			{
   1464 				m_context.getTestContext().getLog()
   1465 					<< tcu::TestLog::Message
   1466 					<< "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
   1467 					<< "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
   1468 				glDeleteProgram(program);
   1469 				return ERROR;
   1470 			}
   1471 		}
   1472 		std::set<GLuint> exp2;
   1473 		exp2.insert(indicesU["NotSoSimpleBlockk.a[0]"]);
   1474 		exp2.insert(indicesU["NotSoSimpleBlockk.b[0]"]);
   1475 		exp2.insert(indicesU["NotSoSimpleBlockk.c"]);
   1476 		glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 1, &prop, bufSize, &length,
   1477 							   param);
   1478 		for (int i = 0; i < length; ++i)
   1479 		{
   1480 			if (exp2.find(param[i]) == exp2.end())
   1481 			{
   1482 				m_context.getTestContext().getLog()
   1483 					<< tcu::TestLog::Message
   1484 					<< "Unexpected index found in active variables of NotSoSimpleBlockk: " << param[i]
   1485 					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
   1486 					<< tcu::TestLog::EndMessage;
   1487 				glDeleteProgram(program);
   1488 				return ERROR;
   1489 			}
   1490 			else if (length != 3)
   1491 			{
   1492 				m_context.getTestContext().getLog()
   1493 					<< tcu::TestLog::Message
   1494 					<< "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
   1495 					<< "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
   1496 				glDeleteProgram(program);
   1497 				return ERROR;
   1498 			}
   1499 		}
   1500 
   1501 		GLint res;
   1502 		glGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
   1503 		if (res < 3)
   1504 		{
   1505 			m_context.getTestContext().getLog()
   1506 				<< tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!"
   1507 				<< tcu::TestLog::EndMessage;
   1508 			glDeleteProgram(program);
   1509 			return ERROR;
   1510 		}
   1511 
   1512 		glDeleteProgram(program);
   1513 		return error;
   1514 	}
   1515 };
   1516 
   1517 class TransformFeedbackTypes : public SimpleShaders
   1518 {
   1519 	virtual std::string Title()
   1520 	{
   1521 		return "Transform Feedback Varying Types";
   1522 	}
   1523 
   1524 	virtual std::string ShadersDesc()
   1525 	{
   1526 		return "fallthrough fragment and vertex shaders with different types of out variables used";
   1527 	}
   1528 
   1529 	virtual std::string PurposeExt()
   1530 	{
   1531 		return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n";
   1532 	}
   1533 
   1534 	virtual std::string VertexShader()
   1535 	{
   1536 		return "#version 310 es                      \n"
   1537 			   "in vec4 position;                    \n"
   1538 			   ""
   1539 			   "flat out highp vec4 a;               \n"
   1540 			   "out mediump float b[2];              \n"
   1541 			   "flat out highp uvec2 c;              \n"
   1542 			   "flat out highp uint d;               \n"
   1543 			   "out mediump vec3 e[2];               \n"
   1544 			   "flat out int f;                      \n"
   1545 			   ""
   1546 			   "void main(void)                      \n"
   1547 			   "{                                    \n"
   1548 			   "   vec4 pos;                         \n"
   1549 			   "   a = vec4(1);                      \n"
   1550 			   "   b[0] = 1.1;                       \n"
   1551 			   "   b[1] = 1.1;                       \n"
   1552 			   "   c = uvec2(1u);                    \n"
   1553 			   "   d = 1u;                           \n"
   1554 			   "   e[0] = vec3(1.1);                 \n"
   1555 			   "   e[1] = vec3(1.1);                 \n"
   1556 			   "   f = 1;                            \n"
   1557 			   "   gl_Position = position;           \n"
   1558 			   "}";
   1559 	}
   1560 
   1561 	virtual long Run()
   1562 	{
   1563 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   1564 		glBindAttribLocation(program, 0, "position");
   1565 		const char* varyings[6] = { "a", "b[0]", "b[1]", "c", "d", "e" };
   1566 		glTransformFeedbackVaryings(program, 6, varyings, GL_INTERLEAVED_ATTRIBS);
   1567 		LinkProgram(program);
   1568 
   1569 		long error = NO_ERROR;
   1570 
   1571 		VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 6, error);
   1572 		VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 5, error);
   1573 
   1574 		std::map<std::string, GLuint> indices;
   1575 		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error);
   1576 		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[0]", error);
   1577 		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[1]", error);
   1578 		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error);
   1579 		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error);
   1580 		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error);
   1581 
   1582 		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error);
   1583 		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], "b[0]", error);
   1584 		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], "b[1]", error);
   1585 		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error);
   1586 		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error);
   1587 		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error);
   1588 
   1589 		GLenum props[]	= { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE };
   1590 		GLint  expected[] = { 2, 35666, 1 };
   1591 		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error);
   1592 		GLint expected2[] = { 5, 5126, 1 };
   1593 		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], 3, props, 3, expected2,
   1594 								   error);
   1595 		GLint expected3[] = { 5, 5126, 1 };
   1596 		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], 3, props, 3, expected3,
   1597 								   error);
   1598 		GLint expected4[] = { 2, 36294, 1 };
   1599 		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected4, error);
   1600 		GLint expected5[] = { 2, 5125, 1 };
   1601 		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected5, error);
   1602 		GLint expected6[] = { 2, 35665, 2 };
   1603 		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected6, error);
   1604 
   1605 		glDeleteProgram(program);
   1606 		return error;
   1607 	}
   1608 };
   1609 
   1610 class AtomicCounterSimple : public ComputeShaderTest
   1611 {
   1612 public:
   1613 	virtual std::string Title()
   1614 	{
   1615 		return "Atomic Counter Buffer Simple Test";
   1616 	}
   1617 
   1618 	virtual std::string ShadersDesc()
   1619 	{
   1620 		return "compute shader with atomic counters used";
   1621 	}
   1622 
   1623 	virtual std::string PurposeExt()
   1624 	{
   1625 		return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
   1626 	}
   1627 
   1628 	virtual long Run()
   1629 	{
   1630 
   1631 		GLint max_buffer_bindings = 0;
   1632 		glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings);
   1633 		if (max_buffer_bindings < 6)
   1634 		{
   1635 			OutputNotSupported("Test requires at least 6 atomic counter buffer binding points.");
   1636 			return NOT_SUPPORTED;
   1637 		}
   1638 
   1639 		const char* const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in;  \n"
   1640 									"layout(std430) buffer Output {                  \n"
   1641 									"   mediump vec4 data;                           \n"
   1642 									"} g_out;                                        \n"
   1643 									""
   1644 									"layout (binding = 1, offset = 0) uniform highp atomic_uint a;    \n"
   1645 									"layout (binding = 2, offset = 0) uniform highp atomic_uint b;    \n"
   1646 									"layout (binding = 2, offset = 4) uniform highp atomic_uint c;    \n"
   1647 									"layout (binding = 5, offset = 0) uniform highp atomic_uint d[3]; \n"
   1648 									"layout (binding = 5, offset = 12) uniform highp atomic_uint e;   \n"
   1649 									""
   1650 									"void main() {                                                         \n"
   1651 									"   uint x = atomicCounterIncrement(d[0]) + atomicCounterIncrement(a); \n"
   1652 									"   uint y = atomicCounterIncrement(d[1]) + atomicCounterIncrement(b); \n"
   1653 									"   uint z = atomicCounterIncrement(d[2]) + atomicCounterIncrement(c); \n"
   1654 									"   uint w = atomicCounterIncrement(e);                                \n"
   1655 									"   g_out.data = vec4(float(x), float(y), float(z), float(w));         \n"
   1656 									"}";
   1657 
   1658 		GLuint program = CreateComputeProgram(glsl_cs);
   1659 		glLinkProgram(program);
   1660 		if (!CheckProgram(program))
   1661 		{
   1662 			glDeleteProgram(program);
   1663 			return ERROR;
   1664 		}
   1665 		glUseProgram(program);
   1666 
   1667 		long error = NO_ERROR;
   1668 
   1669 		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 3, error);
   1670 		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 2, error);
   1671 
   1672 		std::map<std::string, GLuint> indicesU;
   1673 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
   1674 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
   1675 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
   1676 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "d", error);
   1677 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "e", error);
   1678 
   1679 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
   1680 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
   1681 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
   1682 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["d"], "d[0]", error);
   1683 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["e"], "e", error);
   1684 
   1685 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
   1686 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
   1687 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
   1688 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", -1, error);
   1689 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", -1, error);
   1690 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[0]", -1, error);
   1691 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[1]", -1, error);
   1692 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[2]", -1, error);
   1693 
   1694 		GLenum		  prop	= GL_ATOMIC_COUNTER_BUFFER_INDEX;
   1695 		const GLsizei bufSize = 1000;
   1696 		GLsizei		  length;
   1697 		GLint		  res;
   1698 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
   1699 
   1700 		GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES, GL_ACTIVE_VARIABLES };
   1701 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
   1702 		GLint expected[] = { 1, 4, 1, static_cast<GLint>(indicesU["a"]) };
   1703 		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 4, props, 4, expected, error);
   1704 
   1705 		GLenum props2[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES };
   1706 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
   1707 		GLint expected2[] = { 2, 8, 2 };
   1708 		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
   1709 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["c"], 1, &prop, bufSize, &length, &res);
   1710 		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
   1711 
   1712 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
   1713 		GLint expected3[] = { 5, 16, 2 };
   1714 		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
   1715 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["e"], 1, &prop, bufSize, &length, &res);
   1716 		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
   1717 
   1718 		GLenum			 prop2 = GL_ACTIVE_VARIABLES;
   1719 		GLint			 param[bufSize];
   1720 		std::set<GLuint> exp;
   1721 		exp.insert(indicesU["b"]);
   1722 		exp.insert(indicesU["c"]);
   1723 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
   1724 		glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
   1725 		for (int i = 0; i < length; ++i)
   1726 		{
   1727 			if (exp.find(param[i]) == exp.end() || length != 2)
   1728 			{
   1729 				m_context.getTestContext().getLog()
   1730 					<< tcu::TestLog::Message << "Length: " << length
   1731 					<< "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
   1732 					<< tcu::TestLog::EndMessage;
   1733 				glDeleteProgram(program);
   1734 				return ERROR;
   1735 			}
   1736 		}
   1737 		std::set<GLuint> exp2;
   1738 		GLint			 param2[bufSize];
   1739 		exp2.insert(indicesU["d"]);
   1740 		exp2.insert(indicesU["e"]);
   1741 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
   1742 		glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param2);
   1743 		for (int i = 0; i < length; ++i)
   1744 		{
   1745 			if (exp2.find(param2[i]) == exp2.end() || length != 2)
   1746 			{
   1747 				m_context.getTestContext().getLog()
   1748 					<< tcu::TestLog::Message << "Length: " << length
   1749 					<< "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param2[i]
   1750 					<< tcu::TestLog::EndMessage;
   1751 				glDeleteProgram(program);
   1752 				return ERROR;
   1753 			}
   1754 		}
   1755 
   1756 		glDeleteProgram(program);
   1757 		return error;
   1758 	}
   1759 };
   1760 
   1761 class AtomicCounterSimpleOneBuffer : public ComputeShaderTest
   1762 {
   1763 public:
   1764 	virtual std::string Title()
   1765 	{
   1766 		return "Atomic Counter Buffer Simple One Buffer Test";
   1767 	}
   1768 
   1769 	virtual std::string ShadersDesc()
   1770 	{
   1771 		return "compute shader with atomic counters used";
   1772 	}
   1773 
   1774 	virtual std::string PurposeExt()
   1775 	{
   1776 		return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
   1777 	}
   1778 
   1779 	virtual long Run()
   1780 	{
   1781 
   1782 		GLint max_buffer_bindings = 0;
   1783 		glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings);
   1784 		if (max_buffer_bindings < 3)
   1785 		{
   1786 			OutputNotSupported("Test requires at least 3 atomic counter buffer binding points.");
   1787 			return NOT_SUPPORTED;
   1788 		}
   1789 
   1790 		const char* const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in;  \n"
   1791 									"layout(std430) buffer Output {                  \n"
   1792 									"   mediump vec4 data;                           \n"
   1793 									"} g_out;                                        \n"
   1794 									""
   1795 									"layout (binding = 0, offset = 0) uniform highp atomic_uint a;    \n"
   1796 									"layout (binding = 0, offset = 4) uniform highp atomic_uint b[3]; \n"
   1797 									"layout (binding = 0, offset = 16) uniform highp atomic_uint c;   \n"
   1798 									""
   1799 									"void main() {                                                         \n"
   1800 									"   uint x = atomicCounterIncrement(b[0]) + atomicCounterIncrement(a); \n"
   1801 									"   uint y = atomicCounterIncrement(b[1]) + atomicCounterIncrement(a); \n"
   1802 									"   uint z = atomicCounterIncrement(b[2]) + atomicCounterIncrement(a); \n"
   1803 									"   uint w = atomicCounterIncrement(c);                                \n"
   1804 									"   g_out.data = vec4(float(x), float(y), float(z), float(w));         \n"
   1805 									"}";
   1806 
   1807 		GLuint program = CreateComputeProgram(glsl_cs);
   1808 		glLinkProgram(program);
   1809 		if (!CheckProgram(program))
   1810 		{
   1811 			glDeleteProgram(program);
   1812 			return ERROR;
   1813 		}
   1814 		glUseProgram(program);
   1815 
   1816 		long error = NO_ERROR;
   1817 
   1818 		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 1, error);
   1819 		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 3, error);
   1820 
   1821 		std::map<std::string, GLuint> indicesU;
   1822 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
   1823 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
   1824 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
   1825 
   1826 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
   1827 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b[0]", error);
   1828 		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
   1829 
   1830 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
   1831 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
   1832 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
   1833 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[0]", -1, error);
   1834 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[1]", -1, error);
   1835 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[2]", -1, error);
   1836 
   1837 		GLenum		  prop	= GL_ATOMIC_COUNTER_BUFFER_INDEX;
   1838 		const GLsizei bufSize = 1000;
   1839 		GLsizei		  length;
   1840 		GLint		  res;
   1841 
   1842 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
   1843 		if (res != 0)
   1844 		{
   1845 			m_context.getTestContext().getLog()
   1846 				<< tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage;
   1847 			glDeleteProgram(program);
   1848 			return ERROR;
   1849 		}
   1850 
   1851 		GLenum props[]	= { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES };
   1852 		GLint  expected[] = { 0, 20, 3 };
   1853 		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props, 3, expected, error);
   1854 
   1855 		GLenum			 prop2 = GL_ACTIVE_VARIABLES;
   1856 		GLint			 param[bufSize];
   1857 		std::set<GLuint> exp;
   1858 		exp.insert(indicesU["a"]);
   1859 		exp.insert(indicesU["b"]);
   1860 		exp.insert(indicesU["c"]);
   1861 
   1862 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
   1863 		if (res != 0)
   1864 		{
   1865 			m_context.getTestContext().getLog()
   1866 				<< tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage;
   1867 			glDeleteProgram(program);
   1868 			return ERROR;
   1869 		}
   1870 
   1871 		glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
   1872 		for (int i = 0; i < length; ++i)
   1873 		{
   1874 			if (exp.find(param[i]) == exp.end() || length != 3)
   1875 			{
   1876 				m_context.getTestContext().getLog()
   1877 					<< tcu::TestLog::Message << "Length: " << length
   1878 					<< "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
   1879 					<< tcu::TestLog::EndMessage;
   1880 				glDeleteProgram(program);
   1881 				return ERROR;
   1882 			}
   1883 		}
   1884 
   1885 		glDeleteProgram(program);
   1886 		return error;
   1887 	}
   1888 };
   1889 
   1890 class InvalidValueTest : public SimpleShaders
   1891 {
   1892 	virtual std::string Title()
   1893 	{
   1894 		return "Invalid Value Test";
   1895 	}
   1896 
   1897 	virtual std::string PassCriteria()
   1898 	{
   1899 		return "GL_INVALID_VALUE error is generated after every function call.";
   1900 	}
   1901 
   1902 	virtual std::string Purpose()
   1903 	{
   1904 		return "Verify that wrong use of functions generates GL_INVALID_VALUE as described in spec.";
   1905 	}
   1906 
   1907 	virtual std::string Method()
   1908 	{
   1909 		return "Call functions with invalid values and check if GL_INVALID_VALUE was generated.";
   1910 	}
   1911 
   1912 	virtual long Run()
   1913 	{
   1914 		long error = NO_ERROR;
   1915 
   1916 		GLint   res;
   1917 		GLsizei len		  = 0;
   1918 		GLchar  name[100] = { '\0' };
   1919 		GLenum  props[1]  = { GL_NAME_LENGTH };
   1920 
   1921 		m_context.getTestContext().getLog()
   1922 			<< tcu::TestLog::Message << "Case 1: <program> not a name of shader/program object"
   1923 			<< tcu::TestLog::EndMessage;
   1924 		glGetProgramInterfaceiv(1337u, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
   1925 		ExpectError(GL_INVALID_VALUE, error);
   1926 		glGetProgramResourceIndex(31337u, GL_PROGRAM_INPUT, "pie");
   1927 		ExpectError(GL_INVALID_VALUE, error);
   1928 		glGetProgramResourceName(1337u, GL_PROGRAM_INPUT, 0, 1024, &len, name);
   1929 		ExpectError(GL_INVALID_VALUE, error);
   1930 		glGetProgramResourceiv(1337u, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
   1931 		ExpectError(GL_INVALID_VALUE, error);
   1932 		glGetProgramResourceLocation(1337u, GL_PROGRAM_INPUT, "pie");
   1933 		ExpectError(GL_INVALID_VALUE, error);
   1934 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage;
   1935 
   1936 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   1937 		glBindAttribLocation(program, 0, "position");
   1938 		LinkProgram(program);
   1939 
   1940 		m_context.getTestContext().getLog()
   1941 			<< tcu::TestLog::Message
   1942 			<< "Case 2: <index> is greater than the number of the active resources in GetProgramResourceName"
   1943 			<< tcu::TestLog::EndMessage;
   1944 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage;
   1945 		glGetProgramResourceName(program, GL_PROGRAM_INPUT, 3000, 1024, &len, name);
   1946 		ExpectError(GL_INVALID_VALUE, error);
   1947 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2: finished" << tcu::TestLog::EndMessage;
   1948 
   1949 		m_context.getTestContext().getLog()
   1950 			<< tcu::TestLog::Message << "Case 3: <propCount> is zero in GetProgramResourceiv"
   1951 			<< tcu::TestLog::EndMessage;
   1952 		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 0, props, 1024, &len, &res);
   1953 		ExpectError(GL_INVALID_VALUE, error);
   1954 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3: finished" << tcu::TestLog::EndMessage;
   1955 
   1956 		std::string str = "position";
   1957 		glGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, -100, NULL, const_cast<char*>(str.c_str()));
   1958 		ExpectError(GL_INVALID_VALUE, error);
   1959 		GLenum prop = GL_NAME_LENGTH;
   1960 		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, &prop, -100, &len, &res);
   1961 		ExpectError(GL_INVALID_VALUE, error);
   1962 
   1963 		glDeleteProgram(program);
   1964 		return error;
   1965 	}
   1966 };
   1967 
   1968 class InvalidEnumTest : public SimpleShaders
   1969 {
   1970 	virtual std::string Title()
   1971 	{
   1972 		return "Invalid Enum Test";
   1973 	}
   1974 
   1975 	virtual std::string PassCriteria()
   1976 	{
   1977 		return "GL_INVALID_ENUM error is generated after every function call.";
   1978 	}
   1979 
   1980 	virtual std::string Purpose()
   1981 	{
   1982 		return "Verify that wrong use of functions generates GL_INVALID_ENUM as described in spec.";
   1983 	}
   1984 
   1985 	virtual std::string Method()
   1986 	{
   1987 		return "Call functions with invalid enums and check if GL_INVALID_ENUM was generated.";
   1988 	}
   1989 
   1990 	// make sure at least one atomic counter resource is active
   1991 	virtual std::string FragmentShader()
   1992 	{
   1993 		return "#version 310 es                                        \n"
   1994 			   "layout (binding = 0, offset = 0) uniform highp atomic_uint a;\n"
   1995 			   "out mediump vec4 outColor;                             \n"
   1996 			   "void main(void) {                                      \n"
   1997 			   "   uint b = atomicCounterIncrement(a);                 \n"
   1998 			   "   outColor = vec4(float(b));                          \n"
   1999 			   "}                                                      \n";
   2000 	}
   2001 
   2002 	virtual long Run()
   2003 	{
   2004 		GLint max_buffers = 0, max_counters = 0;
   2005 		glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &max_buffers);
   2006 		glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, &max_counters);
   2007 		if (max_buffers < 1 || max_counters < 1)
   2008 		{
   2009 			OutputNotSupported("Test requires at least 1 atomic counter.");
   2010 			return NOT_SUPPORTED;
   2011 		}
   2012 
   2013 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   2014 		glBindAttribLocation(program, 0, "position");
   2015 		LinkProgram(program);
   2016 
   2017 		long error = NO_ERROR;
   2018 
   2019 		GLint   res;
   2020 		GLsizei len		  = 0;
   2021 		GLchar  name[100] = { '\0' };
   2022 		GLenum  props[1]  = { GL_TEXTURE_1D };
   2023 
   2024 		m_context.getTestContext().getLog()
   2025 			<< tcu::TestLog::Message << "Case 1: <programInterface> is ATOMIC_COUNTER_BUFFER in "
   2026 										"GetProgramResourceIndex or GetProgramResourceName"
   2027 			<< tcu::TestLog::EndMessage;
   2028 		glGetProgramResourceIndex(program, GL_ATOMIC_COUNTER_BUFFER, name);
   2029 		ExpectError(GL_INVALID_ENUM, error);
   2030 		glGetProgramResourceName(program, GL_ATOMIC_COUNTER_BUFFER, 0, 1024, &len, name);
   2031 		ExpectError(GL_INVALID_ENUM, error);
   2032 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
   2033 
   2034 		m_context.getTestContext().getLog()
   2035 			<< tcu::TestLog::Message
   2036 			<< "Case 2: <props> is not a property name supported by the command GetProgramResourceiv"
   2037 			<< tcu::TestLog::EndMessage;
   2038 		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
   2039 		ExpectError(GL_INVALID_ENUM, error);
   2040 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
   2041 
   2042 		glGetProgramResourceLocation(program, GL_ATOMIC_COUNTER_BUFFER, "position");
   2043 		ExpectError(GL_INVALID_ENUM, error);
   2044 
   2045 		glDeleteProgram(program);
   2046 		return error;
   2047 	}
   2048 };
   2049 
   2050 class InvalidOperationTest : public SimpleShaders
   2051 {
   2052 	virtual std::string Title()
   2053 	{
   2054 		return "Invalid Operation Test";
   2055 	}
   2056 
   2057 	virtual std::string PassCriteria()
   2058 	{
   2059 		return "GL_INVALID_OPERATION error is generated after every function call.";
   2060 	}
   2061 
   2062 	virtual std::string Purpose()
   2063 	{
   2064 		return "Verify that wrong use of functions generates GL_INVALID_OPERATION as described in spec.";
   2065 	}
   2066 
   2067 	virtual std::string Method()
   2068 	{
   2069 		return "Perform invalid operation and check if GL_INVALID_OPERATION was generated.";
   2070 	}
   2071 
   2072 	virtual long Run()
   2073 	{
   2074 		long error = NO_ERROR;
   2075 
   2076 		GLuint program  = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   2077 		GLuint program2 = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   2078 		glBindAttribLocation(program, 0, "position");
   2079 		LinkProgram(program);
   2080 
   2081 		const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
   2082 		GLint		 res;
   2083 		GLsizei		 len	   = 0;
   2084 		GLchar		 name[100] = { '\0' };
   2085 		GLenum		 props[1]  = { GL_OFFSET };
   2086 
   2087 		m_context.getTestContext().getLog()
   2088 			<< tcu::TestLog::Message << "Case 1: <program> is the name of a shader object" << tcu::TestLog::EndMessage;
   2089 		glGetProgramInterfaceiv(sh, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
   2090 		ExpectError(GL_INVALID_OPERATION, error);
   2091 		glGetProgramResourceIndex(sh, GL_PROGRAM_INPUT, "pie");
   2092 		ExpectError(GL_INVALID_OPERATION, error);
   2093 		glGetProgramResourceName(sh, GL_PROGRAM_INPUT, 0, 1024, &len, name);
   2094 		ExpectError(GL_INVALID_OPERATION, error);
   2095 		glGetProgramResourceiv(sh, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
   2096 		ExpectError(GL_INVALID_OPERATION, error);
   2097 		glGetProgramResourceLocation(sh, GL_PROGRAM_INPUT, "pie");
   2098 		ExpectError(GL_INVALID_OPERATION, error);
   2099 		glDeleteShader(sh);
   2100 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
   2101 
   2102 		m_context.getTestContext().getLog()
   2103 			<< tcu::TestLog::Message << "Case 2: <pname> is not supported in GetProgramInterfaceiv"
   2104 			<< tcu::TestLog::EndMessage;
   2105 		glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
   2106 		ExpectError(GL_INVALID_OPERATION, error);
   2107 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
   2108 
   2109 		m_context.getTestContext().getLog()
   2110 			<< tcu::TestLog::Message << "Case 3: <props> is not supported in GetProgramResourceiv"
   2111 			<< tcu::TestLog::EndMessage;
   2112 		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
   2113 		ExpectError(GL_INVALID_OPERATION, error);
   2114 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3 finished" << tcu::TestLog::EndMessage;
   2115 
   2116 		m_context.getTestContext().getLog()
   2117 			<< tcu::TestLog::Message << "Case 4: <program> has not been linked in GetProgramResourceLocation"
   2118 			<< tcu::TestLog::EndMessage;
   2119 		glGetProgramResourceLocation(program2, GL_PROGRAM_INPUT, "pie");
   2120 		ExpectError(GL_INVALID_OPERATION, error);
   2121 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 4 finished" << tcu::TestLog::EndMessage;
   2122 
   2123 		glDeleteProgram(program);
   2124 		glDeleteProgram(program2);
   2125 		return error;
   2126 	}
   2127 };
   2128 
   2129 class ShaderStorageBlock : public ComputeShaderTest
   2130 {
   2131 	virtual std::string Title()
   2132 	{
   2133 		return "Shader Storage Block Test";
   2134 	}
   2135 
   2136 	virtual std::string ShadersDesc()
   2137 	{
   2138 		return "compute shader different types of storage blocks used";
   2139 	}
   2140 
   2141 	virtual std::string PurposeExt()
   2142 	{
   2143 		return "\n\n Purpose is to verify calls using GL_BUFFER_VARIABLE and GL_SHADER_STORAGE_BLOCK as an interface "
   2144 			   "params.\n";
   2145 	}
   2146 
   2147 	virtual std::string ComputeShader()
   2148 	{
   2149 		return "layout(local_size_x = 1, local_size_y = 1) in;  \n"
   2150 			   "layout(std430) buffer Output {                  \n"
   2151 			   "   mediump vec4 data;                           \n"
   2152 			   "} g_out;                                        \n"
   2153 			   ""
   2154 			   "struct U {                     \n"
   2155 			   "   bool a[3];                  \n"
   2156 			   "   mediump vec4 b;                     \n"
   2157 			   "   mediump mat3 c;                     \n"
   2158 			   "   mediump float d[2];                 \n"
   2159 			   "};                             \n"
   2160 			   "struct UU {                    \n"
   2161 			   "   U a;                        \n"
   2162 			   "   U b[2];                     \n"
   2163 			   "   uvec2 c;                    \n"
   2164 			   "};                             \n"
   2165 			   ""
   2166 			   "layout(binding=4) buffer TrickyBuffer {          \n"
   2167 			   "   UU a[3];                                      \n"
   2168 			   "   mediump mat4 b;                               \n"
   2169 			   "   uint c;                                       \n"
   2170 			   "} e[2];                                          \n"
   2171 			   ""
   2172 			   "layout(binding = 0) buffer SimpleBuffer {                \n"
   2173 			   "   mediump mat3x2 a;                                     \n"
   2174 			   "   mediump mat4 b;                                       \n"
   2175 			   "   mediump vec4 c;                                       \n"
   2176 			   "};                                                       \n"
   2177 			   ""
   2178 			   "layout(binding = 1) buffer NotSoSimpleBuffer {           \n"
   2179 			   "   ivec2 a[4];                                           \n"
   2180 			   "   mediump mat3 b[2];                                    \n"
   2181 			   "   mediump mat2 c;                                       \n"
   2182 			   "} d;                                                     \n"
   2183 			   ""
   2184 			   "void main() {                                    \n"
   2185 			   "    mediump float tmp;                           \n"
   2186 			   "    mediump float tmp2;                          \n"
   2187 			   "    tmp = e[0].a[0].b[0].d[0] * float(e[1].c);   \n"
   2188 			   "    tmp2 = a[0][0] * b[0][0] * c.x;                                \n"
   2189 			   "    tmp2 = tmp2 + float(d.a[0].y) + d.b[0][0][0] + d.c[0][0];      \n"
   2190 			   "    g_out.data = vec4(0, 1, 0, 1) * tmp * tmp2;                    \n"
   2191 			   "}";
   2192 	}
   2193 
   2194 	virtual long Run()
   2195 	{
   2196 		GLuint program = CreateComputeProgram(ComputeShader());
   2197 		glLinkProgram(program);
   2198 		if (!CheckProgram(program))
   2199 		{
   2200 			glDeleteProgram(program);
   2201 			return ERROR;
   2202 		}
   2203 		glUseProgram(program);
   2204 
   2205 		long error = NO_ERROR;
   2206 
   2207 		GLint res;
   2208 		VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 28, error);
   2209 		glGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &res);
   2210 		if (res < 7)
   2211 		{
   2212 			m_context.getTestContext().getLog()
   2213 				<< tcu::TestLog::Message
   2214 				<< "Error on: glGetProgramInterfaceiv, if: GL_BUFFER_VARIABLE, param: GL_ACTIVE_RESOURCES\n"
   2215 				<< "Expected value greater or equal to 7, got " << res << tcu::TestLog::EndMessage;
   2216 			glDeleteProgram(program);
   2217 			return ERROR;
   2218 		}
   2219 		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 5, error);
   2220 		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
   2221 
   2222 		std::map<std::string, GLuint> indicesSSB;
   2223 		std::map<std::string, GLuint> indicesBV;
   2224 		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
   2225 		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "NotSoSimpleBuffer", error);
   2226 		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer", error);
   2227 		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer[1]", error);
   2228 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a", error);
   2229 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "b", error);
   2230 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "c", error);
   2231 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.a[0]", error);
   2232 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.c", error);
   2233 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.b[0]", error);
   2234 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.a[0].b[0].d", error);
   2235 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.b", error);
   2236 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.c", error);
   2237 
   2238 		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer",
   2239 									 error);
   2240 		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"],
   2241 									 "NotSoSimpleBuffer", error);
   2242 		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], "TrickyBuffer[0]",
   2243 									 error);
   2244 		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], "TrickyBuffer[1]",
   2245 									 error);
   2246 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
   2247 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["b"], "b", error);
   2248 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["c"], "c", error);
   2249 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.a[0]"],
   2250 									 "NotSoSimpleBuffer.a[0]", error);
   2251 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.c"],
   2252 									 "NotSoSimpleBuffer.c", error);
   2253 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.b[0]"],
   2254 									 "NotSoSimpleBuffer.b[0]", error);
   2255 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"],
   2256 									 "TrickyBuffer.a[0].b[0].d[0]", error);
   2257 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.b"], "TrickyBuffer.b", error);
   2258 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.c"], "TrickyBuffer.c", error);
   2259 
   2260 		GLenum props[] = { GL_NAME_LENGTH,
   2261 						   GL_BUFFER_BINDING,
   2262 						   GL_NUM_ACTIVE_VARIABLES,
   2263 						   GL_REFERENCED_BY_COMPUTE_SHADER,
   2264 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
   2265 						   GL_REFERENCED_BY_VERTEX_SHADER };
   2266 		GLint expected[] = { 13, 0, 3, 1, 0, 0 };
   2267 		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 6, props, 6, expected,
   2268 								   error);
   2269 		GLenum props2[] = { GL_NAME_LENGTH, GL_BUFFER_BINDING, GL_REFERENCED_BY_COMPUTE_SHADER,
   2270 							GL_REFERENCED_BY_FRAGMENT_SHADER, GL_REFERENCED_BY_VERTEX_SHADER };
   2271 		GLint expected2[] = { 18, 1, 1, 0, 0 };
   2272 		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 5, props2, 5,
   2273 								   expected2, error);
   2274 		GLint expected3[] = { 16, 4, 1, 0, 0 };
   2275 		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], 5, props2, 5,
   2276 								   expected3, error);
   2277 		GLint expected4[] = { 16, 5, 1, 0, 0 };
   2278 		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], 5, props2, 5,
   2279 								   expected4, error);
   2280 
   2281 		GLenum props3[] = { GL_NAME_LENGTH,
   2282 							GL_TYPE,
   2283 							GL_ARRAY_SIZE,
   2284 							GL_BLOCK_INDEX,
   2285 							GL_ARRAY_STRIDE,
   2286 							GL_IS_ROW_MAJOR,
   2287 							GL_REFERENCED_BY_COMPUTE_SHADER,
   2288 							GL_REFERENCED_BY_FRAGMENT_SHADER,
   2289 							GL_REFERENCED_BY_VERTEX_SHADER,
   2290 							GL_TOP_LEVEL_ARRAY_SIZE,
   2291 							GL_TOP_LEVEL_ARRAY_STRIDE };
   2292 		GLint expected5[] = { 2, 35687, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 1, 0, 0, 1, 0 };
   2293 		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a"], 11, props3, 11, expected5, error);
   2294 		GLenum props4[] = { GL_NAME_LENGTH,
   2295 							GL_TYPE,
   2296 							GL_ARRAY_SIZE,
   2297 							GL_BLOCK_INDEX,
   2298 							GL_MATRIX_STRIDE,
   2299 							GL_IS_ROW_MAJOR,
   2300 							GL_REFERENCED_BY_COMPUTE_SHADER,
   2301 							GL_REFERENCED_BY_FRAGMENT_SHADER,
   2302 							GL_REFERENCED_BY_VERTEX_SHADER,
   2303 							GL_TOP_LEVEL_ARRAY_SIZE };
   2304 		GLint expected6[] = { 28, 5126, 2, static_cast<GLint>(indicesSSB["TrickyBuffer"]), 0, 0, 1, 0, 0, 3 };
   2305 		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"], 10, props4, 10,
   2306 								   expected6, error);
   2307 
   2308 		GLenum			 prop	= GL_ACTIVE_VARIABLES;
   2309 		const GLsizei	bufSize = 1000;
   2310 		GLsizei			 length;
   2311 		GLint			 param[bufSize];
   2312 		std::set<GLuint> exp;
   2313 		exp.insert(indicesBV["a"]);
   2314 		exp.insert(indicesBV["b"]);
   2315 		exp.insert(indicesBV["c"]);
   2316 		glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 1, &prop, bufSize, &length,
   2317 							   param);
   2318 		for (int i = 0; i < length; ++i)
   2319 		{
   2320 			if (exp.find(param[i]) == exp.end())
   2321 			{
   2322 				m_context.getTestContext().getLog()
   2323 					<< tcu::TestLog::Message
   2324 					<< "Unexpected index found in active variables of SimpleBuffer: " << param[i]
   2325 					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
   2326 					   "GL_SHADER_STORAGE_BLOCK"
   2327 					<< tcu::TestLog::EndMessage;
   2328 				glDeleteProgram(program);
   2329 				return ERROR;
   2330 			}
   2331 			else if (length != 3)
   2332 			{
   2333 				m_context.getTestContext().getLog()
   2334 					<< tcu::TestLog::Message
   2335 					<< "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK"
   2336 					<< "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
   2337 				glDeleteProgram(program);
   2338 				return ERROR;
   2339 			}
   2340 		}
   2341 		std::set<GLuint> exp2;
   2342 		exp2.insert(indicesBV["NotSoSimpleBuffer.a[0]"]);
   2343 		exp2.insert(indicesBV["NotSoSimpleBuffer.b[0]"]);
   2344 		exp2.insert(indicesBV["NotSoSimpleBuffer.c"]);
   2345 		glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 1, &prop, bufSize,
   2346 							   &length, param);
   2347 		for (int i = 0; i < length; ++i)
   2348 		{
   2349 			if (exp2.find(param[i]) == exp2.end())
   2350 			{
   2351 				m_context.getTestContext().getLog()
   2352 					<< tcu::TestLog::Message
   2353 					<< "Unexpected index found in active variables of NotSoSimpleBuffer: " << param[i]
   2354 					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
   2355 					   "GL_SHADER_STORAGE_BLOCK"
   2356 					<< tcu::TestLog::EndMessage;
   2357 				glDeleteProgram(program);
   2358 				return ERROR;
   2359 			}
   2360 			else if (length != 3)
   2361 			{
   2362 				m_context.getTestContext().getLog()
   2363 					<< tcu::TestLog::Message
   2364 					<< "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK"
   2365 					<< param[i] << "\nExpected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
   2366 				glDeleteProgram(program);
   2367 				return ERROR;
   2368 			}
   2369 		}
   2370 
   2371 		glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
   2372 		if (res < 3)
   2373 		{
   2374 			m_context.getTestContext().getLog()
   2375 				<< tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!\n"
   2376 				<< "Call: glGetProgramInterfaceiv, interface: GL_SHADER_STORAGE_BLOCK" << tcu::TestLog::EndMessage;
   2377 			return ERROR;
   2378 		}
   2379 
   2380 		glDeleteProgram(program);
   2381 		return error;
   2382 	}
   2383 };
   2384 
   2385 class NullLength : public SimpleShaders
   2386 {
   2387 
   2388 	virtual std::string Title()
   2389 	{
   2390 		return "NULL Length Test";
   2391 	}
   2392 
   2393 	virtual std::string PurposeExt()
   2394 	{
   2395 		return "\n\n Purpose is to verify that GetProgramResourceName with null length doesn't return length (doesn't "
   2396 			   "crash).\n";
   2397 	}
   2398 
   2399 	virtual std::string VertexShader()
   2400 	{
   2401 		return "#version 310 es                      \n"
   2402 			   "in vec4 position;                    \n"
   2403 			   "void main(void)                      \n"
   2404 			   "{                                    \n"
   2405 			   "    gl_Position = position;          \n"
   2406 			   "}";
   2407 	}
   2408 
   2409 	virtual std::string FragmentShader()
   2410 	{
   2411 		return "#version 310 es                \n"
   2412 			   "out mediump vec4 color;                \n"
   2413 			   "void main() {                  \n"
   2414 			   "    color = vec4(0, 1, 0, 1);  \n"
   2415 			   "}";
   2416 	}
   2417 
   2418 	virtual long Run()
   2419 	{
   2420 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   2421 		glBindAttribLocation(program, 0, "position");
   2422 		LinkProgram(program);
   2423 
   2424 		GLchar name[1024] = { '\0' };
   2425 		GLuint index	  = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color");
   2426 		GLenum prop		  = GL_ARRAY_SIZE;
   2427 		GLint  res;
   2428 		glGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, 1024, NULL, name);
   2429 		glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &prop, 1, NULL, &res);
   2430 
   2431 		std::string expected = "color";
   2432 		if (name != expected)
   2433 		{
   2434 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected name: " << expected
   2435 												<< ", got: " << name << tcu::TestLog::EndMessage;
   2436 			glDeleteProgram(program);
   2437 			return ERROR;
   2438 		}
   2439 		else if (res != 1)
   2440 		{
   2441 			m_context.getTestContext().getLog()
   2442 				<< tcu::TestLog::Message << "Expected array_size: 1, got: " << res << tcu::TestLog::EndMessage;
   2443 			glDeleteProgram(program);
   2444 			return ERROR;
   2445 		}
   2446 
   2447 		glDeleteProgram(program);
   2448 		return NO_ERROR;
   2449 	}
   2450 };
   2451 
   2452 class ArraysOfArrays : public SimpleShaders
   2453 {
   2454 
   2455 	virtual std::string Title()
   2456 	{
   2457 		return "Arrays Of Arrays Test";
   2458 	}
   2459 
   2460 	virtual std::string ShadersDesc()
   2461 	{
   2462 		return "fallthrough fragment and vertex shaders with multi dimensional uniform array used";
   2463 	}
   2464 
   2465 	virtual std::string PurposeExt()
   2466 	{
   2467 		return "\n\n Purpose is to verify that feature works correctly with arrays_of_arrays feature.\n";
   2468 	}
   2469 
   2470 	virtual std::string VertexShader()
   2471 	{
   2472 		return "#version 310 es                      \n"
   2473 			   "in vec4 position;                    \n"
   2474 			   "uniform mediump vec4 a[3][4][5];             \n"
   2475 			   "void main(void)                      \n"
   2476 			   "{                                                 \n"
   2477 			   "    gl_Position = position + a[2][1][0];          \n"
   2478 			   "}";
   2479 	}
   2480 
   2481 	virtual std::string FragmentShader()
   2482 	{
   2483 		return "#version 310 es                \n"
   2484 			   "out mediump vec4 color;                \n"
   2485 			   "void main() {                  \n"
   2486 			   "    color = vec4(0, 1, 0, 1);  \n"
   2487 			   "}";
   2488 	}
   2489 
   2490 	virtual long Run()
   2491 	{
   2492 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   2493 		glBindAttribLocation(program, 0, "position");
   2494 		LinkProgram(program);
   2495 
   2496 		long error = NO_ERROR;
   2497 
   2498 		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 11, error);
   2499 
   2500 		std::map<std::string, GLuint> indices;
   2501 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a[2][1]", error);
   2502 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, "a[2][1][0]", indices["a[2][1]"], error);
   2503 
   2504 		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a[2][1]"], "a[2][1][0]", error);
   2505 
   2506 		GLenum props[] = { GL_NAME_LENGTH,
   2507 						   GL_TYPE,
   2508 						   GL_ARRAY_SIZE,
   2509 						   GL_OFFSET,
   2510 						   GL_BLOCK_INDEX,
   2511 						   GL_ARRAY_STRIDE,
   2512 						   GL_MATRIX_STRIDE,
   2513 						   GL_IS_ROW_MAJOR,
   2514 						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
   2515 						   GL_REFERENCED_BY_COMPUTE_SHADER,
   2516 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
   2517 						   GL_REFERENCED_BY_VERTEX_SHADER,
   2518 						   GL_LOCATION };
   2519 		GLint expected[] = { 11, 35666, 5, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "a[2][1]") };
   2520 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a[2][1]"], 13, props, 13, expected, error);
   2521 
   2522 		glDeleteProgram(program);
   2523 		return error;
   2524 	}
   2525 };
   2526 
   2527 class TopLevelArray : public ComputeShaderTest
   2528 {
   2529 
   2530 	virtual std::string Title()
   2531 	{
   2532 		return "Top Level Array Test";
   2533 	}
   2534 
   2535 	virtual std::string ShadersDesc()
   2536 	{
   2537 		return "compute shader with multi dimensional array used inside storage block";
   2538 	}
   2539 
   2540 	virtual std::string PurposeExt()
   2541 	{
   2542 		return "\n\n Purpose is to verify that feature works correctly when querying for GL_TOP_LEVEL_ARRAY_SIZE\n"
   2543 			   " and GL_TOP_LEVEL_ARRAY_STRIDE.\n";
   2544 	}
   2545 
   2546 	virtual std::string ComputeShader()
   2547 	{
   2548 		return "layout(local_size_x = 1, local_size_y = 1) in; \n"
   2549 			   "layout(std430) buffer Outp {                   \n"
   2550 			   "   mediump vec4 d;                             \n"
   2551 			   "} g_out;                                       \n"
   2552 			   ""
   2553 			   "buffer Block {                       \n"
   2554 			   "   mediump vec4 a[5][4][3];          \n"
   2555 			   "};                                   \n"
   2556 			   ""
   2557 			   "void main(void)                      \n"
   2558 			   "{                                    \n"
   2559 			   "    g_out.d = a[0][0][0];            \n"
   2560 			   "}";
   2561 	}
   2562 
   2563 	virtual long Run()
   2564 	{
   2565 		GLuint program = CreateComputeProgram(ComputeShader());
   2566 		glLinkProgram(program);
   2567 		if (!CheckProgram(program))
   2568 		{
   2569 			glDeleteProgram(program);
   2570 			return ERROR;
   2571 		}
   2572 		glUseProgram(program);
   2573 
   2574 		long error = NO_ERROR;
   2575 
   2576 		VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 11, error);
   2577 		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 6, error);
   2578 		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 2, error);
   2579 
   2580 		std::map<std::string, GLuint> indicesSSB;
   2581 		std::map<std::string, GLuint> indicesBV;
   2582 		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a[0][0]", error);
   2583 		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Block", error);
   2584 
   2585 		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], "a[0][0][0]", error);
   2586 		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Block"], "Block", error);
   2587 
   2588 		GLenum props3[] = { GL_NAME_LENGTH,
   2589 							GL_TYPE,
   2590 							GL_ARRAY_SIZE,
   2591 							GL_BLOCK_INDEX,
   2592 							GL_IS_ROW_MAJOR,
   2593 							GL_REFERENCED_BY_COMPUTE_SHADER,
   2594 							GL_REFERENCED_BY_FRAGMENT_SHADER,
   2595 							GL_REFERENCED_BY_VERTEX_SHADER,
   2596 							GL_TOP_LEVEL_ARRAY_SIZE };
   2597 		GLint expected5[] = { 11, 35666, 3, static_cast<GLint>(indicesSSB["Block"]), 0, 1, 0, 0, 5 };
   2598 		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 9, props3, 9, expected5, error);
   2599 
   2600 		GLenum  prop = GL_TOP_LEVEL_ARRAY_STRIDE;
   2601 		GLsizei len;
   2602 		GLint   res;
   2603 		glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 1, &prop, 1024, &len, &res);
   2604 		if (res <= 0)
   2605 		{
   2606 			m_context.getTestContext().getLog()
   2607 				<< tcu::TestLog::Message
   2608 				<< "Call: glGetProgramResourceiv, interface: GL_BUFFER_VARIABLE, param: GL_TOP_LEVEL_ARRAY_STRIDE\n"
   2609 				<< "Expected value greater than 0, got: " << res << tcu::TestLog::EndMessage;
   2610 			glDeleteProgram(program);
   2611 			return ERROR;
   2612 		}
   2613 
   2614 		glDeleteProgram(program);
   2615 		return error;
   2616 	}
   2617 };
   2618 
   2619 class SeparateProgramsVertex : public SimpleShaders
   2620 {
   2621 public:
   2622 	virtual std::string Title()
   2623 	{
   2624 		return "Separate Program Vertex Shader Test";
   2625 	}
   2626 
   2627 	virtual std::string ShadersDesc()
   2628 	{
   2629 		return "vertex shader as separate shader object";
   2630 	}
   2631 
   2632 	virtual std::string PurposeExt()
   2633 	{
   2634 		return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
   2635 			   "functionality.\n";
   2636 	}
   2637 
   2638 	virtual GLuint CreateShaderProgram(GLenum type, GLsizei count, const GLchar** strings)
   2639 	{
   2640 		GLuint program = glCreateShaderProgramv(type, count, strings);
   2641 		GLint  status  = GL_TRUE;
   2642 		glGetProgramiv(program, GL_LINK_STATUS, &status);
   2643 		if (status == GL_FALSE)
   2644 		{
   2645 			GLsizei length;
   2646 			GLchar  log[1024];
   2647 			glGetProgramInfoLog(program, sizeof(log), &length, log);
   2648 			if (length > 1)
   2649 			{
   2650 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
   2651 													<< log << tcu::TestLog::EndMessage;
   2652 			}
   2653 		}
   2654 		return program;
   2655 	}
   2656 
   2657 	virtual long Run()
   2658 	{
   2659 		long error = NO_ERROR;
   2660 
   2661 		const char* srcVS = "#version 310 es                            \n"
   2662 							"layout(location = 0) in vec4 in_vertex;    \n"
   2663 							""
   2664 							"out mediump float r, g, b;                           \n"
   2665 							"out mediump vec4 iLikePie;                           \n"
   2666 							""
   2667 							"uniform mediump float u;                           \n"
   2668 							"uniform mediump vec4 v;                            \n"
   2669 							""
   2670 							"void main() {                     \n"
   2671 							"  gl_Position = in_vertex;        \n"
   2672 							"  r = u;                          \n"
   2673 							"  g = 0.0;                        \n"
   2674 							"  b = 0.0;                        \n"
   2675 							"  iLikePie = v;                   \n"
   2676 							"}";
   2677 
   2678 		const GLuint vs = CreateShaderProgram(GL_VERTEX_SHADER, 1, &srcVS);
   2679 
   2680 		VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
   2681 		VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 2, error);
   2682 		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 10, error);
   2683 		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
   2684 		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 12, error);
   2685 		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
   2686 
   2687 		std::map<std::string, GLuint> indicesU;
   2688 		std::map<std::string, GLuint> indicesI;
   2689 		std::map<std::string, GLuint> indicesO;
   2690 		VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "u", error);
   2691 		VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "v", error);
   2692 		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_INPUT, indicesI, "in_vertex", error);
   2693 		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "r", error);
   2694 		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "g", error);
   2695 		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "b", error);
   2696 		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "iLikePie", error);
   2697 		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
   2698 
   2699 		VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["u"], "u", error);
   2700 		VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["v"], "v", error);
   2701 		VerifyGetProgramResourceName(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], "in_vertex", error);
   2702 		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["r"], "r", error);
   2703 		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["g"], "g", error);
   2704 		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
   2705 		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], "iLikePie", error);
   2706 		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
   2707 
   2708 		VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "u", glGetUniformLocation(vs, "u"), error);
   2709 		VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "v", glGetUniformLocation(vs, "v"), error);
   2710 		VerifyGetProgramResourceLocation(vs, GL_PROGRAM_INPUT, "in_vertex", 0, error);
   2711 
   2712 		GLenum props[] = { GL_NAME_LENGTH,
   2713 						   GL_TYPE,
   2714 						   GL_ARRAY_SIZE,
   2715 						   GL_OFFSET,
   2716 						   GL_BLOCK_INDEX,
   2717 						   GL_ARRAY_STRIDE,
   2718 						   GL_MATRIX_STRIDE,
   2719 						   GL_IS_ROW_MAJOR,
   2720 						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
   2721 						   GL_REFERENCED_BY_COMPUTE_SHADER,
   2722 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
   2723 						   GL_REFERENCED_BY_VERTEX_SHADER,
   2724 						   GL_LOCATION };
   2725 		GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(vs, "v") };
   2726 		VerifyGetProgramResourceiv(vs, GL_UNIFORM, indicesU["v"], 13, props, 13, expected, error);
   2727 
   2728 		GLenum props2[] = { GL_NAME_LENGTH,
   2729 							GL_TYPE,
   2730 							GL_ARRAY_SIZE,
   2731 							GL_REFERENCED_BY_COMPUTE_SHADER,
   2732 							GL_REFERENCED_BY_FRAGMENT_SHADER,
   2733 							GL_REFERENCED_BY_VERTEX_SHADER,
   2734 							GL_LOCATION };
   2735 		GLint expected2[] = { 10, 35666, 1, 0, 0, 1, 0 };
   2736 		VerifyGetProgramResourceiv(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], 7, props2, 7, expected2, error);
   2737 
   2738 		GLenum props3[] = { GL_NAME_LENGTH,
   2739 							GL_TYPE,
   2740 							GL_ARRAY_SIZE,
   2741 							GL_REFERENCED_BY_COMPUTE_SHADER,
   2742 							GL_REFERENCED_BY_FRAGMENT_SHADER,
   2743 							GL_REFERENCED_BY_VERTEX_SHADER };
   2744 		GLint expected3[] = { 9, 35666, 1, 0, 0, 1 };
   2745 		VerifyGetProgramResourceiv(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], 6, props3, 6, expected3, error);
   2746 
   2747 		glDeleteProgram(vs);
   2748 		return error;
   2749 	}
   2750 };
   2751 
   2752 class SeparateProgramsFragment : public SeparateProgramsVertex
   2753 {
   2754 
   2755 	virtual std::string Title()
   2756 	{
   2757 		return "Separate Program Fragment Shader Test";
   2758 	}
   2759 
   2760 	virtual std::string ShadersDesc()
   2761 	{
   2762 		return "fragment shader as separate shader object";
   2763 	}
   2764 
   2765 	virtual long Run()
   2766 	{
   2767 		long error = NO_ERROR;
   2768 
   2769 		const char* srcTCS = "#version 310 es                                  \n"
   2770 							 "out mediump vec4 fs_color;                       \n"
   2771 							 ""
   2772 							 "layout(location = 1) uniform mediump vec4 x;     \n"
   2773 							 ""
   2774 							 "in mediump vec4 vs_color;                        \n"
   2775 							 "void main() {                                    \n"
   2776 							 "   fs_color = vs_color + x;                      \n"
   2777 							 "}";
   2778 
   2779 		const GLuint tcs = CreateShaderProgram(GL_FRAGMENT_SHADER, 1, &srcTCS);
   2780 
   2781 		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
   2782 		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
   2783 		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 9, error);
   2784 		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
   2785 		VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
   2786 		VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
   2787 
   2788 		std::map<std::string, GLuint> indicesI;
   2789 		std::map<std::string, GLuint> indicesO;
   2790 		std::map<std::string, GLuint> indicesU;
   2791 		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "vs_color", error);
   2792 		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "fs_color", error);
   2793 		VerifyGetProgramResourceIndex(tcs, GL_UNIFORM, indicesU, "x", error);
   2794 
   2795 		VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], "vs_color", error);
   2796 		VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], "fs_color", error);
   2797 		VerifyGetProgramResourceName(tcs, GL_UNIFORM, indicesU["x"], "x", error);
   2798 
   2799 		VerifyGetProgramResourceLocation(tcs, GL_UNIFORM, "x", 1, error);
   2800 
   2801 		GLenum props2[] = { GL_NAME_LENGTH,
   2802 							GL_TYPE,
   2803 							GL_ARRAY_SIZE,
   2804 							GL_REFERENCED_BY_COMPUTE_SHADER,
   2805 							GL_REFERENCED_BY_FRAGMENT_SHADER,
   2806 							GL_REFERENCED_BY_VERTEX_SHADER };
   2807 		GLint expected2[] = { 9, 35666, 1, 0, 1, 0 };
   2808 		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], 6, props2, 6, expected2, error);
   2809 		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], 6, props2, 6, expected2, error);
   2810 
   2811 		GLenum props[] = { GL_NAME_LENGTH,
   2812 						   GL_TYPE,
   2813 						   GL_ARRAY_SIZE,
   2814 						   GL_OFFSET,
   2815 						   GL_BLOCK_INDEX,
   2816 						   GL_ARRAY_STRIDE,
   2817 						   GL_MATRIX_STRIDE,
   2818 						   GL_IS_ROW_MAJOR,
   2819 						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
   2820 						   GL_REFERENCED_BY_COMPUTE_SHADER,
   2821 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
   2822 						   GL_REFERENCED_BY_VERTEX_SHADER,
   2823 						   GL_LOCATION };
   2824 		GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 1 };
   2825 		VerifyGetProgramResourceiv(tcs, GL_UNIFORM, indicesU["x"], 13, props, 13, expected, error);
   2826 
   2827 		glDeleteProgram(tcs);
   2828 		return error;
   2829 	}
   2830 };
   2831 
   2832 class UniformBlockAdvanced : public SimpleShaders
   2833 {
   2834 	virtual std::string Title()
   2835 	{
   2836 		return "Uniform Block Advanced Test";
   2837 	}
   2838 
   2839 	virtual std::string ShadersDesc()
   2840 	{
   2841 		return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
   2842 	}
   2843 
   2844 	virtual std::string PurposeExt()
   2845 	{
   2846 		return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param and\n"
   2847 			   "verify results of querying offset, strides and row order.\n";
   2848 	}
   2849 
   2850 	virtual std::string VertexShader()
   2851 	{
   2852 		return "#version 310 es                      \n"
   2853 			   "in vec4 position;                    \n"
   2854 			   ""
   2855 			   "layout(row_major) uniform SimpleBlock {   \n"
   2856 			   "   mat4 a;                                \n"
   2857 			   "   vec4 b[10];                            \n"
   2858 			   "};                                        \n"
   2859 			   ""
   2860 			   "void main(void)                      \n"
   2861 			   "{                                    \n"
   2862 			   "    float tmp;                       \n"
   2863 			   "    tmp = a[0][0] + b[0].x;          \n"
   2864 			   "    gl_Position = position * tmp;    \n"
   2865 			   "}";
   2866 	}
   2867 
   2868 	virtual long Run()
   2869 	{
   2870 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   2871 		glBindAttribLocation(program, 0, "position");
   2872 		LinkProgram(program);
   2873 
   2874 		long error = NO_ERROR;
   2875 
   2876 		std::map<std::string, GLuint> indicesU;
   2877 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
   2878 		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
   2879 
   2880 		GLenum props[]	= { GL_IS_ROW_MAJOR };
   2881 		GLint  expected[] = { 1 };
   2882 		VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, props, 1, expected, error);
   2883 
   2884 		GLenum  prop = GL_MATRIX_STRIDE;
   2885 		GLsizei len;
   2886 		GLint   res;
   2887 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
   2888 		if (res < 1)
   2889 		{
   2890 			m_context.getTestContext().getLog()
   2891 				<< tcu::TestLog::Message
   2892 				<< "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_MATRIX_STRIDE\n"
   2893 				<< "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
   2894 		}
   2895 		prop = GL_OFFSET;
   2896 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
   2897 		if (res < 0)
   2898 		{
   2899 			m_context.getTestContext().getLog()
   2900 				<< tcu::TestLog::Message << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_OFFSET\n"
   2901 				<< "Expected value not less than 0, got " << res << tcu::TestLog::EndMessage;
   2902 		}
   2903 		prop = GL_ARRAY_STRIDE;
   2904 		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, 1024, &len, &res);
   2905 		if (res < 1)
   2906 		{
   2907 			m_context.getTestContext().getLog()
   2908 				<< tcu::TestLog::Message
   2909 				<< "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_ARRAY_STRIDE\n"
   2910 				<< "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
   2911 		}
   2912 
   2913 		glDeleteProgram(program);
   2914 		return error;
   2915 	}
   2916 };
   2917 
   2918 class ArrayNames : public SimpleShaders
   2919 {
   2920 
   2921 	virtual std::string Title()
   2922 	{
   2923 		return "Array Names Test";
   2924 	}
   2925 
   2926 	virtual std::string ShadersDesc()
   2927 	{
   2928 		return "fallthrough fragment shader and a vertex shader with array of vec4 uniform used";
   2929 	}
   2930 
   2931 	virtual std::string PurposeExt()
   2932 	{
   2933 		return "\n\n Purpose is to verify that GetProgramResourceLocation match "
   2934 			   "name strings correctly.\n";
   2935 	}
   2936 
   2937 	virtual std::string VertexShader()
   2938 	{
   2939 		return "#version 310 es                      \n"
   2940 			   "in vec4 position;                    \n"
   2941 			   ""
   2942 			   "uniform mediump vec4 a[2];           \n"
   2943 			   ""
   2944 			   "void main(void)                            \n"
   2945 			   "{                                          \n"
   2946 			   "    gl_Position = position + a[0] + a[1];  \n"
   2947 			   "}";
   2948 	}
   2949 
   2950 	virtual long Run()
   2951 	{
   2952 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   2953 		glBindAttribLocation(program, 0, "position");
   2954 		LinkProgram(program);
   2955 
   2956 		long error = NO_ERROR;
   2957 
   2958 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
   2959 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0]", glGetUniformLocation(program, "a"), error);
   2960 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[1]", glGetUniformLocation(program, "a[1]"), error);
   2961 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[2]", -1, error);
   2962 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 + 0]", -1, error);
   2963 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0+0]", -1, error);
   2964 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[ 0]", -1, error);
   2965 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 ]", -1, error);
   2966 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\n0]", -1, error);
   2967 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\t0]", -1, error);
   2968 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[01]", -1, error);
   2969 		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[00]", -1, error);
   2970 
   2971 		glDeleteProgram(program);
   2972 		return error;
   2973 	}
   2974 };
   2975 
   2976 class BuffLength : public SimpleShaders
   2977 {
   2978 
   2979 	virtual std::string Title()
   2980 	{
   2981 		return "Buff Length Test";
   2982 	}
   2983 
   2984 	virtual std::string ShadersDesc()
   2985 	{
   2986 		return "fallthrough fragment shader and vertex with uniform of vec4 type used";
   2987 	}
   2988 
   2989 	virtual std::string PurposeExt()
   2990 	{
   2991 		return "\n\n Purpose is to verify that bufsize of GetProgramResourceName and "
   2992 			   "GetProgramResourceiv is respected.\n";
   2993 	}
   2994 
   2995 	virtual std::string VertexShader()
   2996 	{
   2997 		return "#version 310 es                      \n"
   2998 			   "in vec4 position;                    \n"
   2999 			   ""
   3000 			   "uniform mediump vec4 someLongName;         \n"
   3001 			   ""
   3002 			   "void main(void)                            \n"
   3003 			   "{                                          \n"
   3004 			   "    gl_Position = position + someLongName; \n"
   3005 			   "}";
   3006 	}
   3007 
   3008 	virtual long Run()
   3009 	{
   3010 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   3011 		glBindAttribLocation(program, 0, "position");
   3012 		LinkProgram(program);
   3013 
   3014 		long error = NO_ERROR;
   3015 
   3016 		GLuint  index = glGetProgramResourceIndex(program, GL_UNIFORM, "someLongName");
   3017 		GLsizei length;
   3018 		GLchar  buff[3] = { 'a', 'b', 'c' };
   3019 		glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, NULL);
   3020 		glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, buff);
   3021 		if (buff[0] != 'a' || buff[1] != 'b' || buff[2] != 'c')
   3022 		{
   3023 			m_context.getTestContext().getLog()
   3024 				<< tcu::TestLog::Message << "ERROR: buff has changed" << tcu::TestLog::EndMessage;
   3025 			error = ERROR;
   3026 		}
   3027 		glGetProgramResourceName(program, GL_UNIFORM, index, 2, &length, buff);
   3028 		if (buff[0] != 's' || buff[1] != '\0' || buff[2] != 'c')
   3029 		{
   3030 			m_context.getTestContext().getLog()
   3031 				<< tcu::TestLog::Message << "ERROR: buff different then expected" << tcu::TestLog::EndMessage;
   3032 			error = ERROR;
   3033 		}
   3034 		if (length != 1)
   3035 		{
   3036 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 1, got "
   3037 												<< length << tcu::TestLog::EndMessage;
   3038 			error = ERROR;
   3039 		}
   3040 
   3041 		GLint  params[3] = { 1, 2, 3 };
   3042 		GLenum props[]   = { GL_NAME_LENGTH,
   3043 						   GL_TYPE,
   3044 						   GL_ARRAY_SIZE,
   3045 						   GL_OFFSET,
   3046 						   GL_BLOCK_INDEX,
   3047 						   GL_ARRAY_STRIDE,
   3048 						   GL_MATRIX_STRIDE,
   3049 						   GL_IS_ROW_MAJOR,
   3050 						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
   3051 						   GL_REFERENCED_BY_COMPUTE_SHADER,
   3052 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
   3053 						   GL_REFERENCED_BY_VERTEX_SHADER,
   3054 						   GL_LOCATION };
   3055 		glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, NULL);
   3056 		glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, params);
   3057 		if (params[0] != 1 || params[1] != 2 || params[2] != 3)
   3058 		{
   3059 			m_context.getTestContext().getLog()
   3060 				<< tcu::TestLog::Message << "ERROR: params has changed" << tcu::TestLog::EndMessage;
   3061 			error = ERROR;
   3062 		}
   3063 		glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 2, &length, params);
   3064 		if (params[0] != 13 || params[1] != 35666 || params[2] != 3)
   3065 		{
   3066 			m_context.getTestContext().getLog()
   3067 				<< tcu::TestLog::Message << "ERROR: params has incorrect values" << tcu::TestLog::EndMessage;
   3068 			error = ERROR;
   3069 		}
   3070 		if (length != 2)
   3071 		{
   3072 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 2, got "
   3073 												<< length << tcu::TestLog::EndMessage;
   3074 			error = ERROR;
   3075 		}
   3076 
   3077 		glDeleteProgram(program);
   3078 		return error;
   3079 	}
   3080 };
   3081 
   3082 class NoLocations : public SimpleShaders
   3083 {
   3084 
   3085 	virtual std::string Title()
   3086 	{
   3087 		return "No Locations Test";
   3088 	}
   3089 
   3090 	virtual std::string ShadersDesc()
   3091 	{
   3092 		return "fragment and vertex shaders with no locations set";
   3093 	}
   3094 
   3095 	virtual std::string VertexShader()
   3096 	{
   3097 		return "#version 310 es                      \n"
   3098 			   "in vec4 a;                           \n"
   3099 			   "in vec4 b;                           \n"
   3100 			   "in vec4 c;                           \n"
   3101 			   "in vec4 d;                           \n"
   3102 			   "void main(void)                      \n"
   3103 			   "{                                    \n"
   3104 			   "    gl_Position = a + b + c + d;     \n"
   3105 			   "}";
   3106 	}
   3107 
   3108 	// fragment shader outputs need an explicit location per spec
   3109 	virtual std::string FragmentShader()
   3110 	{
   3111 		return "#version 310 es                \n"
   3112 			   "layout (location=0) out mediump vec4 a;            \n"
   3113 			   "layout (location=1) out mediump vec4 b;            \n"
   3114 			   "layout (location=2) out mediump vec4 c;            \n"
   3115 			   "layout (location=3) out mediump vec4 d[1];         \n"
   3116 			   "void main() {                  \n"
   3117 			   "    a = vec4(0, 1, 0, 1);      \n"
   3118 			   "    b = vec4(0, 1, 0, 1);      \n"
   3119 			   "    c = vec4(0, 1, 0, 1);      \n"
   3120 			   "    d[0] = vec4(0, 1, 0, 1);   \n"
   3121 			   "}";
   3122 	}
   3123 
   3124 	virtual long Run()
   3125 	{
   3126 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   3127 		glBindAttribLocation(program, 0, "position");
   3128 		glLinkProgram(program);
   3129 
   3130 		long error = NO_ERROR;
   3131 
   3132 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 4, error);
   3133 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error);
   3134 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 4, error);
   3135 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
   3136 
   3137 		std::map<std::string, GLuint> indicesI;
   3138 		std::map<std::string, GLuint> indicesO;
   3139 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "a", error);
   3140 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "b", error);
   3141 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "c", error);
   3142 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "d", error);
   3143 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "a", error);
   3144 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "b", error);
   3145 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "c", error);
   3146 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "d[0]", error);
   3147 
   3148 		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["a"], "a", error);
   3149 		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["b"], "b", error);
   3150 		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["c"], "c", error);
   3151 		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["d"], "d", error);
   3152 		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["a"], "a", error);
   3153 		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
   3154 		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["c"], "c", error);
   3155 		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], "d[0]", error);
   3156 
   3157 		std::map<std::string, GLint> locationsI;
   3158 		std::map<std::string, GLint> locationsO;
   3159 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "a", error);
   3160 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "b", error);
   3161 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "c", error);
   3162 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "d", error);
   3163 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "a", error);
   3164 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "b", error);
   3165 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "c", error);
   3166 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "d[0]", error);
   3167 
   3168 		GLenum props[] = { GL_NAME_LENGTH,
   3169 						   GL_TYPE,
   3170 						   GL_ARRAY_SIZE,
   3171 						   GL_REFERENCED_BY_COMPUTE_SHADER,
   3172 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
   3173 						   GL_REFERENCED_BY_VERTEX_SHADER };
   3174 		GLint expected[] = { 2, 35666, 1, 0, 0, 1 };
   3175 		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["a"], 6, props, 6, expected, error);
   3176 		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["b"], 6, props, 6, expected, error);
   3177 		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["d"], 6, props, 6, expected, error);
   3178 		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["c"], 6, props, 6, expected, error);
   3179 		GLint expected3[] = { 2, 35666, 1, 0, 1, 0 };
   3180 		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["a"], 6, props, 6, expected3, error);
   3181 		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["b"], 6, props, 6, expected3, error);
   3182 		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["c"], 6, props, 6, expected3, error);
   3183 		GLint expected4[] = { 5, 35666, 1, 0, 1, 0 };
   3184 		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], 6, props, 6, expected4, error);
   3185 
   3186 		glDeleteProgram(program);
   3187 		return error;
   3188 	}
   3189 };
   3190 
   3191 class OutputBuiltIn : public SimpleShaders
   3192 {
   3193 
   3194 	virtual std::string Title()
   3195 	{
   3196 		return "Output Built-ins Test";
   3197 	}
   3198 
   3199 	virtual std::string ShadersDesc()
   3200 	{
   3201 		return "fragment shader using built-in variables and a fallthrough vertex shader";
   3202 	}
   3203 
   3204 	virtual std::string Expectations()
   3205 	{
   3206 		return ".\n\n In this case we ask for information about built-in variables for the output interface.";
   3207 	}
   3208 
   3209 	virtual std::string FragmentShader()
   3210 	{
   3211 		return "#version 310 es                            \n"
   3212 			   "void main(void)                            \n"
   3213 			   "{                                          \n"
   3214 			   "    gl_FragDepth = 0.1;                    \n"
   3215 			   "}";
   3216 	}
   3217 
   3218 	virtual long Run()
   3219 	{
   3220 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), true);
   3221 
   3222 		long error = NO_ERROR;
   3223 
   3224 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
   3225 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 13, error);
   3226 
   3227 		std::map<std::string, GLuint> indices;
   3228 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "gl_FragDepth", error);
   3229 
   3230 		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], "gl_FragDepth", error);
   3231 
   3232 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_FragDepth", -1, error);
   3233 
   3234 		GLenum props[] = { GL_NAME_LENGTH,
   3235 						   GL_TYPE,
   3236 						   GL_ARRAY_SIZE,
   3237 						   GL_REFERENCED_BY_COMPUTE_SHADER,
   3238 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
   3239 						   GL_REFERENCED_BY_VERTEX_SHADER,
   3240 						   GL_LOCATION };
   3241 		GLint expected[] = { 13, 5126, 1, 0, 1, 0, -1 };
   3242 		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], DE_LENGTH_OF_ARRAY(props),
   3243 								   props, DE_LENGTH_OF_ARRAY(expected), expected, error);
   3244 
   3245 		glDeleteProgram(program);
   3246 		return error;
   3247 	}
   3248 };
   3249 
   3250 class QueryNotUsed : public SimpleShaders
   3251 {
   3252 
   3253 	virtual std::string Title()
   3254 	{
   3255 		return "Query Not Used Test";
   3256 	}
   3257 
   3258 	virtual std::string PassCriteria()
   3259 	{
   3260 		return "Data from queries matches the not used program.";
   3261 	}
   3262 
   3263 	virtual std::string Purpose()
   3264 	{
   3265 		return "Verify that program parameter works correctly and proper program is queried when different program is "
   3266 			   "used.";
   3267 	}
   3268 
   3269 	virtual std::string Method()
   3270 	{
   3271 		return "Create 2 programs, use one of them and query the other, verify the results.";
   3272 	}
   3273 
   3274 	virtual std::string VertexShader2()
   3275 	{
   3276 		return "#version 310 es                      \n"
   3277 			   "in mediump vec4 p;                   \n"
   3278 			   "void main(void)                      \n"
   3279 			   "{                                    \n"
   3280 			   "    gl_Position = p;                 \n"
   3281 			   "}";
   3282 	}
   3283 
   3284 	virtual std::string FragmentShader2()
   3285 	{
   3286 		return "#version 310 es                \n"
   3287 			   "out mediump vec4 c;            \n"
   3288 			   "void main() {                  \n"
   3289 			   "    c = vec4(0., 1., 0., 1.);  \n"
   3290 			   "}";
   3291 	}
   3292 
   3293 	virtual long Run()
   3294 	{
   3295 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   3296 		LinkProgram(program);
   3297 
   3298 		GLuint program2 = CreateProgram(VertexShader2().c_str(), FragmentShader2().c_str(), false);
   3299 		LinkProgram(program2);
   3300 		glUseProgram(program2);
   3301 
   3302 		long error = NO_ERROR;
   3303 
   3304 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
   3305 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
   3306 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
   3307 		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
   3308 
   3309 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
   3310 		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
   3311 
   3312 		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
   3313 		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
   3314 
   3315 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
   3316 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
   3317 
   3318 		GLenum props[] = { GL_NAME_LENGTH,
   3319 						   GL_TYPE,
   3320 						   GL_ARRAY_SIZE,
   3321 						   GL_REFERENCED_BY_COMPUTE_SHADER,
   3322 						   GL_REFERENCED_BY_FRAGMENT_SHADER,
   3323 						   GL_REFERENCED_BY_VERTEX_SHADER,
   3324 						   GL_LOCATION };
   3325 		GLint expected[] = { 9, 35666, 1, 0, 0, 1, 0 };
   3326 		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, DE_LENGTH_OF_ARRAY(props), props,
   3327 								   DE_LENGTH_OF_ARRAY(expected), expected, error);
   3328 
   3329 		GLenum props2[] = { GL_NAME_LENGTH,
   3330 							GL_TYPE,
   3331 							GL_ARRAY_SIZE,
   3332 							GL_REFERENCED_BY_COMPUTE_SHADER,
   3333 							GL_REFERENCED_BY_FRAGMENT_SHADER,
   3334 							GL_REFERENCED_BY_VERTEX_SHADER,
   3335 							GL_LOCATION };
   3336 		GLint expected2[] = { 6, 35666, 1, 0, 1, 0, 0 };
   3337 		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 7, props2, 7, expected2, error);
   3338 
   3339 		glDeleteProgram(program);
   3340 		glDeleteProgram(program2);
   3341 		return error;
   3342 	}
   3343 };
   3344 
   3345 class RelinkFailure : public SimpleShaders
   3346 {
   3347 
   3348 	virtual std::string Title()
   3349 	{
   3350 		return "Relink Failure Test";
   3351 	}
   3352 
   3353 	virtual std::string PassCriteria()
   3354 	{
   3355 		return "INVALID_OPERATION is generated when asking for locations after failed link.";
   3356 	}
   3357 
   3358 	virtual std::string Purpose()
   3359 	{
   3360 		return "Verify that queries behave correctly after failed relink of a program.";
   3361 	}
   3362 
   3363 	virtual std::string Method()
   3364 	{
   3365 		return "Create a program, use it, relink with failure and then verify that INVALID_OPERATION is returned when "
   3366 			   "asking for locations.";
   3367 	}
   3368 
   3369 	virtual std::string VertexShader()
   3370 	{
   3371 		return "#version 310 es                               \n"
   3372 			   "in mediump vec4 position;                     \n"
   3373 			   "in mediump vec3 pos;                          \n"
   3374 			   "void main(void)                               \n"
   3375 			   "{                                             \n"
   3376 			   "    gl_Position = position + vec4(pos, 1.);   \n"
   3377 			   "}";
   3378 	}
   3379 
   3380 	virtual long Run()
   3381 	{
   3382 		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
   3383 		glBindAttribLocation(program, 0, "position");
   3384 		glBindAttribLocation(program, 1, "pos");
   3385 		LinkProgram(program);
   3386 
   3387 		long error = NO_ERROR;
   3388 
   3389 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", 1, error);
   3390 		glUseProgram(program);
   3391 
   3392 		tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
   3393 						   tcu::Vec4(1, -1, 0, 1) };
   3394 		GLuint vao, vbuf;
   3395 		glGenVertexArrays(1, &vao);
   3396 		glBindVertexArray(vao);
   3397 		glGenBuffers(1, &vbuf);
   3398 		glBindBuffer(GL_ARRAY_BUFFER, vbuf);
   3399 		glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
   3400 		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
   3401 		glEnableVertexAttribArray(0);
   3402 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   3403 
   3404 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   3405 		glDisableVertexAttribArray(0);
   3406 		glDeleteVertexArrays(1, &vao);
   3407 		glBindBuffer(GL_ARRAY_BUFFER, 0);
   3408 		glDeleteBuffers(1, &vbuf);
   3409 
   3410 		glBindAttribLocation(program, 0, "pos");
   3411 		glBindAttribLocation(program, 0, "position");
   3412 		const char* varyings[2] = { "q", "z" };
   3413 		glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
   3414 		LinkProgram(program);
   3415 
   3416 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
   3417 		ExpectError(GL_INVALID_OPERATION, error);
   3418 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", -1, error);
   3419 		ExpectError(GL_INVALID_OPERATION, error);
   3420 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
   3421 		ExpectError(GL_INVALID_OPERATION, error);
   3422 
   3423 		glDeleteProgram(program);
   3424 		return error;
   3425 	}
   3426 };
   3427 
   3428 class LinkFailure : public SimpleShaders
   3429 {
   3430 
   3431 	virtual std::string Title()
   3432 	{
   3433 		return "Link Failure Test";
   3434 	}
   3435 
   3436 	virtual std::string PassCriteria()
   3437 	{
   3438 		return "INVALID_OPERATION is generated when asking for locations after failed link.";
   3439 	}
   3440 
   3441 	virtual std::string Purpose()
   3442 	{
   3443 		return "Verify that queries behave correctly after failed relink of a program with changed sources.";
   3444 	}
   3445 
   3446 	virtual std::string Method()
   3447 	{
   3448 		return "Create a program, use it, relink with failure using different sources and then \n"
   3449 			   "verify that INVALID_OPERATION is returned when asking for locations.";
   3450 	}
   3451 
   3452 	virtual const char* VertexShader_prop()
   3453 	{
   3454 		return "#version 310 es                      \n"
   3455 			   "in mediump vec4 posit;               \n"
   3456 			   "in mediump vec4 p;                   \n"
   3457 			   "void main(void)                      \n"
   3458 			   "{                                    \n"
   3459 			   "    gl_Position = p + posit;         \n"
   3460 			   "}";
   3461 	}
   3462 
   3463 	virtual const char* FragmentShader_prop()
   3464 	{
   3465 		return "#version 310 es                    \n"
   3466 			   "out mediump vec4 color;            \n"
   3467 			   "void main() {                      \n"
   3468 			   "    color = vec4(0., 1., 0., 1.);  \n"
   3469 			   "}";
   3470 	}
   3471 
   3472 	virtual const char* VertexShader_fail()
   3473 	{
   3474 		return "#version 310 es                      \n"
   3475 			   "in mediump vec4 position;            \n"
   3476 			   "void main(void)                      \n"
   3477 			   "{                                    \n"
   3478 			   "    gl_Position = position;          \n"
   3479 			   "}";
   3480 	}
   3481 
   3482 	virtual long Run()
   3483 	{
   3484 		const GLuint program = glCreateProgram();
   3485 		const char*  src_vs  = VertexShader_prop();
   3486 		const char*  src_fs  = FragmentShader_prop();
   3487 		const char*  src_vsh = VertexShader_fail();
   3488 
   3489 		GLuint sh1 = glCreateShader(GL_VERTEX_SHADER);
   3490 		glAttachShader(program, sh1);
   3491 		glDeleteShader(sh1);
   3492 		glShaderSource(sh1, 1, &src_vs, NULL);
   3493 		glCompileShader(sh1);
   3494 
   3495 		GLuint sh2 = glCreateShader(GL_FRAGMENT_SHADER);
   3496 		glAttachShader(program, sh2);
   3497 		glDeleteShader(sh2);
   3498 		glShaderSource(sh2, 1, &src_fs, NULL);
   3499 		glCompileShader(sh2);
   3500 
   3501 		glBindAttribLocation(program, 0, "p");
   3502 		glBindAttribLocation(program, 1, "posit");
   3503 		LinkProgram(program);
   3504 
   3505 		long error = NO_ERROR;
   3506 
   3507 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "posit", 1, error);
   3508 		glUseProgram(program);
   3509 
   3510 		tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
   3511 						   tcu::Vec4(1, -1, 0, 1) };
   3512 		GLuint vao, vbuf;
   3513 		glGenVertexArrays(1, &vao);
   3514 		glBindVertexArray(vao);
   3515 		glGenBuffers(1, &vbuf);
   3516 		glBindBuffer(GL_ARRAY_BUFFER, vbuf);
   3517 		glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
   3518 		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
   3519 		glEnableVertexAttribArray(0);
   3520 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   3521 
   3522 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   3523 		glDisableVertexAttribArray(0);
   3524 		glDeleteVertexArrays(1, &vao);
   3525 		glBindBuffer(GL_ARRAY_BUFFER, 0);
   3526 		glDeleteBuffers(1, &vbuf);
   3527 
   3528 		glDetachShader(program, sh1);
   3529 		GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
   3530 		glAttachShader(program, vsh);
   3531 		glDeleteShader(vsh);
   3532 		glShaderSource(vsh, 1, &src_vsh, NULL);
   3533 		glCompileShader(vsh);
   3534 		const char* varyings[2] = { "q", "z" };
   3535 		glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
   3536 		LinkProgram(program);
   3537 
   3538 		GLint res;
   3539 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
   3540 		ExpectError(GL_INVALID_OPERATION, error);
   3541 		glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
   3542 		if (res != 0 && res != 1)
   3543 		{
   3544 			m_context.getTestContext().getLog()
   3545 				<< tcu::TestLog::Message << "Error, expected 0 or 1 active resources, got: " << res
   3546 				<< tcu::TestLog::EndMessage;
   3547 			error = ERROR;
   3548 		}
   3549 		glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, &res);
   3550 		if (res != 0 && res != 9)
   3551 		{
   3552 			m_context.getTestContext().getLog()
   3553 				<< tcu::TestLog::Message << "Error, expected 1 or 9 GL_MAX_NAME_LENGTH, got: " << res
   3554 				<< tcu::TestLog::EndMessage;
   3555 			error = ERROR;
   3556 		}
   3557 		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
   3558 		ExpectError(GL_INVALID_OPERATION, error);
   3559 
   3560 		glDeleteProgram(program);
   3561 		return error;
   3562 	}
   3563 };
   3564 }
   3565 
   3566 ProgramInterfaceQueryTests::ProgramInterfaceQueryTests(glcts::Context& context)
   3567 	: TestCaseGroup(context, "program_interface_query", "")
   3568 {
   3569 }
   3570 
   3571 ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests(void)
   3572 {
   3573 }
   3574 
   3575 void ProgramInterfaceQueryTests::init()
   3576 {
   3577 	using namespace glcts;
   3578 	addChild(new TestSubcase(m_context, "empty-shaders", TestSubcase::Create<NoShaders>));
   3579 	addChild(new TestSubcase(m_context, "simple-shaders", TestSubcase::Create<SimpleShaders>));
   3580 	addChild(new TestSubcase(m_context, "input-types", TestSubcase::Create<InputTypes>));
   3581 	addChild(new TestSubcase(m_context, "input-built-in", TestSubcase::Create<InputBuiltIn>));
   3582 	addChild(new TestSubcase(m_context, "input-layout", TestSubcase::Create<InputLayout>));
   3583 	addChild(new TestSubcase(m_context, "output-layout", TestSubcase::Create<OutputLayout>));
   3584 	addChild(new TestSubcase(m_context, "output-built-in", TestSubcase::Create<OutputBuiltIn>));
   3585 	addChild(new TestSubcase(m_context, "uniform-simple", TestSubcase::Create<UniformSimple>));
   3586 	addChild(new TestSubcase(m_context, "uniform-types", TestSubcase::Create<UniformTypes>));
   3587 	addChild(new TestSubcase(m_context, "uniform-block-types", TestSubcase::Create<UniformBlockTypes>));
   3588 	addChild(new TestSubcase(m_context, "transform-feedback-types", TestSubcase::Create<TransformFeedbackTypes>));
   3589 	addChild(new TestSubcase(m_context, "atomic-counters", TestSubcase::Create<AtomicCounterSimple>));
   3590 	addChild(
   3591 		new TestSubcase(m_context, "atomic-counters-one-buffer", TestSubcase::Create<AtomicCounterSimpleOneBuffer>));
   3592 	addChild(new TestSubcase(m_context, "ssb-types", TestSubcase::Create<ShaderStorageBlock>));
   3593 	addChild(new TestSubcase(m_context, "null-length", TestSubcase::Create<NullLength>));
   3594 	addChild(new TestSubcase(m_context, "arrays-of-arrays", TestSubcase::Create<ArraysOfArrays>));
   3595 	addChild(new TestSubcase(m_context, "top-level-array", TestSubcase::Create<TopLevelArray>));
   3596 	addChild(new TestSubcase(m_context, "separate-programs-vertex", TestSubcase::Create<SeparateProgramsVertex>));
   3597 	addChild(new TestSubcase(m_context, "separate-programs-fragment", TestSubcase::Create<SeparateProgramsFragment>));
   3598 	addChild(new TestSubcase(m_context, "uniform-block", TestSubcase::Create<UniformBlockAdvanced>));
   3599 	addChild(new TestSubcase(m_context, "array-names", TestSubcase::Create<ArrayNames>));
   3600 	addChild(new TestSubcase(m_context, "buff-length", TestSubcase::Create<BuffLength>));
   3601 	addChild(new TestSubcase(m_context, "no-locations", TestSubcase::Create<NoLocations>));
   3602 	addChild(new TestSubcase(m_context, "query-not-used", TestSubcase::Create<QueryNotUsed>));
   3603 	addChild(new TestSubcase(m_context, "relink-failure", TestSubcase::Create<RelinkFailure>));
   3604 	addChild(new TestSubcase(m_context, "link-failure", TestSubcase::Create<LinkFailure>));
   3605 	addChild(new TestSubcase(m_context, "compute-shader", TestSubcase::Create<ComputeShaderTest>));
   3606 	addChild(new TestSubcase(m_context, "invalid-value", TestSubcase::Create<InvalidValueTest>));
   3607 	addChild(new TestSubcase(m_context, "invalid-operation", TestSubcase::Create<InvalidOperationTest>));
   3608 	addChild(new TestSubcase(m_context, "invalid-enum", TestSubcase::Create<InvalidEnumTest>));
   3609 }
   3610 }
   3611