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