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 /**
     25  * \file  gl4cShaderSubroutineTests.cpp
     26  * \brief Implements conformance tests for "Shader Subroutine" functionality.
     27  */ /*-------------------------------------------------------------------*/
     28 
     29 #include "gl4cShaderSubroutineTests.hpp"
     30 #include "gluContextInfo.hpp"
     31 #include "glwEnums.hpp"
     32 #include "glwFunctions.hpp"
     33 #include "tcuMatrix.hpp"
     34 #include <cmath>
     35 #include <cstring>
     36 #include <deMath.h>
     37 
     38 using namespace glw;
     39 
     40 namespace gl4cts
     41 {
     42 namespace ShaderSubroutine
     43 {
     44 /** Constructor.
     45  *
     46  * @param context CTS context.
     47  **/
     48 Utils::buffer::buffer(deqp::Context& context) : m_id(0), m_context(context)
     49 {
     50 }
     51 
     52 /** Destructor
     53  *
     54  **/
     55 Utils::buffer::~buffer()
     56 {
     57 	if (0 != m_id)
     58 	{
     59 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
     60 
     61 		gl.deleteBuffers(1, &m_id);
     62 		m_id = 0;
     63 	}
     64 }
     65 
     66 /** Execute BindBufferRange
     67  *
     68  * @param target <target> parameter
     69  * @param index  <index> parameter
     70  * @param offset <offset> parameter
     71  * @param size   <size> parameter
     72  **/
     73 void Utils::buffer::bindRange(glw::GLenum target, glw::GLuint index, glw::GLintptr offset, glw::GLsizeiptr size)
     74 {
     75 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
     76 
     77 	gl.bindBufferRange(target, index, m_id, offset, size);
     78 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
     79 }
     80 
     81 /** Execute GenBuffer
     82  *
     83  **/
     84 void Utils::buffer::generate()
     85 {
     86 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
     87 
     88 	gl.genBuffers(1, &m_id);
     89 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
     90 }
     91 
     92 /** Execute BufferData
     93  *
     94  * @param target <target> parameter
     95  * @param size   <size> parameter
     96  * @param data   <data> parameter
     97  * @param usage  <usage> parameter
     98  **/
     99 void Utils::buffer::update(glw::GLenum target, glw::GLsizeiptr size, glw::GLvoid* data, glw::GLenum usage)
    100 {
    101 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    102 
    103 	gl.bindBuffer(target, m_id);
    104 	GLU_EXPECT_NO_ERROR(gl.getError(), "bindBuffer");
    105 
    106 	gl.bufferData(target, size, data, usage);
    107 	GLU_EXPECT_NO_ERROR(gl.getError(), "bufferData");
    108 }
    109 
    110 /** Constructor
    111  *
    112  * @param context CTS context
    113  **/
    114 Utils::framebuffer::framebuffer(deqp::Context& context) : m_id(0), m_context(context)
    115 {
    116 	/* Nothing to be done here */
    117 }
    118 
    119 /** Destructor
    120  *
    121  **/
    122 Utils::framebuffer::~framebuffer()
    123 {
    124 	if (0 != m_id)
    125 	{
    126 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    127 
    128 		gl.deleteFramebuffers(1, &m_id);
    129 		m_id = 0;
    130 	}
    131 }
    132 
    133 /** Attach texture to specified attachment
    134  *
    135  * @param attachment Attachment
    136  * @param texture_id Texture id
    137  * @param width      Texture width
    138  * @param height     Texture height
    139  **/
    140 void Utils::framebuffer::attachTexture(glw::GLenum attachment, glw::GLuint texture_id, glw::GLuint width,
    141 									   glw::GLuint height)
    142 {
    143 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    144 
    145 	bind();
    146 
    147 	gl.bindTexture(GL_TEXTURE_2D, texture_id);
    148 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
    149 
    150 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture_id, 0 /* level */);
    151 
    152 	GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
    153 
    154 	gl.viewport(0 /* x */, 0 /* y */, width, height);
    155 	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
    156 }
    157 
    158 /** Binds framebuffer to DRAW_FRAMEBUFFER
    159  *
    160  **/
    161 void Utils::framebuffer::bind()
    162 {
    163 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    164 
    165 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_id);
    166 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
    167 }
    168 
    169 /** Clear framebuffer
    170  *
    171  * @param mask <mask> parameter of glClear. Decides which shall be cleared
    172  **/
    173 void Utils::framebuffer::clear(glw::GLenum mask)
    174 {
    175 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    176 
    177 	gl.clear(mask);
    178 	GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
    179 }
    180 
    181 /** Specifie clear color
    182  *
    183  * @param red   Red channel
    184  * @param green Green channel
    185  * @param blue  Blue channel
    186  * @param alpha Alpha channel
    187  **/
    188 void Utils::framebuffer::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
    189 {
    190 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    191 
    192 	gl.clearColor(red, green, blue, alpha);
    193 	GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
    194 }
    195 
    196 /** Generate framebuffer
    197  *
    198  **/
    199 void Utils::framebuffer::generate()
    200 {
    201 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    202 
    203 	gl.genFramebuffers(1, &m_id);
    204 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
    205 }
    206 
    207 const glw::GLenum Utils::program::ARB_COMPUTE_SHADER = 0x91B9;
    208 
    209 /** Constructor.
    210  *
    211  * @param context CTS context.
    212  **/
    213 Utils::program::program(deqp::Context& context)
    214 	: m_compute_shader_id(0)
    215 	, m_fragment_shader_id(0)
    216 	, m_geometry_shader_id(0)
    217 	, m_program_object_id(0)
    218 	, m_tesselation_control_shader_id(0)
    219 	, m_tesselation_evaluation_shader_id(0)
    220 	, m_vertex_shader_id(0)
    221 	, m_context(context)
    222 {
    223 	/* Nothing to be done here */
    224 }
    225 
    226 /** Destructor
    227  *
    228  **/
    229 Utils::program::~program()
    230 {
    231 	remove();
    232 }
    233 
    234 /** Build program
    235  *
    236  * @param compute_shader_code                Compute shader source code
    237  * @param fragment_shader_code               Fragment shader source code
    238  * @param geometry_shader_code               Geometry shader source code
    239  * @param tesselation_control_shader_code    Tesselation control shader source code
    240  * @param tesselation_evaluation_shader_code Tesselation evaluation shader source code
    241  * @param vertex_shader_code                 Vertex shader source code
    242  * @param varying_names                      Array of strings containing names of varyings to be captured with transfrom feedback
    243  * @param n_varying_names                    Number of varyings to be captured with transfrom feedback
    244  * @param is_separable                       Selects if monolithis or separable program should be built. Defaults to false
    245  **/
    246 void Utils::program::build(const glw::GLchar* compute_shader_code, const glw::GLchar* fragment_shader_code,
    247 						   const glw::GLchar* geometry_shader_code, const glw::GLchar* tesselation_control_shader_code,
    248 						   const glw::GLchar* tesselation_evaluation_shader_code, const glw::GLchar* vertex_shader_code,
    249 						   const glw::GLchar* const* varying_names, glw::GLuint n_varying_names, bool is_separable)
    250 {
    251 	/* GL entry points */
    252 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    253 
    254 	/* Create shader objects and compile */
    255 	if (0 != compute_shader_code)
    256 	{
    257 		m_compute_shader_id = gl.createShader(ARB_COMPUTE_SHADER);
    258 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    259 
    260 		compile(m_compute_shader_id, compute_shader_code);
    261 	}
    262 
    263 	if (0 != fragment_shader_code)
    264 	{
    265 		m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
    266 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    267 
    268 		compile(m_fragment_shader_id, fragment_shader_code);
    269 	}
    270 
    271 	if (0 != geometry_shader_code)
    272 	{
    273 		m_geometry_shader_id = gl.createShader(GL_GEOMETRY_SHADER);
    274 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    275 
    276 		compile(m_geometry_shader_id, geometry_shader_code);
    277 	}
    278 
    279 	if (0 != tesselation_control_shader_code)
    280 	{
    281 		m_tesselation_control_shader_id = gl.createShader(GL_TESS_CONTROL_SHADER);
    282 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    283 
    284 		compile(m_tesselation_control_shader_id, tesselation_control_shader_code);
    285 	}
    286 
    287 	if (0 != tesselation_evaluation_shader_code)
    288 	{
    289 		m_tesselation_evaluation_shader_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
    290 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    291 
    292 		compile(m_tesselation_evaluation_shader_id, tesselation_evaluation_shader_code);
    293 	}
    294 
    295 	if (0 != vertex_shader_code)
    296 	{
    297 		m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
    298 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    299 
    300 		compile(m_vertex_shader_id, vertex_shader_code);
    301 	}
    302 
    303 	/* Create program object */
    304 	m_program_object_id = gl.createProgram();
    305 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
    306 
    307 	/* Set up captyured varyings' names */
    308 	if (0 != n_varying_names)
    309 	{
    310 		gl.transformFeedbackVaryings(m_program_object_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS);
    311 		GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
    312 	}
    313 
    314 	/* Set separable parameter */
    315 	if (true == is_separable)
    316 	{
    317 		gl.programParameteri(m_program_object_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
    318 		GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri");
    319 	}
    320 
    321 	/* Link program */
    322 	link();
    323 }
    324 
    325 /** Compile shader
    326  *
    327  * @param shader_id   Shader object id
    328  * @param shader_code Shader source code
    329  **/
    330 void Utils::program::compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const
    331 {
    332 	/* GL entry points */
    333 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    334 
    335 	/* Compilation status */
    336 	glw::GLint status = GL_FALSE;
    337 
    338 	/* Set source code */
    339 	gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
    340 	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
    341 
    342 	/* Compile */
    343 	gl.compileShader(shader_id);
    344 	GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
    345 
    346 	/* Get compilation status */
    347 	gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
    348 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
    349 
    350 	/* Log compilation error */
    351 	if (GL_TRUE != status)
    352 	{
    353 		glw::GLint				 length = 0;
    354 		std::vector<glw::GLchar> message;
    355 
    356 		/* Error log length */
    357 		gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
    358 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
    359 
    360 		/* Prepare storage */
    361 		message.resize(length);
    362 
    363 		/* Get error log */
    364 		gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
    365 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
    366 
    367 		/* Log */
    368 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n"
    369 											<< &message[0] << "\nShader source\n"
    370 											<< shader_code << tcu::TestLog::EndMessage;
    371 
    372 		TCU_FAIL("Failed to compile shader");
    373 	}
    374 }
    375 
    376 /** Checks whether the tested driver supports GL_ARB_get_program_binary
    377  *
    378  *  @return true if the extension is supported and, also, at least one binary format.
    379  **/
    380 bool Utils::program::isProgramBinarySupported() const
    381 {
    382 	glw::GLint n_program_binary_formats = 0;
    383 
    384 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    385 
    386 	if (m_context.getContextInfo().isExtensionSupported("GL_ARB_get_program_binary"))
    387 	{
    388 		gl.getIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &n_program_binary_formats);
    389 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed.");
    390 	}
    391 
    392 	return n_program_binary_formats > 0;
    393 }
    394 
    395 /** Create program from provided binary
    396  *
    397  * @param binary        Buffer with binary form of program
    398  * @param binary_format Format of <binary> data
    399  **/
    400 void Utils::program::createFromBinary(const std::vector<GLubyte>& binary, GLenum binary_format)
    401 {
    402 	/* GL entry points */
    403 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    404 
    405 	/* Create program object */
    406 	m_program_object_id = gl.createProgram();
    407 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
    408 
    409 	gl.programBinary(m_program_object_id, binary_format, &binary[0], (GLsizei)binary.size());
    410 	GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramBinary");
    411 }
    412 
    413 /** Get binary form of program
    414  *
    415  * @param binary        Buffer for binary data
    416  * @param binary_format Format of binary data
    417  **/
    418 void Utils::program::getBinary(std::vector<GLubyte>& binary, GLenum& binary_format) const
    419 {
    420 	/* GL entry points */
    421 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    422 
    423 	/* Get binary size */
    424 	GLint length = 0;
    425 	gl.getProgramiv(m_program_object_id, GL_PROGRAM_BINARY_LENGTH, &length);
    426 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
    427 
    428 	/* Allocate storage */
    429 	binary.resize(length);
    430 
    431 	/* Get binary */
    432 	gl.getProgramBinary(m_program_object_id, (GLsizei)binary.size(), &length, &binary_format, &binary[0]);
    433 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramBinary");
    434 }
    435 
    436 /** Get subroutine index
    437  *
    438  * @param subroutine_name Subroutine name
    439  *
    440  * @return Index of subroutine
    441  **/
    442 GLuint Utils::program::getSubroutineIndex(const glw::GLchar* subroutine_name, glw::GLenum shader_stage) const
    443 {
    444 	const glw::Functions& gl	= m_context.getRenderContext().getFunctions();
    445 	GLuint				  index = -1;
    446 
    447 	index = gl.getSubroutineIndex(m_program_object_id, shader_stage, subroutine_name);
    448 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetSubroutineIndex");
    449 
    450 	if (GL_INVALID_INDEX == index)
    451 	{
    452 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Subroutine: " << subroutine_name
    453 											<< " is not available" << tcu::TestLog::EndMessage;
    454 
    455 		TCU_FAIL("Subroutine is not available");
    456 	}
    457 
    458 	return index;
    459 }
    460 
    461 /** Get subroutine uniform location
    462  *
    463  * @param uniform_name Subroutine uniform name
    464  *
    465  * @return Location of subroutine uniform
    466  **/
    467 GLint Utils::program::getSubroutineUniformLocation(const glw::GLchar* uniform_name, glw::GLenum shader_stage) const
    468 {
    469 	const glw::Functions& gl	   = m_context.getRenderContext().getFunctions();
    470 	GLint				  location = -1;
    471 
    472 	location = gl.getSubroutineUniformLocation(m_program_object_id, shader_stage, uniform_name);
    473 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetSubroutineUniformLocation");
    474 
    475 	if (-1 == location)
    476 	{
    477 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Subroutine uniform: " << uniform_name
    478 											<< " is not available" << tcu::TestLog::EndMessage;
    479 
    480 		TCU_FAIL("Subroutine uniform is not available");
    481 	}
    482 
    483 	return location;
    484 }
    485 
    486 /** Get uniform location
    487  *
    488  * @param uniform_name Subroutine uniform name
    489  *
    490  * @return Location of uniform
    491  **/
    492 GLint Utils::program::getUniformLocation(const glw::GLchar* uniform_name) const
    493 {
    494 	const glw::Functions& gl	   = m_context.getRenderContext().getFunctions();
    495 	GLint				  location = -1;
    496 
    497 	location = gl.getUniformLocation(m_program_object_id, uniform_name);
    498 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
    499 
    500 	if (-1 == location)
    501 	{
    502 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Uniform: " << uniform_name
    503 											<< " is not available" << tcu::TestLog::EndMessage;
    504 
    505 		TCU_FAIL("Uniform is not available");
    506 	}
    507 
    508 	return location;
    509 }
    510 
    511 /** Attach shaders and link program
    512  *
    513  **/
    514 void Utils::program::link() const
    515 {
    516 	/* GL entry points */
    517 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    518 
    519 	/* Link status */
    520 	glw::GLint status = GL_FALSE;
    521 
    522 	/* Attach shaders */
    523 	if (0 != m_compute_shader_id)
    524 	{
    525 		gl.attachShader(m_program_object_id, m_compute_shader_id);
    526 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    527 	}
    528 
    529 	if (0 != m_fragment_shader_id)
    530 	{
    531 		gl.attachShader(m_program_object_id, m_fragment_shader_id);
    532 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    533 	}
    534 
    535 	if (0 != m_geometry_shader_id)
    536 	{
    537 		gl.attachShader(m_program_object_id, m_geometry_shader_id);
    538 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    539 	}
    540 
    541 	if (0 != m_tesselation_control_shader_id)
    542 	{
    543 		gl.attachShader(m_program_object_id, m_tesselation_control_shader_id);
    544 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    545 	}
    546 
    547 	if (0 != m_tesselation_evaluation_shader_id)
    548 	{
    549 		gl.attachShader(m_program_object_id, m_tesselation_evaluation_shader_id);
    550 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    551 	}
    552 
    553 	if (0 != m_vertex_shader_id)
    554 	{
    555 		gl.attachShader(m_program_object_id, m_vertex_shader_id);
    556 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    557 	}
    558 
    559 	/* Link */
    560 	gl.linkProgram(m_program_object_id);
    561 	GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
    562 
    563 	/* Get link status */
    564 	gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
    565 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
    566 
    567 	/* Log link error */
    568 	if (GL_TRUE != status)
    569 	{
    570 		glw::GLint				 length = 0;
    571 		std::vector<glw::GLchar> message;
    572 
    573 		/* Get error log length */
    574 		gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
    575 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
    576 
    577 		message.resize(length);
    578 
    579 		/* Get error log */
    580 		gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
    581 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
    582 
    583 		/* Log */
    584 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
    585 											<< &message[0] << tcu::TestLog::EndMessage;
    586 
    587 		TCU_FAIL("Failed to link program");
    588 	}
    589 }
    590 
    591 /** Delete program object and all attached shaders
    592  *
    593  **/
    594 void Utils::program::remove()
    595 {
    596 	/* GL entry points */
    597 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    598 
    599 	/* Make sure program object is no longer used by GL */
    600 	gl.useProgram(0);
    601 
    602 	/* Clean program object */
    603 	if (0 != m_program_object_id)
    604 	{
    605 		gl.deleteProgram(m_program_object_id);
    606 		m_program_object_id = 0;
    607 	}
    608 
    609 	/* Clean shaders */
    610 	if (0 != m_compute_shader_id)
    611 	{
    612 		gl.deleteShader(m_compute_shader_id);
    613 		m_compute_shader_id = 0;
    614 	}
    615 
    616 	if (0 != m_fragment_shader_id)
    617 	{
    618 		gl.deleteShader(m_fragment_shader_id);
    619 		m_fragment_shader_id = 0;
    620 	}
    621 
    622 	if (0 != m_geometry_shader_id)
    623 	{
    624 		gl.deleteShader(m_geometry_shader_id);
    625 		m_geometry_shader_id = 0;
    626 	}
    627 
    628 	if (0 != m_tesselation_control_shader_id)
    629 	{
    630 		gl.deleteShader(m_tesselation_control_shader_id);
    631 		m_tesselation_control_shader_id = 0;
    632 	}
    633 
    634 	if (0 != m_tesselation_evaluation_shader_id)
    635 	{
    636 		gl.deleteShader(m_tesselation_evaluation_shader_id);
    637 		m_tesselation_evaluation_shader_id = 0;
    638 	}
    639 
    640 	if (0 != m_vertex_shader_id)
    641 	{
    642 		gl.deleteShader(m_vertex_shader_id);
    643 		m_vertex_shader_id = 0;
    644 	}
    645 }
    646 
    647 /** Execute UseProgram
    648  *
    649  **/
    650 void Utils::program::use() const
    651 {
    652 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    653 
    654 	gl.useProgram(m_program_object_id);
    655 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
    656 }
    657 
    658 /** Constructor.
    659  *
    660  * @param context CTS context.
    661  **/
    662 Utils::texture::texture(deqp::Context& context) : m_id(0), m_context(context)
    663 {
    664 	/* Nothing to done here */
    665 }
    666 
    667 /** Destructor
    668  *
    669  **/
    670 Utils::texture::~texture()
    671 {
    672 	if (0 != m_id)
    673 	{
    674 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    675 
    676 		gl.deleteTextures(1, &m_id);
    677 		m_id = 0;
    678 	}
    679 }
    680 
    681 /** Bind texture to GL_TEXTURE_2D
    682  *
    683  **/
    684 void Utils::texture::bind()
    685 {
    686 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    687 
    688 	gl.bindTexture(GL_TEXTURE_2D, m_id);
    689 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
    690 }
    691 
    692 /** Create 2d texture
    693  *
    694  * @param width           Width of texture
    695  * @param height          Height of texture
    696  * @param internal_format Internal format of texture
    697  **/
    698 void Utils::texture::create(glw::GLuint width, glw::GLuint height, glw::GLenum internal_format)
    699 {
    700 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    701 
    702 	gl.genTextures(1, &m_id);
    703 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
    704 
    705 	bind();
    706 
    707 	gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, internal_format, width, height);
    708 	GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
    709 }
    710 
    711 /** Get contents of texture
    712  *
    713  * @param format   Format of image
    714  * @param type     Type of image
    715  * @param out_data Buffer for image
    716  **/
    717 void Utils::texture::get(glw::GLenum format, glw::GLenum type, glw::GLvoid* out_data)
    718 {
    719 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    720 
    721 	bind();
    722 
    723 	gl.getTexImage(GL_TEXTURE_2D, 0, format, type, out_data);
    724 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
    725 }
    726 
    727 /** Update contents of texture
    728  *
    729  * @param width  Width of texture
    730  * @param height Height of texture
    731  * @param format Format of data
    732  * @param type   Type of data
    733  * @param data   Buffer with image
    734  **/
    735 void Utils::texture::update(glw::GLuint width, glw::GLuint height, glw::GLenum format, glw::GLenum type,
    736 							glw::GLvoid* data)
    737 {
    738 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    739 
    740 	bind();
    741 
    742 	gl.texSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, width, height, format, type, data);
    743 	GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
    744 }
    745 
    746 /** Constructor.
    747  *
    748  * @param context CTS context.
    749  **/
    750 Utils::vertexArray::vertexArray(deqp::Context& context) : m_id(0), m_context(context)
    751 {
    752 }
    753 
    754 /** Destructor
    755  *
    756  **/
    757 Utils::vertexArray::~vertexArray()
    758 {
    759 	if (0 != m_id)
    760 	{
    761 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    762 
    763 		gl.deleteVertexArrays(1, &m_id);
    764 
    765 		m_id = 0;
    766 	}
    767 }
    768 
    769 /** Execute BindVertexArray
    770  *
    771  **/
    772 void Utils::vertexArray::bind()
    773 {
    774 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    775 
    776 	gl.bindVertexArray(m_id);
    777 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
    778 }
    779 
    780 /** Execute GenVertexArrays
    781  *
    782  **/
    783 void Utils::vertexArray::generate()
    784 {
    785 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    786 
    787 	gl.genVertexArrays(1, &m_id);
    788 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
    789 }
    790 
    791 /** Builds a program object consisting of up to 5 shader stages
    792  *  (vertex/tessellation control/tessellation evaluation/geometry/fragment).
    793  *  The shaders are attached to the program object, then compiled. Finally,
    794  *  the program object is linked.
    795  *
    796  *  XFB can be optionally configured for the program object.
    797  *
    798  *  Should an error be reported by GL implementation, a TestError
    799  *  exception will be thrown.
    800  *
    801  *  @param gl             OpenGL functions from the active rendering context.
    802  *  @param vs_body        Body to use for the vertex shader. Can be an empty string.
    803  *  @param tc_body        Body to use for the tessellation control shader. Can be
    804  *                        an empty string.
    805  *  @param te_body        Body to use for the tessellation evaluation shader. Can be
    806  *                        an empty string.
    807  *  @param gs_body        Body to use for the geometry shader. Can be an empty string.
    808  *  @param fs_body        Body to use for the fragment shader. Can be an empty string.
    809  *  @param xfb_varyings   An array of names of varyings to use for XFB. Can be NULL.
    810  *  @param n_xfb_varyings Amount of XFB varyings defined in @param xfb_varyings.Can be 0.
    811  *  @param out_vs_id      Deref will be used to store GL id of a generated vertex shader.
    812  *                        Can be NULL in which case no vertex shader will be used for the
    813  *                        program object.
    814  *  @param out_tc_id      Deref will be used to store GL id of a generated tess control shader.
    815  *                        Can be NULL in which case no tess control shader will be used for the
    816  *                        program object.
    817  *  @param out_te_id      Deref will be used to store GL id of a generated tess evaluation shader.
    818  *                        Can be NULL in which case no tess evaluation shader will be used for the
    819  *                        program object.
    820  *  @param out_gs_id      Deref will be used to store GL id of a generated geometry shader.
    821  *                        Can be NULL in which case no geometry shader will be used for the
    822  *                        program object.
    823  *  @param out_fs_id      Deref will be used to store GL id of a generated fragment shader.
    824  *                        Can be NULL in which case no fragment shader will be used for the
    825  *                        program object.
    826  *  @param out_po_id      Deref will be used to store GL id of a generated program object.
    827  *                        Must not be NULL.
    828  *
    829  *  @return true if the program was built successfully, false otherwise.
    830  *  */
    831 bool Utils::buildProgram(const glw::Functions& gl, const std::string& vs_body, const std::string& tc_body,
    832 						 const std::string& te_body, const std::string& gs_body, const std::string& fs_body,
    833 						 const glw::GLchar** xfb_varyings, const unsigned int& n_xfb_varyings, glw::GLuint* out_vs_id,
    834 						 glw::GLuint* out_tc_id, glw::GLuint* out_te_id, glw::GLuint* out_gs_id, glw::GLuint* out_fs_id,
    835 						 glw::GLuint* out_po_id)
    836 {
    837 	bool result = false;
    838 
    839 	/* Link the program object */
    840 	glw::GLint link_status = GL_FALSE;
    841 
    842 	/* Create objects, set up shader bodies and attach all requested shaders to the program object */
    843 	*out_po_id = gl.createProgram();
    844 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
    845 
    846 	if (out_vs_id != DE_NULL)
    847 	{
    848 		const char* vs_body_raw_ptr = vs_body.c_str();
    849 
    850 		*out_vs_id = gl.createShader(GL_VERTEX_SHADER);
    851 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
    852 
    853 		gl.attachShader(*out_po_id, *out_vs_id);
    854 		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
    855 
    856 		gl.shaderSource(*out_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */);
    857 		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
    858 	}
    859 
    860 	if (out_tc_id != DE_NULL)
    861 	{
    862 		const char* tc_body_raw_ptr = tc_body.c_str();
    863 
    864 		*out_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
    865 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
    866 
    867 		gl.attachShader(*out_po_id, *out_tc_id);
    868 		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
    869 
    870 		gl.shaderSource(*out_tc_id, 1 /* count */, &tc_body_raw_ptr, DE_NULL /* length */);
    871 		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
    872 	}
    873 
    874 	if (out_te_id != DE_NULL)
    875 	{
    876 		const char* te_body_raw_ptr = te_body.c_str();
    877 
    878 		*out_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
    879 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
    880 
    881 		gl.attachShader(*out_po_id, *out_te_id);
    882 		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
    883 
    884 		gl.shaderSource(*out_te_id, 1 /* count */, &te_body_raw_ptr, DE_NULL /* length */);
    885 		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
    886 	}
    887 
    888 	if (out_gs_id != DE_NULL)
    889 	{
    890 		const char* gs_body_raw_ptr = gs_body.c_str();
    891 
    892 		*out_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
    893 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
    894 
    895 		gl.attachShader(*out_po_id, *out_gs_id);
    896 		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
    897 
    898 		gl.shaderSource(*out_gs_id, 1 /* count */, &gs_body_raw_ptr, DE_NULL /* length */);
    899 		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
    900 	}
    901 
    902 	if (out_fs_id != DE_NULL)
    903 	{
    904 		const char* fs_body_raw_ptr = fs_body.c_str();
    905 
    906 		*out_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
    907 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
    908 
    909 		gl.attachShader(*out_po_id, *out_fs_id);
    910 		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
    911 
    912 		gl.shaderSource(*out_fs_id, 1 /* count */, &fs_body_raw_ptr, DE_NULL /* length */);
    913 		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
    914 	}
    915 
    916 	/* Compile all shaders */
    917 	const glw::GLuint so_ids[] = { (out_vs_id != DE_NULL) ? *out_vs_id : 0, (out_tc_id != DE_NULL) ? *out_tc_id : 0,
    918 								   (out_te_id != DE_NULL) ? *out_te_id : 0, (out_gs_id != DE_NULL) ? *out_gs_id : 0,
    919 								   (out_fs_id != DE_NULL) ? *out_fs_id : 0 };
    920 	const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]);
    921 
    922 	for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
    923 	{
    924 		glw::GLuint so_id = so_ids[n_so_id];
    925 
    926 		if (so_id != 0)
    927 		{
    928 			glw::GLint compile_status = GL_FALSE;
    929 
    930 			gl.compileShader(so_id);
    931 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
    932 
    933 			gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
    934 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
    935 
    936 			if (compile_status != GL_TRUE)
    937 			{
    938 				goto end;
    939 			}
    940 		} /* if (so_id != 0) */
    941 	}	 /* for (all shader objects) */
    942 
    943 	/* Set up XFB */
    944 	if (xfb_varyings != NULL)
    945 	{
    946 		gl.transformFeedbackVaryings(*out_po_id, n_xfb_varyings, xfb_varyings, GL_INTERLEAVED_ATTRIBS);
    947 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
    948 	}
    949 
    950 	gl.linkProgram(*out_po_id);
    951 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
    952 
    953 	gl.getProgramiv(*out_po_id, GL_LINK_STATUS, &link_status);
    954 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
    955 
    956 	if (link_status != GL_TRUE)
    957 	{
    958 		goto end;
    959 	}
    960 
    961 	/* All done */
    962 	result = true;
    963 
    964 end:
    965 	return result;
    966 }
    967 
    968 /** Retrieves base variable type for user-specified variable type
    969  *  (eg. float for vec4)
    970  *
    971  *  @param variable_type Variable type to use for the query.
    972  *
    973  *  @return As per description.
    974  **/
    975 Utils::_variable_type Utils::getBaseVariableType(const _variable_type& variable_type)
    976 {
    977 	_variable_type result = VARIABLE_TYPE_UNKNOWN;
    978 
    979 	switch (variable_type)
    980 	{
    981 	case VARIABLE_TYPE_BOOL:
    982 	case VARIABLE_TYPE_BVEC2:
    983 	case VARIABLE_TYPE_BVEC3:
    984 	case VARIABLE_TYPE_BVEC4:
    985 	{
    986 		result = VARIABLE_TYPE_BOOL;
    987 
    988 		break;
    989 	}
    990 
    991 	case VARIABLE_TYPE_DOUBLE:
    992 	case VARIABLE_TYPE_DVEC2:
    993 	case VARIABLE_TYPE_DVEC3:
    994 	case VARIABLE_TYPE_DVEC4:
    995 	{
    996 		result = VARIABLE_TYPE_DOUBLE;
    997 
    998 		break;
    999 	}
   1000 
   1001 	case VARIABLE_TYPE_FLOAT:
   1002 	case VARIABLE_TYPE_MAT2:
   1003 	case VARIABLE_TYPE_MAT2X3:
   1004 	case VARIABLE_TYPE_MAT2X4:
   1005 	case VARIABLE_TYPE_MAT3:
   1006 	case VARIABLE_TYPE_MAT3X2:
   1007 	case VARIABLE_TYPE_MAT3X4:
   1008 	case VARIABLE_TYPE_MAT4:
   1009 	case VARIABLE_TYPE_MAT4X2:
   1010 	case VARIABLE_TYPE_MAT4X3:
   1011 	case VARIABLE_TYPE_VEC2:
   1012 	case VARIABLE_TYPE_VEC3:
   1013 	case VARIABLE_TYPE_VEC4:
   1014 	{
   1015 		result = VARIABLE_TYPE_FLOAT;
   1016 
   1017 		break;
   1018 	}
   1019 
   1020 	case VARIABLE_TYPE_INT:
   1021 	case VARIABLE_TYPE_IVEC2:
   1022 	case VARIABLE_TYPE_IVEC3:
   1023 	case VARIABLE_TYPE_IVEC4:
   1024 	{
   1025 		result = VARIABLE_TYPE_INT;
   1026 
   1027 		break;
   1028 	}
   1029 
   1030 	case VARIABLE_TYPE_UINT:
   1031 	case VARIABLE_TYPE_UVEC2:
   1032 	case VARIABLE_TYPE_UVEC3:
   1033 	case VARIABLE_TYPE_UVEC4:
   1034 	{
   1035 		result = VARIABLE_TYPE_UINT;
   1036 
   1037 		break;
   1038 	}
   1039 
   1040 	default:
   1041 	{
   1042 		TCU_FAIL("Unrecognized variable type");
   1043 	}
   1044 	} /* switch (variable_type) */
   1045 
   1046 	return result;
   1047 }
   1048 
   1049 /** Retrieves size of a single component (in bytes) for user-specified
   1050  *  variable type.
   1051  *
   1052  *  @param variable_type Variable type to use for the query.
   1053  *
   1054  *  @return As per description.
   1055  **/
   1056 unsigned int Utils::getComponentSizeForVariableType(const _variable_type& variable_type)
   1057 {
   1058 	_variable_type base_variable_type = getBaseVariableType(variable_type);
   1059 	unsigned int   result			  = 0;
   1060 
   1061 	switch (base_variable_type)
   1062 	{
   1063 	case VARIABLE_TYPE_BOOL:
   1064 		result = sizeof(bool);
   1065 		break;
   1066 	case VARIABLE_TYPE_DOUBLE:
   1067 		result = sizeof(double);
   1068 		break;
   1069 	case VARIABLE_TYPE_FLOAT:
   1070 		result = sizeof(float);
   1071 		break;
   1072 	case VARIABLE_TYPE_INT:
   1073 		result = sizeof(int);
   1074 		break;
   1075 	case VARIABLE_TYPE_UINT:
   1076 		result = sizeof(unsigned int);
   1077 		break;
   1078 
   1079 	default:
   1080 	{
   1081 		TCU_FAIL("Unrecognized base variable type");
   1082 	}
   1083 	} /* switch (variable_type) */
   1084 
   1085 	return result;
   1086 }
   1087 
   1088 /** Retrieves a GLenum value corresponding to internal shader stage
   1089  *  representation.
   1090  *
   1091  *  @param shader_stage Shader stage to user for the query.
   1092  *
   1093  *  @return Requested value or GL_NONE if the stage was not recognized.
   1094  **/
   1095 glw::GLenum Utils::getGLenumForShaderStage(const _shader_stage& shader_stage)
   1096 {
   1097 	glw::GLenum result = GL_NONE;
   1098 
   1099 	switch (shader_stage)
   1100 	{
   1101 	case SHADER_STAGE_VERTEX:
   1102 		result = GL_VERTEX_SHADER;
   1103 		break;
   1104 	case SHADER_STAGE_TESSELLATION_CONTROL:
   1105 		result = GL_TESS_CONTROL_SHADER;
   1106 		break;
   1107 	case SHADER_STAGE_TESSELLATION_EVALUATION:
   1108 		result = GL_TESS_EVALUATION_SHADER;
   1109 		break;
   1110 	case SHADER_STAGE_GEOMETRY:
   1111 		result = GL_GEOMETRY_SHADER;
   1112 		break;
   1113 	case SHADER_STAGE_FRAGMENT:
   1114 		result = GL_FRAGMENT_SHADER;
   1115 		break;
   1116 
   1117 	default:
   1118 	{
   1119 		TCU_FAIL("Unrecognized shader stage requested");
   1120 	}
   1121 	} /* switch (shader_stage) */
   1122 
   1123 	return result;
   1124 }
   1125 
   1126 /** Retrieves number of components that user-specified variable type supports.
   1127  *
   1128  *  @param variable_type GLSL variable type to use for the query.
   1129  *
   1130  *  @return As per description.
   1131  **/
   1132 unsigned int Utils::getNumberOfComponentsForVariableType(const _variable_type& variable_type)
   1133 {
   1134 	unsigned int result = 0;
   1135 
   1136 	switch (variable_type)
   1137 	{
   1138 	case VARIABLE_TYPE_BOOL:
   1139 	case VARIABLE_TYPE_DOUBLE:
   1140 	case VARIABLE_TYPE_FLOAT:
   1141 	case VARIABLE_TYPE_INT:
   1142 	case VARIABLE_TYPE_UINT:
   1143 	{
   1144 		result = 1;
   1145 
   1146 		break;
   1147 	}
   1148 
   1149 	case VARIABLE_TYPE_BVEC2:
   1150 	case VARIABLE_TYPE_DVEC2:
   1151 	case VARIABLE_TYPE_IVEC2:
   1152 	case VARIABLE_TYPE_UVEC2:
   1153 	case VARIABLE_TYPE_VEC2:
   1154 	{
   1155 		result = 2;
   1156 
   1157 		break;
   1158 	}
   1159 
   1160 	case VARIABLE_TYPE_BVEC3:
   1161 	case VARIABLE_TYPE_DVEC3:
   1162 	case VARIABLE_TYPE_IVEC3:
   1163 	case VARIABLE_TYPE_UVEC3:
   1164 	case VARIABLE_TYPE_VEC3:
   1165 	{
   1166 		result = 3;
   1167 
   1168 		break;
   1169 	}
   1170 
   1171 	case VARIABLE_TYPE_BVEC4:
   1172 	case VARIABLE_TYPE_DVEC4:
   1173 	case VARIABLE_TYPE_IVEC4:
   1174 	case VARIABLE_TYPE_MAT2:
   1175 	case VARIABLE_TYPE_UVEC4:
   1176 	case VARIABLE_TYPE_VEC4:
   1177 	{
   1178 		result = 4;
   1179 
   1180 		break;
   1181 	}
   1182 
   1183 	case VARIABLE_TYPE_MAT2X3:
   1184 	case VARIABLE_TYPE_MAT3X2:
   1185 	{
   1186 		result = 6;
   1187 
   1188 		break;
   1189 	}
   1190 
   1191 	case VARIABLE_TYPE_MAT2X4:
   1192 	case VARIABLE_TYPE_MAT4X2:
   1193 	{
   1194 		result = 8;
   1195 
   1196 		break;
   1197 	}
   1198 
   1199 	case VARIABLE_TYPE_MAT3:
   1200 	{
   1201 		result = 9;
   1202 
   1203 		break;
   1204 	}
   1205 
   1206 	case VARIABLE_TYPE_MAT3X4:
   1207 	case VARIABLE_TYPE_MAT4X3:
   1208 	{
   1209 		result = 12;
   1210 
   1211 		break;
   1212 	}
   1213 
   1214 	case VARIABLE_TYPE_MAT4:
   1215 	{
   1216 		result = 16;
   1217 
   1218 		break;
   1219 	}
   1220 
   1221 	default:
   1222 		break;
   1223 	} /* switch (variable_type) */
   1224 
   1225 	return result;
   1226 }
   1227 
   1228 /** Retrieves a literal defining user-specified shader stage enum.
   1229  *
   1230  *  @param shader_stage Shader stage to use for the query.
   1231  *
   1232  *  @return Requested string or "?" if the stage was not recognized.
   1233  **/
   1234 std::string Utils::getShaderStageString(const _shader_stage& shader_stage)
   1235 {
   1236 	std::string result = "?";
   1237 
   1238 	switch (shader_stage)
   1239 	{
   1240 	case SHADER_STAGE_FRAGMENT:
   1241 		result = "Fragment Shader";
   1242 		break;
   1243 	case SHADER_STAGE_GEOMETRY:
   1244 		result = "Geometry Shader";
   1245 		break;
   1246 	case SHADER_STAGE_TESSELLATION_CONTROL:
   1247 		result = "Tessellation Control Shader";
   1248 		break;
   1249 	case SHADER_STAGE_TESSELLATION_EVALUATION:
   1250 		result = "Tessellation Evaluation Shader";
   1251 		break;
   1252 	case SHADER_STAGE_VERTEX:
   1253 		result = "Vertex Shader";
   1254 		break;
   1255 
   1256 	default:
   1257 	{
   1258 		TCU_FAIL("Unrecognized shader stage");
   1259 	}
   1260 	} /* switch (shader_stage) */
   1261 
   1262 	return result;
   1263 }
   1264 
   1265 /** Retrieves a literal defining user-specified shader stage enum.
   1266  *
   1267  *  @param shader_stage_glenum Shader stage to use for the query.
   1268  *
   1269  *  @return Requested string or "?" if the stage was not recognized.
   1270  **/
   1271 std::string Utils::getShaderStageStringFromGLEnum(const glw::GLenum shader_stage_glenum)
   1272 {
   1273 	std::string result = "?";
   1274 
   1275 	switch (shader_stage_glenum)
   1276 	{
   1277 	case GL_FRAGMENT_SHADER:
   1278 		result = "Fragment Shader";
   1279 		break;
   1280 	case GL_GEOMETRY_SHADER:
   1281 		result = "Geometry Shader";
   1282 		break;
   1283 	case GL_TESS_CONTROL_SHADER:
   1284 		result = "Tessellation Control Shader";
   1285 		break;
   1286 	case GL_TESS_EVALUATION_SHADER:
   1287 		result = "Tessellation Evaluation Shader";
   1288 		break;
   1289 	case GL_VERTEX_SHADER:
   1290 		result = "Vertex Shader";
   1291 		break;
   1292 
   1293 	default:
   1294 	{
   1295 		TCU_FAIL("Unrecognized shader string");
   1296 	}
   1297 	} /* switch (shader_stage_glenum) */
   1298 
   1299 	return result;
   1300 }
   1301 
   1302 /** Returns string that represents program interface name
   1303  *
   1304  * @param program_interface Program interface
   1305  *
   1306  * @return String representation of known program interface
   1307  **/
   1308 const GLchar* Utils::programInterfaceToStr(glw::GLenum program_interface)
   1309 {
   1310 	const GLchar* string = "Unknown program interface";
   1311 
   1312 	switch (program_interface)
   1313 	{
   1314 	case GL_VERTEX_SUBROUTINE:
   1315 		string = "GL_VERTEX_SUBROUTINE";
   1316 		break;
   1317 	case GL_VERTEX_SUBROUTINE_UNIFORM:
   1318 		string = "GL_VERTEX_SUBROUTINE_UNIFORM";
   1319 		break;
   1320 	default:
   1321 		TCU_FAIL("Not implemented");
   1322 		break;
   1323 	};
   1324 
   1325 	return string;
   1326 }
   1327 
   1328 /** Returns string that represents pname's name
   1329  *
   1330  * @param pname pname
   1331  *
   1332  * @return String representation of known pnames
   1333  **/
   1334 const GLchar* Utils::pnameToStr(glw::GLenum pname)
   1335 {
   1336 	const GLchar* string = "Unknown pname";
   1337 
   1338 	switch (pname)
   1339 	{
   1340 	case GL_ACTIVE_SUBROUTINE_UNIFORMS:
   1341 		string = "GL_ACTIVE_SUBROUTINE_UNIFORMS";
   1342 		break;
   1343 	case GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS:
   1344 		string = "GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS";
   1345 		break;
   1346 	case GL_ACTIVE_SUBROUTINES:
   1347 		string = "GL_ACTIVE_SUBROUTINES";
   1348 		break;
   1349 	case GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH:
   1350 		string = "GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH";
   1351 		break;
   1352 	case GL_ACTIVE_SUBROUTINE_MAX_LENGTH:
   1353 		string = "GL_ACTIVE_SUBROUTINE_MAX_LENGTH";
   1354 		break;
   1355 	case GL_NUM_COMPATIBLE_SUBROUTINES:
   1356 		string = "GL_NUM_COMPATIBLE_SUBROUTINES";
   1357 		break;
   1358 	case GL_UNIFORM_SIZE:
   1359 		string = "GL_UNIFORM_SIZE";
   1360 		break;
   1361 	case GL_COMPATIBLE_SUBROUTINES:
   1362 		string = "GL_COMPATIBLE_SUBROUTINES";
   1363 		break;
   1364 	case GL_UNIFORM_NAME_LENGTH:
   1365 		string = "GL_UNIFORM_NAME_LENGTH";
   1366 		break;
   1367 	case GL_ACTIVE_RESOURCES:
   1368 		string = "GL_ACTIVE_RESOURCES";
   1369 		break;
   1370 	case GL_MAX_NAME_LENGTH:
   1371 		string = "GL_MAX_NAME_LENGTH";
   1372 		break;
   1373 	case GL_MAX_NUM_COMPATIBLE_SUBROUTINES:
   1374 		string = "GL_MAX_NUM_COMPATIBLE_SUBROUTINES";
   1375 		break;
   1376 	case GL_NAME_LENGTH:
   1377 		string = "GL_NAME_LENGTH";
   1378 		break;
   1379 	case GL_ARRAY_SIZE:
   1380 		string = "GL_ARRAY_SIZE";
   1381 		break;
   1382 	case GL_LOCATION:
   1383 		string = "GL_LOCATION";
   1384 		break;
   1385 	default:
   1386 		TCU_FAIL("Not implemented");
   1387 		break;
   1388 	};
   1389 
   1390 	return string;
   1391 }
   1392 
   1393 bool Utils::compare(const glw::GLfloat& left, const glw::GLfloat& right)
   1394 {
   1395 	static const glw::GLfloat m_epsilon = 0.00001f;
   1396 
   1397 	if (m_epsilon < std::abs(right - left))
   1398 	{
   1399 		return false;
   1400 	}
   1401 	else
   1402 	{
   1403 		return true;
   1404 	}
   1405 }
   1406 
   1407 /** Returns a variable type enum corresponding to user-specified base variable type
   1408  *  and the number of components it should support.
   1409  *
   1410  *  @param base_variable_type Base variable type to use for the query.
   1411  *  @param n_components       Number of components to consider for the query.
   1412  *
   1413  *  @return As per description.
   1414  **/
   1415 Utils::_variable_type Utils::getVariableTypeFromProperties(const _variable_type& base_variable_type,
   1416 														   const unsigned int&   n_components)
   1417 {
   1418 	_variable_type result = VARIABLE_TYPE_UNKNOWN;
   1419 
   1420 	switch (base_variable_type)
   1421 	{
   1422 	case VARIABLE_TYPE_BOOL:
   1423 	{
   1424 		switch (n_components)
   1425 		{
   1426 		case 1:
   1427 			result = VARIABLE_TYPE_BOOL;
   1428 			break;
   1429 		case 2:
   1430 			result = VARIABLE_TYPE_BVEC2;
   1431 			break;
   1432 		case 3:
   1433 			result = VARIABLE_TYPE_BVEC3;
   1434 			break;
   1435 		case 4:
   1436 			result = VARIABLE_TYPE_BVEC4;
   1437 			break;
   1438 
   1439 		default:
   1440 		{
   1441 			TCU_FAIL("Unsupported number of components requested");
   1442 		}
   1443 		} /* switch (n_components) */
   1444 
   1445 		break;
   1446 	}
   1447 
   1448 	case VARIABLE_TYPE_DOUBLE:
   1449 	{
   1450 		switch (n_components)
   1451 		{
   1452 		case 1:
   1453 			result = VARIABLE_TYPE_DOUBLE;
   1454 			break;
   1455 		case 2:
   1456 			result = VARIABLE_TYPE_DVEC2;
   1457 			break;
   1458 		case 3:
   1459 			result = VARIABLE_TYPE_DVEC3;
   1460 			break;
   1461 		case 4:
   1462 			result = VARIABLE_TYPE_DVEC4;
   1463 			break;
   1464 
   1465 		default:
   1466 		{
   1467 			TCU_FAIL("Unsupported number of components requested");
   1468 		}
   1469 		} /* switch (n_components) */
   1470 
   1471 		break;
   1472 	}
   1473 
   1474 	case VARIABLE_TYPE_FLOAT:
   1475 	{
   1476 		switch (n_components)
   1477 		{
   1478 		case 1:
   1479 			result = VARIABLE_TYPE_FLOAT;
   1480 			break;
   1481 		case 2:
   1482 			result = VARIABLE_TYPE_VEC2;
   1483 			break;
   1484 		case 3:
   1485 			result = VARIABLE_TYPE_VEC3;
   1486 			break;
   1487 		case 4:
   1488 			result = VARIABLE_TYPE_VEC4;
   1489 			break;
   1490 
   1491 		default:
   1492 		{
   1493 			TCU_FAIL("Unsupported number of components requested");
   1494 		}
   1495 		} /* switch (n_components) */
   1496 
   1497 		break;
   1498 	}
   1499 
   1500 	case VARIABLE_TYPE_INT:
   1501 	{
   1502 		switch (n_components)
   1503 		{
   1504 		case 1:
   1505 			result = VARIABLE_TYPE_INT;
   1506 			break;
   1507 		case 2:
   1508 			result = VARIABLE_TYPE_IVEC2;
   1509 			break;
   1510 		case 3:
   1511 			result = VARIABLE_TYPE_IVEC3;
   1512 			break;
   1513 		case 4:
   1514 			result = VARIABLE_TYPE_IVEC4;
   1515 			break;
   1516 
   1517 		default:
   1518 		{
   1519 			TCU_FAIL("Unsupported number of components requested");
   1520 		}
   1521 		} /* switch (n_components) */
   1522 
   1523 		break;
   1524 	}
   1525 
   1526 	case VARIABLE_TYPE_UINT:
   1527 	{
   1528 		switch (n_components)
   1529 		{
   1530 		case 1:
   1531 			result = VARIABLE_TYPE_UINT;
   1532 			break;
   1533 		case 2:
   1534 			result = VARIABLE_TYPE_UVEC2;
   1535 			break;
   1536 		case 3:
   1537 			result = VARIABLE_TYPE_UVEC3;
   1538 			break;
   1539 		case 4:
   1540 			result = VARIABLE_TYPE_UVEC4;
   1541 			break;
   1542 
   1543 		default:
   1544 		{
   1545 			TCU_FAIL("Unsupported number of components requested");
   1546 		}
   1547 		} /* switch (n_components) */
   1548 
   1549 		break;
   1550 	}
   1551 
   1552 	default:
   1553 	{
   1554 		TCU_FAIL("Unrecognized base variable type");
   1555 	}
   1556 	} /* switch (base_variable_type) */
   1557 
   1558 	return result;
   1559 }
   1560 
   1561 /** Returns a GLSL literal corresponding to user-specified variable type.
   1562  *
   1563  *  @param variable_type Variable type to use for the query.
   1564  *
   1565  *  @return As per description or [?] if @param variable_type was not
   1566  *          recognized.
   1567  **/
   1568 std::string Utils::getVariableTypeGLSLString(const _variable_type& variable_type)
   1569 {
   1570 	std::string result = "[?]";
   1571 
   1572 	switch (variable_type)
   1573 	{
   1574 	case VARIABLE_TYPE_BOOL:
   1575 		result = "bool";
   1576 		break;
   1577 	case VARIABLE_TYPE_BVEC2:
   1578 		result = "bvec2";
   1579 		break;
   1580 	case VARIABLE_TYPE_BVEC3:
   1581 		result = "bvec3";
   1582 		break;
   1583 	case VARIABLE_TYPE_BVEC4:
   1584 		result = "bvec4";
   1585 		break;
   1586 	case VARIABLE_TYPE_DOUBLE:
   1587 		result = "double";
   1588 		break;
   1589 	case VARIABLE_TYPE_DVEC2:
   1590 		result = "dvec2";
   1591 		break;
   1592 	case VARIABLE_TYPE_DVEC3:
   1593 		result = "dvec3";
   1594 		break;
   1595 	case VARIABLE_TYPE_DVEC4:
   1596 		result = "dvec4";
   1597 		break;
   1598 	case VARIABLE_TYPE_FLOAT:
   1599 		result = "float";
   1600 		break;
   1601 	case VARIABLE_TYPE_INT:
   1602 		result = "int";
   1603 		break;
   1604 	case VARIABLE_TYPE_IVEC2:
   1605 		result = "ivec2";
   1606 		break;
   1607 	case VARIABLE_TYPE_IVEC3:
   1608 		result = "ivec3";
   1609 		break;
   1610 	case VARIABLE_TYPE_IVEC4:
   1611 		result = "ivec4";
   1612 		break;
   1613 	case VARIABLE_TYPE_MAT2:
   1614 		result = "mat2";
   1615 		break;
   1616 	case VARIABLE_TYPE_MAT2X3:
   1617 		result = "mat2x3";
   1618 		break;
   1619 	case VARIABLE_TYPE_MAT2X4:
   1620 		result = "mat2x4";
   1621 		break;
   1622 	case VARIABLE_TYPE_MAT3:
   1623 		result = "mat3";
   1624 		break;
   1625 	case VARIABLE_TYPE_MAT3X2:
   1626 		result = "mat3x2";
   1627 		break;
   1628 	case VARIABLE_TYPE_MAT3X4:
   1629 		result = "mat3x4";
   1630 		break;
   1631 	case VARIABLE_TYPE_MAT4:
   1632 		result = "mat4";
   1633 		break;
   1634 	case VARIABLE_TYPE_MAT4X2:
   1635 		result = "mat4x2";
   1636 		break;
   1637 	case VARIABLE_TYPE_MAT4X3:
   1638 		result = "mat4x3";
   1639 		break;
   1640 	case VARIABLE_TYPE_UINT:
   1641 		result = "uint";
   1642 		break;
   1643 	case VARIABLE_TYPE_UVEC2:
   1644 		result = "uvec2";
   1645 		break;
   1646 	case VARIABLE_TYPE_UVEC3:
   1647 		result = "uvec3";
   1648 		break;
   1649 	case VARIABLE_TYPE_UVEC4:
   1650 		result = "uvec4";
   1651 		break;
   1652 	case VARIABLE_TYPE_VEC2:
   1653 		result = "vec2";
   1654 		break;
   1655 	case VARIABLE_TYPE_VEC3:
   1656 		result = "vec3";
   1657 		break;
   1658 	case VARIABLE_TYPE_VEC4:
   1659 		result = "vec4";
   1660 		break;
   1661 
   1662 	default:
   1663 	{
   1664 		TCU_FAIL("Unrecognized variable type");
   1665 	}
   1666 	} /* switch (variable_type) */
   1667 
   1668 	return result;
   1669 }
   1670 
   1671 /** Constructor.
   1672  *
   1673  *  @param context Rendering context.
   1674  *
   1675  **/
   1676 APITest1::APITest1(deqp::Context& context)
   1677 	: TestCase(context, "min_maxes", "Verifies the implementation returns valid GL_MAX_SUBROUTINE* pnames "
   1678 									 "which meet the minimum maximum requirements enforced by the spec.")
   1679 	, m_has_test_passed(true)
   1680 {
   1681 	/* Left blank intentionally */
   1682 }
   1683 
   1684 /** Executes test iteration.
   1685  *
   1686  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   1687  */
   1688 tcu::TestNode::IterateResult APITest1::iterate()
   1689 {
   1690 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1691 
   1692 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   1693 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   1694 	{
   1695 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   1696 	}
   1697 
   1698 	/* Iterate over all pnames */
   1699 	const struct
   1700 	{
   1701 		glw::GLenum pname;
   1702 		const char* pname_string;
   1703 		glw::GLint  min_value;
   1704 	} pnames[] = { { GL_MAX_SUBROUTINES, "GL_MAX_SUBROUTINES", 256 },
   1705 				   { GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS, "GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS", 1024 } };
   1706 	const unsigned int n_pnames = sizeof(pnames) / sizeof(pnames[0]);
   1707 
   1708 	for (unsigned int n_pname = 0; n_pname < n_pnames; ++n_pname)
   1709 	{
   1710 		glw::GLboolean	 bool_value   = GL_FALSE;
   1711 		glw::GLdouble	  double_value = 0.0;
   1712 		glw::GLfloat	   float_value  = 0.0f;
   1713 		glw::GLint		   int_value	= 0;
   1714 		glw::GLint64	   int64_value  = 0;
   1715 		const glw::GLint   min_value	= pnames[n_pname].min_value;
   1716 		const glw::GLenum& pname		= pnames[n_pname].pname;
   1717 		const char*		   pname_string = pnames[n_pname].pname_string;
   1718 
   1719 		/* Retrieve the pname values */
   1720 		gl.getBooleanv(pname, &bool_value);
   1721 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv() call failed.");
   1722 
   1723 		gl.getDoublev(pname, &double_value);
   1724 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetDoublev() call failed.");
   1725 
   1726 		gl.getFloatv(pname, &float_value);
   1727 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv() call failed.");
   1728 
   1729 		gl.getIntegerv(pname, &int_value);
   1730 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed.");
   1731 
   1732 		gl.getInteger64v(pname, &int64_value);
   1733 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInteger64v() call failed.");
   1734 
   1735 		/* Make sure the value reported meets the min max requirement */
   1736 		if (int_value < min_value)
   1737 		{
   1738 			m_testCtx.getLog() << tcu::TestLog::Message << "GL implementation reports a value of [" << int_value
   1739 							   << "]"
   1740 								  " for property ["
   1741 							   << pname_string << "]"
   1742 												  ", whereas the min max for the property is ["
   1743 							   << min_value << "]." << tcu::TestLog::EndMessage;
   1744 
   1745 			m_has_test_passed = false;
   1746 		}
   1747 
   1748 		/* Verify the other getters reported valid values */
   1749 		const float epsilon = 1e-5f;
   1750 
   1751 		if (((int_value == 0) && (bool_value == GL_TRUE)) || ((int_value != 0) && (bool_value != GL_TRUE)))
   1752 		{
   1753 			m_testCtx.getLog() << tcu::TestLog::Message << "Invalid boolean value [" << bool_value
   1754 							   << "]"
   1755 								  " reported for property ["
   1756 							   << pname_string << "]"
   1757 												  " (int value:["
   1758 							   << int_value << "])" << tcu::TestLog::EndMessage;
   1759 
   1760 			m_has_test_passed = false;
   1761 		}
   1762 
   1763 		if (de::abs(double_value - (double)int_value) > epsilon)
   1764 		{
   1765 			m_testCtx.getLog() << tcu::TestLog::Message << "Invalid double value [" << double_value
   1766 							   << "]"
   1767 								  " reported for property ["
   1768 							   << pname_string << "]"
   1769 												  " (int value:["
   1770 							   << int_value << "])" << tcu::TestLog::EndMessage;
   1771 
   1772 			m_has_test_passed = false;
   1773 		}
   1774 
   1775 		if (de::abs(float_value - (float)int_value) > epsilon)
   1776 		{
   1777 			m_testCtx.getLog() << tcu::TestLog::Message << "Invalid float value [" << float_value
   1778 							   << "]"
   1779 								  " reported for property ["
   1780 							   << pname_string << "]"
   1781 												  " (int value:["
   1782 							   << int_value << "])" << tcu::TestLog::EndMessage;
   1783 
   1784 			m_has_test_passed = false;
   1785 		}
   1786 
   1787 		if (int64_value != int_value)
   1788 		{
   1789 			m_testCtx.getLog() << tcu::TestLog::Message << "Invalid 64-bit integer value [" << float_value
   1790 							   << "]"
   1791 								  " reported for property ["
   1792 							   << pname_string << "]"
   1793 												  " (int value:["
   1794 							   << int_value << "])" << tcu::TestLog::EndMessage;
   1795 
   1796 			m_has_test_passed = false;
   1797 		}
   1798 	} /* for (all pnames) */
   1799 
   1800 	if (m_has_test_passed)
   1801 	{
   1802 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1803 	}
   1804 	else
   1805 	{
   1806 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1807 	}
   1808 
   1809 	return STOP;
   1810 }
   1811 
   1812 /** Constructor.
   1813  *
   1814  *  @param context Rendering context.
   1815  *
   1816  **/
   1817 APITest2::APITest2(deqp::Context& context)
   1818 	: TestCase(context, "name_getters", "Verifies glGetActiveSubroutineName() and glGetActiveSubroutineUniformName() "
   1819 										"functions work correctly.")
   1820 	, m_buffer(DE_NULL)
   1821 	, m_has_test_passed(true)
   1822 	, m_po_id(0)
   1823 	, m_subroutine_name1("subroutine1")
   1824 	, m_subroutine_name2("subroutine2")
   1825 	, m_subroutine_uniform_name("data_provider")
   1826 	, m_vs_id(0)
   1827 {
   1828 	/* Left blank intentionally */
   1829 }
   1830 
   1831 /** Destroys all ES objects that may have been created during test initialization,
   1832  *  as well as releases any buffers that may have been allocated during the process.
   1833  */
   1834 void APITest2::deinit()
   1835 {
   1836 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1837 
   1838 	if (m_buffer != DE_NULL)
   1839 	{
   1840 		delete[] m_buffer;
   1841 
   1842 		m_buffer = DE_NULL;
   1843 	}
   1844 
   1845 	if (m_po_id != 0)
   1846 	{
   1847 		gl.deleteProgram(m_po_id);
   1848 
   1849 		m_po_id = 0;
   1850 	}
   1851 
   1852 	if (m_vs_id != 0)
   1853 	{
   1854 		gl.deleteShader(m_vs_id);
   1855 
   1856 		m_vs_id = 0;
   1857 	}
   1858 }
   1859 
   1860 /** Returns body of a vertex shader that should be used for the test.
   1861  *
   1862  *  @return As per description.
   1863  **/
   1864 std::string APITest2::getVertexShaderBody()
   1865 {
   1866 	return "#version 400\n"
   1867 		   "\n"
   1868 		   "#extension GL_ARB_shader_subroutine : require\n"
   1869 		   "\n"
   1870 		   "subroutine int ExampleSubroutineType(int example_argument);\n"
   1871 		   "\n"
   1872 		   "subroutine(ExampleSubroutineType) int subroutine1(int example_argument)\n"
   1873 		   "{\n"
   1874 		   "    return 1;\n"
   1875 		   "}\n"
   1876 		   "\n"
   1877 		   "subroutine(ExampleSubroutineType) int subroutine2(int example_argument)\n"
   1878 		   "{\n"
   1879 		   "    return 2;\n"
   1880 		   "}\n"
   1881 		   "\n"
   1882 		   "subroutine uniform ExampleSubroutineType data_provider;\n"
   1883 		   "\n"
   1884 		   "void main()\n"
   1885 		   "{\n"
   1886 		   "    gl_Position = vec4(float(data_provider(0)), vec3(1) );\n"
   1887 		   "}\n";
   1888 }
   1889 
   1890 /** Initializes all ES objects required to run the test. */
   1891 void APITest2::initTest()
   1892 {
   1893 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1894 
   1895 	/* Generate program & shader objects */
   1896 	m_po_id = gl.createProgram();
   1897 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
   1898 
   1899 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() or glCreateShader() call(s) failed.");
   1900 
   1901 	/* Attach the shader to the program object */
   1902 	gl.attachShader(m_po_id, m_vs_id);
   1903 	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
   1904 
   1905 	/* Compile the shader */
   1906 	glw::GLint  compile_status  = GL_FALSE;
   1907 	std::string vs_body			= getVertexShaderBody();
   1908 	const char* vs_body_raw_ptr = vs_body.c_str();
   1909 
   1910 	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */);
   1911 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   1912 
   1913 	gl.compileShader(m_vs_id);
   1914 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
   1915 
   1916 	gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
   1917 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
   1918 
   1919 	if (compile_status != GL_TRUE)
   1920 	{
   1921 		TCU_FAIL("Shader compilation failed.");
   1922 	}
   1923 
   1924 	/* Try to link the program object */
   1925 	glw::GLint link_status = GL_FALSE;
   1926 
   1927 	gl.linkProgram(m_po_id);
   1928 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
   1929 
   1930 	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
   1931 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
   1932 
   1933 	if (link_status != GL_TRUE)
   1934 	{
   1935 		TCU_FAIL("Program linking failed.");
   1936 	}
   1937 
   1938 	/* Perform a few sanity checks */
   1939 	glw::GLint n_active_subroutines			= 0;
   1940 	glw::GLint n_active_subroutine_uniforms = 0;
   1941 
   1942 	gl.getProgramStageiv(m_po_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINES, &n_active_subroutines);
   1943 	gl.getProgramStageiv(m_po_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &n_active_subroutine_uniforms);
   1944 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramStageiv() call failed.");
   1945 
   1946 	if (n_active_subroutines != 2 /* subroutines declared in vertex shader */)
   1947 	{
   1948 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid amount of active subroutines reported; expected: 2,"
   1949 													   " reported:"
   1950 						   << n_active_subroutines << tcu::TestLog::EndMessage;
   1951 
   1952 		TCU_FAIL("Invalid GL_ACTIVE_SUBROUTINES property value.");
   1953 	}
   1954 
   1955 	if (n_active_subroutine_uniforms != 1)
   1956 	{
   1957 		m_testCtx.getLog() << tcu::TestLog::Message
   1958 						   << "Invalid amount of active subroutine uniforms reported: expected: 1,"
   1959 							  " reported: "
   1960 						   << n_active_subroutine_uniforms << tcu::TestLog::EndMessage;
   1961 
   1962 		TCU_FAIL("Invalid GL_ACTIVE_SUBROUTINE_UNIFORMS property value.");
   1963 	}
   1964 }
   1965 
   1966 /** Executes test iteration.
   1967  *
   1968  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   1969  */
   1970 tcu::TestNode::IterateResult APITest2::iterate()
   1971 {
   1972 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   1973 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   1974 	{
   1975 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   1976 	}
   1977 
   1978 	/* Initialize a test program object */
   1979 	initTest();
   1980 
   1981 	/* Verify glGetActiveSubroutineName() works correctly */
   1982 	verifyGLGetActiveSubroutineNameFunctionality();
   1983 
   1984 	/* Verify glGetActiveSubroutineUniformName() works correctly */
   1985 	verifyGLGetActiveSubroutineUniformNameFunctionality();
   1986 
   1987 	/* Done */
   1988 	if (m_has_test_passed)
   1989 	{
   1990 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1991 	}
   1992 	else
   1993 	{
   1994 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1995 	}
   1996 
   1997 	return STOP;
   1998 }
   1999 
   2000 /** Verifies glGetActiveSubroutineName() behaves as per GL_ARB_shader_subroutine
   2001  *  specification.
   2002  **/
   2003 void APITest2::verifyGLGetActiveSubroutineNameFunctionality()
   2004 {
   2005 	GLsizei				  expected_length1 = (GLsizei)strlen(m_subroutine_name1) + 1;
   2006 	GLsizei				  expected_length2 = (GLsizei)strlen(m_subroutine_name1) + 1;
   2007 	const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
   2008 	GLsizei				  reported_length  = 0;
   2009 
   2010 	gl.getActiveSubroutineName(m_po_id, GL_VERTEX_SHADER, 0, /* index */
   2011 							   0,							 /* bufsize */
   2012 							   DE_NULL,						 /* length */
   2013 							   DE_NULL);					 /* name */
   2014 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetActiveSubroutineName() call failed.");
   2015 
   2016 	gl.getProgramInterfaceiv(m_po_id, GL_VERTEX_SUBROUTINE, GL_MAX_NAME_LENGTH, &reported_length);
   2017 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetActiveSubroutineName() call failed.");
   2018 
   2019 	if ((reported_length != expected_length1) && (reported_length != expected_length2))
   2020 	{
   2021 		m_testCtx.getLog() << tcu::TestLog::Message
   2022 						   << "Invalid active subroutine name length reported:" << reported_length
   2023 						   << ", instead of: " << expected_length1 << " or " << expected_length2
   2024 						   << tcu::TestLog::EndMessage;
   2025 
   2026 		TCU_FAIL("Incorrect length of active subroutine name");
   2027 	}
   2028 
   2029 	m_buffer = new glw::GLchar[reported_length];
   2030 
   2031 	memset(m_buffer, 0, reported_length);
   2032 
   2033 	gl.getActiveSubroutineName(m_po_id, GL_VERTEX_SHADER, 0, reported_length, DE_NULL, /* length */
   2034 							   m_buffer);
   2035 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetActiveSubroutineName() call failed.");
   2036 
   2037 	if (strcmp(m_buffer, m_subroutine_name1) != 0 && strcmp(m_buffer, m_subroutine_name2) != 0)
   2038 	{
   2039 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid active subroutine name reported:[" << m_buffer
   2040 						   << "]"
   2041 							  " instead of:["
   2042 						   << m_subroutine_name1 << "]"
   2043 													" or:["
   2044 						   << m_subroutine_name2 << "]." << tcu::TestLog::EndMessage;
   2045 
   2046 		TCU_FAIL("Invalid active subroutine name reported.");
   2047 	}
   2048 
   2049 	delete[] m_buffer;
   2050 	m_buffer = DE_NULL;
   2051 }
   2052 
   2053 /** Verifies glGetActiveSubroutineUniformName() behaves as per GL_ARB_shader_subroutine
   2054  *  specification.
   2055  **/
   2056 void APITest2::verifyGLGetActiveSubroutineUniformNameFunctionality()
   2057 {
   2058 	GLsizei				  expected_length = (GLsizei)strlen(m_subroutine_uniform_name);
   2059 	const glw::Functions& gl			  = m_context.getRenderContext().getFunctions();
   2060 	GLsizei				  reported_length = 0;
   2061 
   2062 	gl.getActiveSubroutineUniformName(m_po_id, GL_VERTEX_SHADER, 0, /* index */
   2063 									  0,							/* bufsize */
   2064 									  DE_NULL,						/* length */
   2065 									  DE_NULL);						/* name */
   2066 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetActiveSubroutineUniformName() call failed.");
   2067 
   2068 	gl.getActiveSubroutineUniformName(m_po_id, GL_VERTEX_SHADER, 0, /* index */
   2069 									  0,							/* bufsize */
   2070 									  &reported_length, DE_NULL);   /* name */
   2071 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetActiveSubroutineUniformName() call failed.");
   2072 
   2073 	// reported_length is the actual number of characters written into <name>
   2074 	// If <bufSize> is 0, reported_length should be 0
   2075 	if (reported_length != 0)
   2076 	{
   2077 		m_testCtx.getLog() << tcu::TestLog::Message
   2078 						   << "Invalid active subroutine uniform name length reported:" << reported_length
   2079 						   << ", instead of: " << 0 << tcu::TestLog::EndMessage;
   2080 
   2081 		TCU_FAIL("Incorrect length of active subroutine uniform name");
   2082 	}
   2083 
   2084 	m_buffer = new glw::GLchar[expected_length + 1];
   2085 
   2086 	memset(m_buffer, 0, expected_length + 1);
   2087 
   2088 	gl.getActiveSubroutineUniformName(m_po_id, GL_VERTEX_SHADER, 0, expected_length + 1, &reported_length, m_buffer);
   2089 	GLU_EXPECT_NO_ERROR(gl.getError(), "getActiveSubroutineUniformName() call failed.");
   2090 
   2091 	if (reported_length != expected_length)
   2092 	{
   2093 		m_testCtx.getLog() << tcu::TestLog::Message
   2094 						   << "Invalid active subroutine uniform name length reported:" << reported_length
   2095 						   << ", instead of: " << expected_length << tcu::TestLog::EndMessage;
   2096 
   2097 		TCU_FAIL("Incorrect length of active subroutine uniform name");
   2098 	}
   2099 
   2100 	if (strcmp(m_buffer, m_subroutine_uniform_name) != 0)
   2101 	{
   2102 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid active subroutine uniform name reported:[" << m_buffer
   2103 						   << "]"
   2104 							  " instead of:["
   2105 						   << m_subroutine_uniform_name << "]" << tcu::TestLog::EndMessage;
   2106 
   2107 		TCU_FAIL("Invalid active subroutine uniform name reported.");
   2108 	}
   2109 
   2110 	delete[] m_buffer;
   2111 	m_buffer = DE_NULL;
   2112 }
   2113 
   2114 /** Constructor.
   2115  *
   2116  *  @param context Rendering context.
   2117  *
   2118  **/
   2119 FunctionalTest1_2::FunctionalTest1_2(deqp::Context& context)
   2120 	: TestCase(context, "two_subroutines_single_subroutine_uniform",
   2121 			   "Verifies the subroutines work correctly in a vertex shader for"
   2122 			   " bool/float/int/uint/double/*vec*/*mat* argument and return types")
   2123 	, m_has_test_passed(true)
   2124 	, m_po_id(0)
   2125 	, m_po_getter0_subroutine_index(GL_INVALID_INDEX)
   2126 	, m_po_getter1_subroutine_index(GL_INVALID_INDEX)
   2127 	, m_po_subroutine_uniform_index(-1)
   2128 	, m_xfb_bo_id(0)
   2129 	, m_vao_id(0)
   2130 	, m_vs_id(0)
   2131 {
   2132 	/* Left blank intentionally */
   2133 }
   2134 
   2135 /** Destroys all ES objects that may have been created during test initialization,
   2136  *  as well as releases any buffers that may have been allocated during the process.
   2137  */
   2138 void FunctionalTest1_2::deinit()
   2139 {
   2140 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2141 
   2142 	deinitTestIteration();
   2143 
   2144 	if (m_xfb_bo_id != 0)
   2145 	{
   2146 		gl.deleteBuffers(1, &m_xfb_bo_id);
   2147 
   2148 		m_xfb_bo_id = 0;
   2149 	}
   2150 
   2151 	if (m_vao_id != 0)
   2152 	{
   2153 		gl.deleteVertexArrays(1, &m_vao_id);
   2154 
   2155 		m_vao_id = 0;
   2156 	}
   2157 }
   2158 
   2159 /** Deinitializes GL objects that are iteration-specific */
   2160 void FunctionalTest1_2::deinitTestIteration()
   2161 {
   2162 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2163 
   2164 	if (m_po_id != 0)
   2165 	{
   2166 		gl.deleteProgram(m_po_id);
   2167 
   2168 		m_po_id = 0;
   2169 	}
   2170 
   2171 	if (m_vs_id != 0)
   2172 	{
   2173 		gl.deleteShader(m_vs_id);
   2174 
   2175 		m_vs_id = 0;
   2176 	}
   2177 }
   2178 
   2179 /** Executes a single test iteration using user-specified test case propertiesz.
   2180  *
   2181  *  @param test-case Test case descriptor.
   2182  *
   2183  *  @return true if the test iteration passed, false otherwise.
   2184  **/
   2185 bool FunctionalTest1_2::executeTestIteration(const _test_case& test_case)
   2186 {
   2187 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
   2188 	bool				  result = true;
   2189 
   2190 	/* Build the test program */
   2191 	std::string		   empty_body;
   2192 	std::string		   vs_body		  = getVertexShaderBody(test_case.variable_type, test_case.array_size);
   2193 	const glw::GLchar* xfb_varyings[] = { "result" };
   2194 	const unsigned int n_xfb_varyings = sizeof(xfb_varyings) / sizeof(xfb_varyings[0]);
   2195 
   2196 	if (!Utils::buildProgram(gl, vs_body, empty_body, empty_body, empty_body, empty_body, xfb_varyings, n_xfb_varyings,
   2197 							 &m_vs_id, NULL, /* out_tc_id */
   2198 							 NULL,			 /* out_te_id */
   2199 							 NULL,			 /* out_gs_id */
   2200 							 NULL, &m_po_id))
   2201 	{
   2202 		TCU_FAIL("Test program failed to build.");
   2203 	}
   2204 
   2205 	/* Retrieve subroutine locations */
   2206 	m_po_getter0_subroutine_index = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "getter0");
   2207 	m_po_getter1_subroutine_index = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "getter1");
   2208 
   2209 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() call(s) failed.");
   2210 
   2211 	if (m_po_getter0_subroutine_index == GL_INVALID_INDEX || m_po_getter1_subroutine_index == GL_INVALID_INDEX)
   2212 	{
   2213 		TCU_FAIL("At least one subroutine is considered inactive which is invalid.");
   2214 	}
   2215 
   2216 	/* Retrieve subroutine uniform location */
   2217 	m_po_subroutine_uniform_index = gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "colorGetterUniform");
   2218 
   2219 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() call failed.");
   2220 
   2221 	if (m_po_subroutine_uniform_index == -1)
   2222 	{
   2223 		TCU_FAIL("Subroutine uniform is considered inactive which is invalid.");
   2224 	}
   2225 
   2226 	/* Set up XFB BO storage */
   2227 	const Utils::_variable_type base_variable_type	= Utils::getBaseVariableType(test_case.variable_type);
   2228 	unsigned int				iteration_xfb_bo_size = Utils::getComponentSizeForVariableType(base_variable_type) *
   2229 										 Utils::getNumberOfComponentsForVariableType(test_case.variable_type);
   2230 	unsigned int total_xfb_bo_size = 0;
   2231 
   2232 	if (base_variable_type == Utils::VARIABLE_TYPE_BOOL)
   2233 	{
   2234 		/* Boolean varyings are not supported by OpenGL. Instead, we use ints to output
   2235 		 * boolean values. */
   2236 		iteration_xfb_bo_size = static_cast<unsigned int>(iteration_xfb_bo_size * sizeof(int));
   2237 	}
   2238 
   2239 	total_xfb_bo_size = iteration_xfb_bo_size * 2 /* subroutines we will be testing */;
   2240 
   2241 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, total_xfb_bo_size, DE_NULL /* data */, GL_STATIC_DRAW);
   2242 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
   2243 
   2244 	/* Activate test program object */
   2245 	gl.useProgram(m_po_id);
   2246 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   2247 
   2248 	/* Run two iterations. Each iteration should invoke different subroutine. */
   2249 	const glw::GLuint  subroutine_indices[] = { m_po_getter0_subroutine_index, m_po_getter1_subroutine_index };
   2250 	const unsigned int n_subroutine_indices = sizeof(subroutine_indices) / sizeof(subroutine_indices[0]);
   2251 
   2252 	for (unsigned int n_subroutine_index = 0; n_subroutine_index < n_subroutine_indices; ++n_subroutine_index)
   2253 	{
   2254 		/* Configure which subroutine should be used for the draw call */
   2255 		glw::GLuint current_subroutine_index = subroutine_indices[n_subroutine_index];
   2256 
   2257 		gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, 1 /* count */, &current_subroutine_index);
   2258 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() call failed.");
   2259 
   2260 		/* Update XFB binding so that we do not overwrite data XFBed in previous iterations */
   2261 		gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* index */
   2262 						   m_xfb_bo_id, iteration_xfb_bo_size * n_subroutine_index, iteration_xfb_bo_size);
   2263 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange() call failed.");
   2264 
   2265 		/* Draw a single point */
   2266 		gl.beginTransformFeedback(GL_POINTS);
   2267 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
   2268 		{
   2269 			gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   2270 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   2271 		}
   2272 		gl.endTransformFeedback();
   2273 		GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
   2274 	} /* for (all subroutine indices) */
   2275 
   2276 	/* Map the BO storage into process space */
   2277 	const void* xfb_data_ptr = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   2278 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
   2279 
   2280 	result &= verifyXFBData(xfb_data_ptr, test_case.variable_type);
   2281 
   2282 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   2283 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffeR() call failed.");
   2284 
   2285 	return result;
   2286 }
   2287 
   2288 /** Retrieves body of a vertex shader that should be used to verify
   2289  *  subroutine support, given user-specified test iteration properties.
   2290  *
   2291  *  @param variable_type GLSL type that should be used for argument and
   2292  *                       return type definition in a subroutine. This setting
   2293  *                       also affects type of the only output variable in the shader.
   2294  *  @param array_size    1 if non-arrayed arguments/return types should be tested;
   2295  *                       2 if arrayed arguments/return types should be tested.
   2296  *
   2297  *  @return Requested string.
   2298  **/
   2299 std::string FunctionalTest1_2::getVertexShaderBody(const Utils::_variable_type& variable_type, unsigned int array_size)
   2300 {
   2301 	Utils::_variable_type base_variable_type		 = Utils::getBaseVariableType(variable_type);
   2302 	unsigned int		  n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type);
   2303 	std::stringstream	 result_sstream;
   2304 	std::string			  variable_type_glsl = Utils::getVariableTypeGLSLString(variable_type);
   2305 	std::stringstream	 variable_type_glsl_array_sstream;
   2306 	std::stringstream	 variable_type_glsl_arrayed_sstream;
   2307 
   2308 	variable_type_glsl_arrayed_sstream << variable_type_glsl;
   2309 
   2310 	if (array_size > 1)
   2311 	{
   2312 		variable_type_glsl_array_sstream << "[" << array_size << "]";
   2313 		variable_type_glsl_arrayed_sstream << variable_type_glsl_array_sstream.str();
   2314 	}
   2315 
   2316 	/* Form pre-amble */
   2317 	result_sstream << "#version 400\n"
   2318 					  "\n"
   2319 					  "#extension GL_ARB_shader_subroutine : require\n";
   2320 
   2321 	if (variable_type == Utils::VARIABLE_TYPE_DOUBLE)
   2322 	{
   2323 		result_sstream << "#extension GL_ARB_gpu_shader_fp64 : require\n";
   2324 	}
   2325 
   2326 	/* Form subroutine type declaration */
   2327 	result_sstream << "\n"
   2328 					  "subroutine "
   2329 				   << variable_type_glsl_arrayed_sstream.str() << " colorGetter(in " << variable_type_glsl
   2330 				   << " in_value" << variable_type_glsl_array_sstream.str() << ");\n"
   2331 																			   "\n";
   2332 
   2333 	/* Declare getter functions */
   2334 	for (int n_getter = 0; n_getter < 2; ++n_getter)
   2335 	{
   2336 		result_sstream << "subroutine(colorGetter) " << variable_type_glsl_arrayed_sstream.str() << " getter"
   2337 					   << n_getter << "(in " << variable_type_glsl << " in_value"
   2338 					   << variable_type_glsl_array_sstream.str() << ")\n"
   2339 																	"{\n";
   2340 
   2341 		if (array_size > 1)
   2342 		{
   2343 			result_sstream << variable_type_glsl << " temp" << variable_type_glsl_array_sstream.str() << ";\n";
   2344 		}
   2345 
   2346 		if (base_variable_type == Utils::VARIABLE_TYPE_BOOL)
   2347 		{
   2348 			if (array_size > 1)
   2349 			{
   2350 				for (unsigned int array_index = 0; array_index < array_size; ++array_index)
   2351 				{
   2352 					result_sstream << "    temp[" << array_index << "]"
   2353 																	" = "
   2354 								   << ((n_getter == 0) ? ((variable_type_glsl == "bool") ? "!" : "not") : "")
   2355 								   << "(in_value[" << array_index << "]);\n";
   2356 				}
   2357 
   2358 				result_sstream << "    return temp;\n";
   2359 			}
   2360 			else
   2361 			{
   2362 				result_sstream << "    return "
   2363 							   << ((n_getter == 0) ? ((variable_type_glsl == "bool") ? "!" : "not") : "")
   2364 							   << "(in_value);\n";
   2365 			}
   2366 		} /* if (base_variable_type == Utils::VARIABLE_TYPE_BOOL) */
   2367 		else
   2368 		{
   2369 			if (array_size > 1)
   2370 			{
   2371 				for (unsigned int array_index = 0; array_index < array_size; ++array_index)
   2372 				{
   2373 					result_sstream << "    temp[" << array_index << "]"
   2374 																	" = in_value["
   2375 								   << array_index << "] + " << (n_getter + 1) << ";\n";
   2376 				}
   2377 
   2378 				result_sstream << "    return temp;\n";
   2379 			}
   2380 			else
   2381 			{
   2382 				result_sstream << "    return (in_value + " << (n_getter + 1) << ");\n";
   2383 			}
   2384 		}
   2385 
   2386 		result_sstream << "}\n";
   2387 	} /* for (both getter functions) */
   2388 
   2389 	/* Declare subroutine uniform */
   2390 	result_sstream << "subroutine uniform colorGetter colorGetterUniform;\n"
   2391 					  "\n";
   2392 
   2393 	/* Declare output variable */
   2394 	result_sstream << "out ";
   2395 
   2396 	if (base_variable_type == Utils::VARIABLE_TYPE_BOOL)
   2397 	{
   2398 		Utils::_variable_type result_as_int_variable_type =
   2399 			Utils::getVariableTypeFromProperties(Utils::VARIABLE_TYPE_INT, n_variable_type_components);
   2400 		std::string variable_type_glsl_as_int = Utils::getVariableTypeGLSLString(result_as_int_variable_type);
   2401 
   2402 		result_sstream << variable_type_glsl_as_int;
   2403 	}
   2404 	else
   2405 	{
   2406 		result_sstream << variable_type_glsl;
   2407 	}
   2408 
   2409 	result_sstream << " result;\n"
   2410 					  "\n";
   2411 
   2412 	/* Declare main(): prepare input argument for the subroutine function */
   2413 	result_sstream << "void main()\n"
   2414 					  "{\n"
   2415 					  "    "
   2416 				   << variable_type_glsl << " temp";
   2417 
   2418 	if (array_size > 1)
   2419 	{
   2420 		result_sstream << "[" << array_size << "]";
   2421 	};
   2422 
   2423 	result_sstream << ";\n";
   2424 
   2425 	for (unsigned int array_index = 0; array_index < array_size; ++array_index)
   2426 	{
   2427 		result_sstream << "    temp";
   2428 
   2429 		if (array_size > 1)
   2430 		{
   2431 			result_sstream << "[" << array_index << "]";
   2432 		}
   2433 
   2434 		result_sstream << " = " << variable_type_glsl << "(";
   2435 
   2436 		if (base_variable_type == Utils::VARIABLE_TYPE_BOOL)
   2437 		{
   2438 			result_sstream << "true";
   2439 		}
   2440 		else
   2441 		{
   2442 			for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
   2443 			{
   2444 				result_sstream << "3";
   2445 
   2446 				if (n_component != (n_variable_type_components - 1))
   2447 				{
   2448 					result_sstream << ", ";
   2449 				}
   2450 			} /* for (all components) */
   2451 		}
   2452 
   2453 		result_sstream << ");\n";
   2454 	} /* for (all array indices) */
   2455 
   2456 	/* Declare main(): call the subroutine. Verify the input and write the result
   2457 	 *                 to the output variable.
   2458 	 **/
   2459 	if (base_variable_type == Utils::VARIABLE_TYPE_BOOL)
   2460 	{
   2461 		Utils::_variable_type result_as_int_variable_type =
   2462 			Utils::getVariableTypeFromProperties(Utils::VARIABLE_TYPE_INT, n_variable_type_components);
   2463 		std::string variable_type_glsl_as_int = Utils::getVariableTypeGLSLString(result_as_int_variable_type);
   2464 
   2465 		result_sstream << variable_type_glsl_arrayed_sstream.str() << " subroutine_result = colorGetterUniform(temp);\n"
   2466 																	  "result = ";
   2467 
   2468 		for (unsigned int array_index = 0; array_index < array_size; ++array_index)
   2469 		{
   2470 			if (variable_type_glsl == "bool")
   2471 				result_sstream << "bool(subroutine_result";
   2472 			else
   2473 				result_sstream << "all(subroutine_result";
   2474 
   2475 			if (array_size > 1)
   2476 			{
   2477 				result_sstream << "[" << array_index << "]";
   2478 			}
   2479 
   2480 			result_sstream << ")";
   2481 
   2482 			if (array_index != (array_size - 1))
   2483 			{
   2484 				result_sstream << "&& ";
   2485 			}
   2486 		}
   2487 
   2488 		result_sstream << " == true ? " << variable_type_glsl_as_int << "(1) : " << variable_type_glsl_as_int << "(0);";
   2489 	}
   2490 	else
   2491 	{
   2492 		if (array_size > 1)
   2493 		{
   2494 			DE_ASSERT(array_size == 2);
   2495 
   2496 			result_sstream << variable_type_glsl << " subroutine_result" << variable_type_glsl_array_sstream.str()
   2497 						   << " = colorGetterUniform(temp);\n"
   2498 							  "\n"
   2499 							  "if (subroutine_result[0] == subroutine_result[1]) result = subroutine_result[0];\n"
   2500 							  "else\n"
   2501 							  "result = "
   2502 						   << variable_type_glsl << "(-1);\n";
   2503 		}
   2504 		else
   2505 		{
   2506 			result_sstream << "result = colorGetterUniform(temp);\n";
   2507 		}
   2508 	}
   2509 
   2510 	/* All done */
   2511 	result_sstream << "}\n";
   2512 
   2513 	return result_sstream.str();
   2514 }
   2515 
   2516 /** Initializes all GL objects required to run the test. */
   2517 void FunctionalTest1_2::initTest()
   2518 {
   2519 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2520 
   2521 	/* Generate buffer object to hold result XFB data */
   2522 	gl.genBuffers(1, &m_xfb_bo_id);
   2523 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
   2524 
   2525 	/* Set up XFB BO bindings */
   2526 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id);
   2527 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
   2528 
   2529 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id);
   2530 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
   2531 
   2532 	/* Generate VAO to use for the draw calls */
   2533 	gl.genVertexArrays(1, &m_vao_id);
   2534 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
   2535 
   2536 	gl.bindVertexArray(m_vao_id);
   2537 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
   2538 }
   2539 
   2540 /** Executes test iteration.
   2541  *
   2542  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   2543  */
   2544 tcu::TestNode::IterateResult FunctionalTest1_2::iterate()
   2545 {
   2546 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   2547 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   2548 	{
   2549 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   2550 	}
   2551 
   2552 	/* Initialize a test program object */
   2553 	initTest();
   2554 
   2555 	/* Construct test case descriptors: first, iIerate over all
   2556 	 * variable types we want to cover */
   2557 	const Utils::_variable_type variable_types[] = {
   2558 		Utils::VARIABLE_TYPE_BOOL,   Utils::VARIABLE_TYPE_BVEC2,  Utils::VARIABLE_TYPE_BVEC3,
   2559 		Utils::VARIABLE_TYPE_BVEC4,  Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_FLOAT,
   2560 		Utils::VARIABLE_TYPE_INT,	Utils::VARIABLE_TYPE_IVEC2,  Utils::VARIABLE_TYPE_IVEC3,
   2561 		Utils::VARIABLE_TYPE_IVEC4,  Utils::VARIABLE_TYPE_MAT2,   Utils::VARIABLE_TYPE_MAT2X3,
   2562 		Utils::VARIABLE_TYPE_MAT2X4, Utils::VARIABLE_TYPE_MAT3,   Utils::VARIABLE_TYPE_MAT3X2,
   2563 		Utils::VARIABLE_TYPE_MAT3X4, Utils::VARIABLE_TYPE_MAT4,   Utils::VARIABLE_TYPE_MAT4X2,
   2564 		Utils::VARIABLE_TYPE_MAT4X3, Utils::VARIABLE_TYPE_UINT,   Utils::VARIABLE_TYPE_UVEC2,
   2565 		Utils::VARIABLE_TYPE_UVEC3,  Utils::VARIABLE_TYPE_UVEC4,  Utils::VARIABLE_TYPE_VEC2,
   2566 		Utils::VARIABLE_TYPE_VEC3,   Utils::VARIABLE_TYPE_VEC4
   2567 	};
   2568 	const unsigned int n_variable_types = sizeof(variable_types) / sizeof(variable_types[0]);
   2569 
   2570 	for (unsigned int n_variable_type = 0; n_variable_type < n_variable_types; ++n_variable_type)
   2571 	{
   2572 		Utils::_variable_type current_variable_type = variable_types[n_variable_type];
   2573 
   2574 		/* We need to test both arrayed and non-arrayed arguments */
   2575 		for (unsigned int array_size = 1; array_size < 3; ++array_size)
   2576 		{
   2577 			/* Exclude double variables if the relevant extension is unavailable */
   2578 			if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64") &&
   2579 				current_variable_type == Utils::VARIABLE_TYPE_DOUBLE)
   2580 			{
   2581 				continue;
   2582 			}
   2583 
   2584 			/* Form the descriptor */
   2585 			_test_case test_case;
   2586 
   2587 			test_case.array_size	= array_size;
   2588 			test_case.variable_type = current_variable_type;
   2589 
   2590 			/* Store the test case descriptor */
   2591 			m_test_cases.push_back(test_case);
   2592 		} /* for (both arrayed and non-arrayed arguments) */
   2593 	}	 /* for (all variable types) */
   2594 
   2595 	/* Iterate over all test cases and execute the test */
   2596 	for (_test_cases_const_iterator test_case_iterator = m_test_cases.begin(); test_case_iterator != m_test_cases.end();
   2597 		 ++test_case_iterator)
   2598 	{
   2599 		const _test_case& test_case = *test_case_iterator;
   2600 
   2601 		m_has_test_passed &= executeTestIteration(test_case);
   2602 
   2603 		/* Release GL objects that were created during the execution */
   2604 		deinitTestIteration();
   2605 	} /* for (all test cases) */
   2606 
   2607 	/* Done */
   2608 	if (m_has_test_passed)
   2609 	{
   2610 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2611 	}
   2612 	else
   2613 	{
   2614 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2615 	}
   2616 
   2617 	return STOP;
   2618 }
   2619 
   2620 /** Verifies data that has been XFBed out by the vertex shader.
   2621  *
   2622  *  @param xfb_data      Buffer holding the data.
   2623  *  @param variable_type GLSL type used for the test iteration
   2624  *                       that generated the data at @param xfb_data.
   2625  *
   2626  *  @return true if the data was found to be valid, false if it
   2627  *               was detected to be incorrect.
   2628  **/
   2629 bool FunctionalTest1_2::verifyXFBData(const void* xfb_data, const Utils::_variable_type& variable_type)
   2630 {
   2631 	const Utils::_variable_type base_variable_type		   = Utils::getBaseVariableType(variable_type);
   2632 	const float					epsilon					   = 1e-5f;
   2633 	const unsigned int			n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type);
   2634 	bool						result					   = true;
   2635 	const unsigned char*		traveller_ptr			   = (const unsigned char*)xfb_data;
   2636 
   2637 	/* Boolean arguments/return types are tested with a slightly different shader so we
   2638 	 * need to test them in a separate code-path.
   2639 	 */
   2640 	if (base_variable_type == Utils::VARIABLE_TYPE_BOOL)
   2641 	{
   2642 		/* 0 should be returned when getter0 is used, 1 otherwise */
   2643 		const unsigned int ref_values[] = { 0, 1 };
   2644 		const unsigned int n_ref_values = sizeof(ref_values) / sizeof(ref_values[0]);
   2645 
   2646 		for (unsigned int n_ref_value = 0; n_ref_value < n_ref_values; ++n_ref_value)
   2647 		{
   2648 			const unsigned int ref_value = ref_values[n_ref_value];
   2649 
   2650 			for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
   2651 			{
   2652 				int* result_value_ptr = (int*)(traveller_ptr);
   2653 
   2654 				if (*result_value_ptr != (int)ref_value)
   2655 				{
   2656 					m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value reported by subroutine using "
   2657 																   "["
   2658 									   << Utils::getVariableTypeGLSLString(variable_type) << "]"
   2659 									   << " argument/return types ("
   2660 										  "expected:["
   2661 									   << ref_value << "], found:[" << *result_value_ptr << "])"
   2662 									   << tcu::TestLog::EndMessage;
   2663 
   2664 					result = false;
   2665 					break;
   2666 				}
   2667 
   2668 				traveller_ptr += sizeof(int);
   2669 			} /* for (all components) */
   2670 		}	 /* for (all reference values) */
   2671 	}		  /* if (base_variable_type == Utils::VARIABLE_TYPE_BOOL) */
   2672 	else
   2673 	{
   2674 		/* 4 should be returned when getter0 is used, 5 otherwise */
   2675 		const unsigned int ref_values[] = { 4, 5 };
   2676 		const unsigned int n_ref_values = sizeof(ref_values) / sizeof(ref_values[0]);
   2677 
   2678 		for (unsigned int n_ref_value = 0; n_ref_value < n_ref_values; ++n_ref_value)
   2679 		{
   2680 			const unsigned int ref_value = ref_values[n_ref_value];
   2681 
   2682 			DE_ASSERT(
   2683 				base_variable_type == Utils::VARIABLE_TYPE_DOUBLE || base_variable_type == Utils::VARIABLE_TYPE_FLOAT ||
   2684 				base_variable_type == Utils::VARIABLE_TYPE_INT || base_variable_type == Utils::VARIABLE_TYPE_UINT);
   2685 
   2686 			for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
   2687 			{
   2688 				const double* double_value_ptr = (double*)traveller_ptr;
   2689 				const float*  float_value_ptr  = (float*)traveller_ptr;
   2690 				const int*	int_value_ptr	= (int*)traveller_ptr;
   2691 
   2692 				switch (base_variable_type)
   2693 				{
   2694 				case Utils::VARIABLE_TYPE_DOUBLE:
   2695 				{
   2696 					if (de::abs(*double_value_ptr - (double)ref_value) > epsilon)
   2697 					{
   2698 						m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value reported by subroutine using "
   2699 																	   "["
   2700 										   << Utils::getVariableTypeGLSLString(variable_type) << "]"
   2701 										   << " argument/return types ("
   2702 											  "expected:["
   2703 										   << ref_value << "], found:[" << *double_value_ptr << "])"
   2704 										   << tcu::TestLog::EndMessage;
   2705 
   2706 						result = false;
   2707 					}
   2708 
   2709 					traveller_ptr += sizeof(double);
   2710 					break;
   2711 				}
   2712 
   2713 				case Utils::VARIABLE_TYPE_FLOAT:
   2714 				{
   2715 					if (de::abs(*float_value_ptr - (float)ref_value) > epsilon)
   2716 					{
   2717 						m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value reported by subroutine using "
   2718 																	   "["
   2719 										   << Utils::getVariableTypeGLSLString(variable_type) << "]"
   2720 										   << " argument/return types ("
   2721 											  "expected:["
   2722 										   << ref_value << "], found:[" << *float_value_ptr << "])"
   2723 										   << tcu::TestLog::EndMessage;
   2724 
   2725 						result = false;
   2726 					}
   2727 
   2728 					traveller_ptr += sizeof(float);
   2729 					break;
   2730 				}
   2731 
   2732 				case Utils::VARIABLE_TYPE_INT:
   2733 				case Utils::VARIABLE_TYPE_UINT:
   2734 				{
   2735 					if (*int_value_ptr != (int)ref_value)
   2736 					{
   2737 						m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value reported by subroutine using "
   2738 																	   "["
   2739 										   << Utils::getVariableTypeGLSLString(variable_type) << "]"
   2740 										   << " argument/return types ("
   2741 											  "expected:["
   2742 										   << ref_value << "], found:[" << *int_value_ptr << "])"
   2743 										   << tcu::TestLog::EndMessage;
   2744 
   2745 						result = false;
   2746 					}
   2747 
   2748 					traveller_ptr += sizeof(int);
   2749 					break;
   2750 				}
   2751 
   2752 				default:
   2753 					break;
   2754 				} /* switch (base_variable_type) */
   2755 			}	 /* for (all components) */
   2756 		}		  /* for (all reference values) */
   2757 	}
   2758 
   2759 	return result;
   2760 }
   2761 
   2762 /** Constructor
   2763  *
   2764  * @param context CTS context
   2765  **/
   2766 FunctionalTest3_4::FunctionalTest3_4(deqp::Context& context)
   2767 	: TestCase(context, "four_subroutines_with_two_uniforms", "Verify Get* API and draw calls")
   2768 	, m_n_active_subroutine_uniforms(0)
   2769 	, m_n_active_subroutine_uniform_locations(0)
   2770 	, m_n_active_subroutines(0)
   2771 	, m_n_active_subroutine_uniform_name_length(0)
   2772 	, m_n_active_subroutine_name_length(0)
   2773 	, m_n_active_subroutine_uniform_size(0)
   2774 {
   2775 	/* Nothing to be done here */
   2776 }
   2777 
   2778 /** Execute test
   2779  *
   2780  * @return tcu::TestNode::STOP
   2781  **/
   2782 tcu::TestNode::IterateResult FunctionalTest3_4::iterate()
   2783 {
   2784 	static const glw::GLchar* vertex_shader_code =
   2785 		"#version 400 core\n"
   2786 		"#extension GL_ARB_shader_subroutine : require\n"
   2787 		"\n"
   2788 		"precision highp float;\n"
   2789 		"\n"
   2790 		"// Sub routine type declaration\n"
   2791 		"subroutine vec4 routine_type(in vec4 iparam);\n"
   2792 		"\n"
   2793 		"// Sub routine definitions\n"
   2794 		"subroutine(routine_type) vec4 inverse_order(in vec4 iparam)\n"
   2795 		"{\n"
   2796 		"    return iparam.wzyx;\n"
   2797 		"}\n"
   2798 		"\n"
   2799 		"subroutine(routine_type) vec4 negate(in vec4 iparam)\n"
   2800 		"{\n"
   2801 		"    return -iparam;\n"
   2802 		"}\n"
   2803 		"\n"
   2804 		"subroutine(routine_type) vec4 inverse(in vec4 iparam)\n"
   2805 		"{\n"
   2806 		"    return 1 / iparam;\n"
   2807 		"}\n"
   2808 		"\n"
   2809 		"subroutine(routine_type) vec4 square(in vec4 iparam)\n"
   2810 		"{\n"
   2811 		"    return iparam * iparam;\n"
   2812 		"}\n"
   2813 		"\n"
   2814 		"// Sub routine uniforms\n"
   2815 		"subroutine uniform routine_type first_routine;\n"
   2816 		"subroutine uniform routine_type second_routine;\n"
   2817 		"\n"
   2818 		"// Input data\n"
   2819 		"uniform vec4 input_data;\n"
   2820 		"\n"
   2821 		"// Output\n"
   2822 		"out vec4 out_input_data;\n"
   2823 		"out vec4 out_result_from_first_routine;\n"
   2824 		"out vec4 out_result_from_second_routine;\n"
   2825 		"out vec4 out_result_from_combined_routines;\n"
   2826 		"out vec4 out_result_from_routines_combined_in_reveresed_order;\n"
   2827 		"\n"
   2828 		"void main()\n"
   2829 		"{\n"
   2830 		"    out_input_data                                       = input_data;\n"
   2831 		"    out_result_from_first_routine                        = first_routine(input_data);\n"
   2832 		"    out_result_from_second_routine                       = second_routine(input_data);\n"
   2833 		"    out_result_from_combined_routines                    = second_routine(first_routine(input_data));\n"
   2834 		"    out_result_from_routines_combined_in_reveresed_order = first_routine(second_routine(input_data));\n"
   2835 		"}\n"
   2836 		"\n";
   2837 
   2838 	static const GLchar* varying_names[] = {
   2839 		"out_input_data",
   2840 		"out_result_from_first_routine",
   2841 		"out_result_from_second_routine",
   2842 		"out_result_from_combined_routines",
   2843 		"out_result_from_routines_combined_in_reveresed_order",
   2844 	};
   2845 
   2846 	static const GLchar* subroutine_uniform_names[] = { "first_routine", "second_routine" };
   2847 
   2848 	static const GLchar* subroutine_names[] = { "inverse_order", "negate", "inverse", "square" };
   2849 
   2850 	static const GLuint n_varyings					   = sizeof(varying_names) / sizeof(varying_names[0]);
   2851 	static const GLuint transform_feedback_buffer_size = n_varyings * sizeof(GLfloat) * 4 /* vec4 */;
   2852 
   2853 	static const GLuint inverse_order_routine_index = 0;
   2854 	static const GLuint negate_routine_index		= 1;
   2855 	static const GLuint inverse_routine_index		= 2;
   2856 	static const GLuint square_routine_index		= 3;
   2857 
   2858 	/* Test data */
   2859 	static const Utils::vec4<GLfloat> inverse_order_negate_data[5] = {
   2860 		Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f), Utils::vec4<GLfloat>(2.0f, 1.0f, -1.0f, -2.0f),
   2861 		Utils::vec4<GLfloat>(2.0f, 1.0f, -1.0f, -2.0f), Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f),
   2862 		Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f),
   2863 	};
   2864 
   2865 	static const Utils::vec4<GLfloat> inverse_order_inverse_data[5] = {
   2866 		Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f), Utils::vec4<GLfloat>(2.0f, 1.0f, -1.0f, -2.0f),
   2867 		Utils::vec4<GLfloat>(-0.5f, -1.0f, 1.0f, 0.5f), Utils::vec4<GLfloat>(0.5f, 1.0f, -1.0f, -0.5f),
   2868 		Utils::vec4<GLfloat>(0.5f, 1.0f, -1.0f, -0.5f),
   2869 	};
   2870 
   2871 	static const Utils::vec4<GLfloat> inverse_order_square_data[5] = {
   2872 		Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f), Utils::vec4<GLfloat>(2.0f, 1.0f, -1.0f, -2.0f),
   2873 		Utils::vec4<GLfloat>(4.0f, 1.0f, 1.0f, 4.0f),   Utils::vec4<GLfloat>(4.0f, 1.0f, 1.0f, 4.0f),
   2874 		Utils::vec4<GLfloat>(4.0f, 1.0f, 1.0f, 4.0f),
   2875 	};
   2876 
   2877 	static const Utils::vec4<GLfloat> negate_inverse_data[5] = {
   2878 		Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f), Utils::vec4<GLfloat>(2.0f, 1.0f, -1.0f, -2.0f),
   2879 		Utils::vec4<GLfloat>(-0.5f, -1.0f, 1.0f, 0.5f), Utils::vec4<GLfloat>(0.5f, 1.0f, -1.0f, -0.5f),
   2880 		Utils::vec4<GLfloat>(0.5f, 1.0f, -1.0f, -0.5f),
   2881 	};
   2882 
   2883 	static const Utils::vec4<GLfloat> negate_square_data[5] = {
   2884 		Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f),   Utils::vec4<GLfloat>(2.0f, 1.0f, -1.0f, -2.0f),
   2885 		Utils::vec4<GLfloat>(4.0f, 1.0f, 1.0f, 4.0f),	 Utils::vec4<GLfloat>(4.0f, 1.0f, 1.0f, 4.0f),
   2886 		Utils::vec4<GLfloat>(-4.0f, -1.0f, -1.0f, -4.0f),
   2887 	};
   2888 
   2889 	static const Utils::vec4<GLfloat> inverse_square_data[5] = {
   2890 		Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f), Utils::vec4<GLfloat>(-0.5f, -1.0f, 1.0f, 0.5f),
   2891 		Utils::vec4<GLfloat>(4.0f, 1.0f, 1.0f, 4.0f),   Utils::vec4<GLfloat>(0.25f, 1.0f, 1.0f, 0.25f),
   2892 		Utils::vec4<GLfloat>(0.25f, 1.0f, 1.0f, 0.25f),
   2893 	};
   2894 
   2895 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   2896 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   2897 	{
   2898 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   2899 	}
   2900 
   2901 	m_n_active_subroutine_uniforms			  = 2;
   2902 	m_n_active_subroutine_uniform_locations   = 2;
   2903 	m_n_active_subroutines					  = 4;
   2904 	m_n_active_subroutine_uniform_name_length = 0;
   2905 	m_n_active_subroutine_name_length		  = 0;
   2906 	m_n_active_subroutine_uniform_size		  = 1;
   2907 
   2908 	/* GL objects */
   2909 	Utils::program	 program(m_context);
   2910 	Utils::buffer	  transform_feedback_buffer(m_context);
   2911 	Utils::vertexArray vao(m_context);
   2912 
   2913 	bool result = true;
   2914 
   2915 	/* Calculate max name lengths for subroutines and subroutine uniforms */
   2916 	for (GLint i = 0; i < m_n_active_subroutine_uniforms; ++i)
   2917 	{
   2918 		const GLsizei length = (GLsizei)strlen(subroutine_uniform_names[i]);
   2919 
   2920 		if (length > m_n_active_subroutine_uniform_name_length)
   2921 		{
   2922 			m_n_active_subroutine_uniform_name_length = length;
   2923 		}
   2924 	}
   2925 
   2926 	for (GLint i = 0; i < m_n_active_subroutines; ++i)
   2927 	{
   2928 		const GLsizei length = (GLsizei)strlen(subroutine_names[i]);
   2929 
   2930 		if (length > m_n_active_subroutine_name_length)
   2931 		{
   2932 			m_n_active_subroutine_name_length = length;
   2933 		}
   2934 	}
   2935 
   2936 	/* Init */
   2937 	program.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* test */, vertex_shader_code, varying_names,
   2938 				  n_varyings);
   2939 
   2940 	vao.generate();
   2941 	vao.bind();
   2942 
   2943 	transform_feedback_buffer.generate();
   2944 	transform_feedback_buffer.update(GL_TRANSFORM_FEEDBACK_BUFFER, transform_feedback_buffer_size, 0 /* data */,
   2945 									 GL_DYNAMIC_COPY);
   2946 	transform_feedback_buffer.bindRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, transform_feedback_buffer_size);
   2947 
   2948 	program.use();
   2949 
   2950 	/* Inspect Get* API */
   2951 	if ((false == inspectProgramStageiv(program.m_program_object_id)) ||
   2952 		(false == inspectActiveSubroutineUniformiv(program.m_program_object_id, subroutine_uniform_names)) ||
   2953 		(false == inspectActiveSubroutineUniformName(program.m_program_object_id, subroutine_uniform_names)) ||
   2954 		(false == inspectActiveSubroutineName(program.m_program_object_id, subroutine_names)) ||
   2955 		(false ==
   2956 		 inspectSubroutineBinding(program.m_program_object_id, subroutine_names, subroutine_uniform_names, false)))
   2957 	{
   2958 		result = false;
   2959 	}
   2960 
   2961 	/* Inspect GetProgram* API */
   2962 	if (true == m_context.getContextInfo().isExtensionSupported("GL_ARB_program_interface_query"))
   2963 	{
   2964 		if ((false == inspectProgramInterfaceiv(program.m_program_object_id)) ||
   2965 			(false ==
   2966 			 inspectProgramResourceiv(program.m_program_object_id, subroutine_names, subroutine_uniform_names)) ||
   2967 			(false ==
   2968 			 inspectSubroutineBinding(program.m_program_object_id, subroutine_names, subroutine_uniform_names, true)))
   2969 		{
   2970 			result = false;
   2971 		}
   2972 	}
   2973 
   2974 	/* Test shader execution */
   2975 	if ((false == testDraw(program.m_program_object_id, subroutine_names[inverse_order_routine_index],
   2976 						   subroutine_names[negate_routine_index], subroutine_uniform_names, inverse_order_negate_data,
   2977 						   false)) ||
   2978 		(false == testDraw(program.m_program_object_id, subroutine_names[inverse_order_routine_index],
   2979 						   subroutine_names[inverse_routine_index], subroutine_uniform_names,
   2980 						   inverse_order_inverse_data, false)) ||
   2981 		(false == testDraw(program.m_program_object_id, subroutine_names[inverse_order_routine_index],
   2982 						   subroutine_names[square_routine_index], subroutine_uniform_names, inverse_order_square_data,
   2983 						   false)) ||
   2984 		(false == testDraw(program.m_program_object_id, subroutine_names[negate_routine_index],
   2985 						   subroutine_names[inverse_routine_index], subroutine_uniform_names, negate_inverse_data,
   2986 						   false)) ||
   2987 		(false == testDraw(program.m_program_object_id, subroutine_names[negate_routine_index],
   2988 						   subroutine_names[square_routine_index], subroutine_uniform_names, negate_square_data,
   2989 						   false)) ||
   2990 		(false == testDraw(program.m_program_object_id, subroutine_names[inverse_routine_index],
   2991 						   subroutine_names[square_routine_index], subroutine_uniform_names, inverse_square_data,
   2992 						   false)))
   2993 	{
   2994 		result = false;
   2995 	}
   2996 
   2997 	if (true == m_context.getContextInfo().isExtensionSupported("GL_ARB_program_interface_query"))
   2998 	{
   2999 		if ((false == testDraw(program.m_program_object_id, subroutine_names[inverse_order_routine_index],
   3000 							   subroutine_names[negate_routine_index], subroutine_uniform_names,
   3001 							   inverse_order_negate_data, true)) ||
   3002 			(false == testDraw(program.m_program_object_id, subroutine_names[inverse_order_routine_index],
   3003 							   subroutine_names[inverse_routine_index], subroutine_uniform_names,
   3004 							   inverse_order_inverse_data, true)) ||
   3005 			(false == testDraw(program.m_program_object_id, subroutine_names[inverse_order_routine_index],
   3006 							   subroutine_names[square_routine_index], subroutine_uniform_names,
   3007 							   inverse_order_square_data, true)) ||
   3008 			(false == testDraw(program.m_program_object_id, subroutine_names[negate_routine_index],
   3009 							   subroutine_names[inverse_routine_index], subroutine_uniform_names, negate_inverse_data,
   3010 							   true)) ||
   3011 			(false == testDraw(program.m_program_object_id, subroutine_names[negate_routine_index],
   3012 							   subroutine_names[square_routine_index], subroutine_uniform_names, negate_square_data,
   3013 							   true)) ||
   3014 			(false == testDraw(program.m_program_object_id, subroutine_names[inverse_routine_index],
   3015 							   subroutine_names[square_routine_index], subroutine_uniform_names, inverse_square_data,
   3016 							   true)))
   3017 		{
   3018 			result = false;
   3019 		}
   3020 	}
   3021 
   3022 	/* Done */
   3023 	if (true == result)
   3024 	{
   3025 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   3026 	}
   3027 	else
   3028 	{
   3029 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   3030 	}
   3031 
   3032 	return tcu::TestNode::STOP;
   3033 }
   3034 
   3035 /** Verify result of getProgramStageiv
   3036  *
   3037  * @param program_id Program object id
   3038  * @param pname      <pname> parameter for getProgramStageiv
   3039  * @param expected   Expected value
   3040  *
   3041  * @return true if result is equal to expected value, flase otherwise
   3042  **/
   3043 bool FunctionalTest3_4::checkProgramStageiv(glw::GLuint program_id, glw::GLenum pname, glw::GLint expected) const
   3044 {
   3045 	const glw::Functions& gl	= m_context.getRenderContext().getFunctions();
   3046 	GLint				  value = 0;
   3047 
   3048 	gl.getProgramStageiv(program_id, GL_VERTEX_SHADER, pname, &value);
   3049 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramStageiv");
   3050 
   3051 	if (expected != value)
   3052 	{
   3053 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   3054 											<< "Error. Invalid result. Function: getProgramStageiv. "
   3055 											<< "pname: " << Utils::pnameToStr(pname) << ". "
   3056 											<< "Result: " << value << ". "
   3057 											<< "Expected: " << expected << "." << tcu::TestLog::EndMessage;
   3058 
   3059 		return false;
   3060 	}
   3061 	else
   3062 	{
   3063 		return true;
   3064 	}
   3065 }
   3066 
   3067 /** Verify result of getProgramResourceiv
   3068  *
   3069  * @param program_id        Program object id
   3070  * @param program_interface Program interface
   3071  * @param pname             <pname> parameter for getProgramStageiv
   3072  * @param resource_name     Resource name
   3073  * @param expected          Expected value
   3074  *
   3075  * @return true if result is equal to expected value, false otherwise
   3076  **/
   3077 bool FunctionalTest3_4::checkProgramResourceiv(GLuint program_id, GLenum program_interface, GLenum pname,
   3078 											   const glw::GLchar* resource_name, GLint expected) const
   3079 {
   3080 	const glw::Functions& gl	= m_context.getRenderContext().getFunctions();
   3081 	GLuint				  index = gl.getProgramResourceIndex(program_id, program_interface, resource_name);
   3082 	GLint				  value = 0;
   3083 
   3084 	if (GL_INVALID_INDEX == index)
   3085 	{
   3086 		return false;
   3087 	}
   3088 
   3089 	gl.getProgramResourceiv(program_id, program_interface, index, 1, &pname, 1, 0, &value);
   3090 	GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramResourceiv");
   3091 
   3092 	if (expected != value)
   3093 	{
   3094 		m_context.getTestContext().getLog()
   3095 			<< tcu::TestLog::Message << "Error. Invalid result. Function: getProgramResourceiv. "
   3096 			<< "Program interface: " << Utils::programInterfaceToStr(program_interface) << ". "
   3097 			<< "Resource name: " << resource_name << ". "
   3098 			<< "Property: " << Utils::pnameToStr(pname) << ". "
   3099 			<< "Result: " << value << ". "
   3100 			<< "Expected: " << expected << "." << tcu::TestLog::EndMessage;
   3101 
   3102 		return false;
   3103 	}
   3104 	else
   3105 	{
   3106 		return true;
   3107 	}
   3108 }
   3109 
   3110 /** Verify result of getProgramInterfaceiv
   3111  *
   3112  * @param program_id        Program object id
   3113  * @param program_interface Program interface
   3114  * @param pname             <pname> parameter for getProgramStageiv
   3115  * @param expected          Expected value
   3116  *
   3117  * @return true if result is equal to expected value, flase otherwise
   3118  **/
   3119 bool FunctionalTest3_4::checkProgramInterfaceiv(GLuint program_id, GLenum program_interface, GLenum pname,
   3120 												GLint expected) const
   3121 {
   3122 	const glw::Functions& gl	= m_context.getRenderContext().getFunctions();
   3123 	GLint				  value = 0;
   3124 
   3125 	gl.getProgramInterfaceiv(program_id, program_interface, pname, &value);
   3126 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInterfaceiv");
   3127 
   3128 	if (expected != value)
   3129 	{
   3130 		m_context.getTestContext().getLog()
   3131 			<< tcu::TestLog::Message << "Error. Invalid result. Function: getProgramInterfaceiv. "
   3132 			<< "Program interface: " << Utils::programInterfaceToStr(program_interface) << ". "
   3133 			<< "pname: " << Utils::pnameToStr(pname) << ". "
   3134 			<< "Result: " << value << ". "
   3135 			<< "Expected: " << expected << "." << tcu::TestLog::EndMessage;
   3136 
   3137 		return false;
   3138 	}
   3139 	else
   3140 	{
   3141 		return true;
   3142 	}
   3143 }
   3144 
   3145 /** Verify result of getActiveSubroutineUniformiv
   3146  *
   3147  * @param program_id Program object id
   3148  * @param index      <index> parameter for getActiveSubroutineUniformiv
   3149  * @param pname      <pname> parameter for getActiveSubroutineUniformiv
   3150  * @param expected   Expected value
   3151  *
   3152  * @return true if result is equal to expected value, flase otherwise
   3153  **/
   3154 bool FunctionalTest3_4::checkActiveSubroutineUniformiv(GLuint program_id, GLuint index, GLenum pname,
   3155 													   GLint expected) const
   3156 {
   3157 	const glw::Functions& gl	= m_context.getRenderContext().getFunctions();
   3158 	GLint				  value = 0;
   3159 
   3160 	gl.getActiveSubroutineUniformiv(program_id, GL_VERTEX_SHADER, index, pname, &value);
   3161 	GLU_EXPECT_NO_ERROR(gl.getError(), "getActiveSubroutineUniformiv");
   3162 
   3163 	if (expected != value)
   3164 	{
   3165 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   3166 											<< "Error. Invalid result. Function: getActiveSubroutineUniformiv. "
   3167 											<< "idnex: " << index << ". "
   3168 											<< "pname: " << Utils::pnameToStr(pname) << ". "
   3169 											<< "Result: " << value << ". "
   3170 											<< "Expected: " << expected << "." << tcu::TestLog::EndMessage;
   3171 
   3172 		return false;
   3173 	}
   3174 	else
   3175 	{
   3176 		return true;
   3177 	}
   3178 }
   3179 
   3180 /** Returns index of program resource
   3181  *
   3182  * @param program_id        Program object id
   3183  * @param program_interface Program interface
   3184  * @param resource_name     Name of resource
   3185  *
   3186  * @return Index of specified resource
   3187  **/
   3188 GLuint FunctionalTest3_4::getProgramResourceIndex(GLuint program_id, GLenum program_interface,
   3189 												  const glw::GLchar* resource_name) const
   3190 {
   3191 	const glw::Functions& gl	= m_context.getRenderContext().getFunctions();
   3192 	GLuint				  index = gl.getProgramResourceIndex(program_id, program_interface, resource_name);
   3193 
   3194 	GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramResourceIndex");
   3195 
   3196 	if (GL_INVALID_INDEX == index)
   3197 	{
   3198 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Program resource is not available. "
   3199 											<< "Program interface: " << Utils::programInterfaceToStr(program_interface)
   3200 											<< ". "
   3201 											<< "Resource name: " << resource_name << "." << tcu::TestLog::EndMessage;
   3202 	}
   3203 
   3204 	return index;
   3205 }
   3206 
   3207 /** Get subroutine index
   3208  *
   3209  * @param program_id        Program object id
   3210  * @param subroutine_name   Subroutine name
   3211  * @param use_program_query If true getProgramResourceIndex is used, otherwise getSubroutineIndex
   3212  *
   3213  * @return Index of subroutine
   3214  **/
   3215 GLuint FunctionalTest3_4::getSubroutineIndex(GLuint program_id, const glw::GLchar* subroutine_name,
   3216 											 bool use_program_query) const
   3217 {
   3218 	const glw::Functions& gl	= m_context.getRenderContext().getFunctions();
   3219 	GLuint				  index = -1;
   3220 
   3221 	if (false == use_program_query)
   3222 	{
   3223 		index = gl.getSubroutineIndex(program_id, GL_VERTEX_SHADER, subroutine_name);
   3224 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetSubroutineIndex");
   3225 	}
   3226 	else
   3227 	{
   3228 		index = gl.getProgramResourceIndex(program_id, GL_VERTEX_SUBROUTINE, subroutine_name);
   3229 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex");
   3230 	}
   3231 
   3232 	if (GL_INVALID_INDEX == index)
   3233 	{
   3234 		TCU_FAIL("Subroutine is not available");
   3235 	}
   3236 
   3237 	return index;
   3238 }
   3239 
   3240 /** Get subroutine uniform location
   3241  *
   3242  * @param program_id        Program object id
   3243  * @param uniform_name      Subroutine uniform name
   3244  * @param use_program_query If true getProgramResourceLocation is used, otherwise getSubroutineUniformLocation
   3245  *
   3246  * @return Location of subroutine uniform
   3247  **/
   3248 GLint FunctionalTest3_4::getSubroutineUniformLocation(GLuint program_id, const glw::GLchar* uniform_name,
   3249 													  bool use_program_query) const
   3250 {
   3251 	const glw::Functions& gl	   = m_context.getRenderContext().getFunctions();
   3252 	GLint				  location = -1;
   3253 
   3254 	if (false == use_program_query)
   3255 	{
   3256 		location = gl.getSubroutineUniformLocation(program_id, GL_VERTEX_SHADER, uniform_name);
   3257 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetSubroutineUniformLocation");
   3258 	}
   3259 	else
   3260 	{
   3261 		location = gl.getProgramResourceLocation(program_id, GL_VERTEX_SUBROUTINE_UNIFORM, uniform_name);
   3262 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceLocation");
   3263 	}
   3264 
   3265 	if (-1 == location)
   3266 	{
   3267 		TCU_FAIL("Subroutine uniform is not available");
   3268 	}
   3269 
   3270 	return location;
   3271 }
   3272 
   3273 /** Test if getProgramStageiv results are as expected
   3274  *
   3275  * @param program_id Program object id
   3276  *
   3277  * @result false in case of invalid result for any pname, true otherwise
   3278  **/
   3279 bool FunctionalTest3_4::inspectProgramStageiv(glw::GLuint program_id) const
   3280 {
   3281 	bool result = true;
   3282 
   3283 	const inspectionDetails details[] = {
   3284 		{ GL_ACTIVE_SUBROUTINE_UNIFORMS, m_n_active_subroutine_uniforms },
   3285 		{ GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, m_n_active_subroutine_uniform_locations },
   3286 		{ GL_ACTIVE_SUBROUTINES, m_n_active_subroutines },
   3287 		{ GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH, m_n_active_subroutine_uniform_name_length + 1 },
   3288 		{ GL_ACTIVE_SUBROUTINE_MAX_LENGTH, m_n_active_subroutine_name_length + 1 }
   3289 	};
   3290 	const GLuint n_details = sizeof(details) / sizeof(details[0]);
   3291 
   3292 	for (GLuint i = 0; i < n_details; ++i)
   3293 	{
   3294 		if (false == checkProgramStageiv(program_id, details[i].pname, details[i].expected_value))
   3295 		{
   3296 			result = false;
   3297 		}
   3298 	}
   3299 
   3300 	return result;
   3301 }
   3302 
   3303 /** Test if checkProgramInterfaceiv results are as expected
   3304  *
   3305  * @param program_id Program object id
   3306  *
   3307  * @result false in case of invalid result for any pname, true otherwise
   3308  **/
   3309 bool FunctionalTest3_4::inspectProgramInterfaceiv(glw::GLuint program_id) const
   3310 {
   3311 	bool result = true;
   3312 
   3313 	const inspectionDetailsForProgramInterface details[] = {
   3314 		{ GL_VERTEX_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, m_n_active_subroutine_uniforms },
   3315 		{ GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, m_n_active_subroutine_uniform_name_length + 1 },
   3316 		{ GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, m_n_active_subroutines },
   3317 		{ GL_VERTEX_SUBROUTINE, GL_ACTIVE_RESOURCES, m_n_active_subroutines },
   3318 		{ GL_VERTEX_SUBROUTINE, GL_MAX_NAME_LENGTH, m_n_active_subroutine_name_length + 1 }
   3319 	};
   3320 	const GLuint n_details = sizeof(details) / sizeof(details[0]);
   3321 
   3322 	for (GLuint i = 0; i < n_details; ++i)
   3323 	{
   3324 		if (false == checkProgramInterfaceiv(program_id, details[i].program_interface, details[i].pname,
   3325 											 details[i].expected_value))
   3326 		{
   3327 			result = false;
   3328 		}
   3329 	}
   3330 
   3331 	return result;
   3332 }
   3333 
   3334 /** Test if checkProgramResourceiv results are as expected
   3335  *
   3336  * @param program_id       Program object id
   3337  * @param subroutine_names Array of subroutine names
   3338  * @param uniform_names    Array of uniform names
   3339  *
   3340  * @result false in case of invalid result for any pname, true otherwise
   3341  **/
   3342 bool FunctionalTest3_4::inspectProgramResourceiv(GLuint program_id, const GLchar** subroutine_names,
   3343 												 const GLchar** uniform_names) const
   3344 {
   3345 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
   3346 	bool				  result = true;
   3347 
   3348 	for (GLint subroutine = 0; subroutine < m_n_active_subroutines; ++subroutine)
   3349 	{
   3350 		const GLchar* subroutine_name = subroutine_names[subroutine];
   3351 		const GLint   length		  = (GLint)strlen(subroutine_name) + 1;
   3352 
   3353 		if (false == checkProgramResourceiv(program_id, GL_VERTEX_SUBROUTINE, GL_NAME_LENGTH, subroutine_name, length))
   3354 		{
   3355 			result = false;
   3356 		}
   3357 	}
   3358 
   3359 	inspectionDetails details[] = {
   3360 		{ GL_NAME_LENGTH, 0 },
   3361 		{ GL_ARRAY_SIZE, 1 },
   3362 		{ GL_NUM_COMPATIBLE_SUBROUTINES, m_n_active_subroutines },
   3363 		{ GL_LOCATION, 0 },
   3364 	};
   3365 	const GLuint n_details = sizeof(details) / sizeof(details[0]);
   3366 
   3367 	for (GLint uniform = 0; uniform < m_n_active_subroutine_uniforms; ++uniform)
   3368 	{
   3369 		const GLchar* uniform_name = uniform_names[uniform];
   3370 		const GLint   length	   = (GLint)strlen(uniform_name) + 1;
   3371 		const GLint   location	 = getSubroutineUniformLocation(program_id, uniform_name, true);
   3372 
   3373 		details[0].expected_value = length;
   3374 		details[3].expected_value = location;
   3375 
   3376 		for (GLuint i = 0; i < n_details; ++i)
   3377 		{
   3378 			if (false == checkProgramResourceiv(program_id, GL_VERTEX_SUBROUTINE_UNIFORM, details[i].pname,
   3379 												uniform_name, details[i].expected_value))
   3380 			{
   3381 				result = false;
   3382 			}
   3383 		}
   3384 
   3385 		/* Check compatible subroutines */
   3386 		GLuint index = getProgramResourceIndex(program_id, GL_VERTEX_SUBROUTINE_UNIFORM, uniform_name);
   3387 
   3388 		if (GL_INVALID_INDEX != index)
   3389 		{
   3390 			std::vector<GLint> compatible_subroutines;
   3391 			GLint			   index_sum = 0;
   3392 			GLenum			   prop		 = GL_COMPATIBLE_SUBROUTINES;
   3393 
   3394 			compatible_subroutines.resize(m_n_active_subroutines);
   3395 
   3396 			gl.getProgramResourceiv(program_id, GL_VERTEX_SUBROUTINE_UNIFORM, index, 1, &prop, m_n_active_subroutines,
   3397 									0, &compatible_subroutines[0]);
   3398 
   3399 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv");
   3400 
   3401 			/* Expected indices are 0, 1, 2, ... N */
   3402 			for (GLint i = 0; i < m_n_active_subroutines; ++i)
   3403 			{
   3404 				index_sum += compatible_subroutines[i];
   3405 			}
   3406 
   3407 			/* Sum of E1, ..., EN = (E1 + EN) * N / 2 */
   3408 			if (((m_n_active_subroutines - 1) * m_n_active_subroutines) / 2 != index_sum)
   3409 			{
   3410 				tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   3411 
   3412 				message << "Error. Invalid result. Function: getProgramResourceiv. "
   3413 						<< "Program interface: GL_VERTEX_SUBROUTINE_UNIFORM. "
   3414 						<< "Resource name: " << uniform_name << ". "
   3415 						<< "Property: GL_COMPATIBLE_SUBROUTINES. "
   3416 						<< "Results: ";
   3417 
   3418 				for (GLint i = 1; i < m_n_active_subroutines; ++i)
   3419 				{
   3420 					message << compatible_subroutines[i];
   3421 				}
   3422 
   3423 				message << tcu::TestLog::EndMessage;
   3424 
   3425 				result = false;
   3426 			}
   3427 		}
   3428 	}
   3429 
   3430 	return result;
   3431 }
   3432 
   3433 /** Test if getActiveSubroutineUniformiv results are as expected
   3434  *
   3435  * @param program_id    Program object id
   3436  * @param uniform_names Array of subroutine uniform names available in program
   3437  *
   3438  * @result false in case of invalid result for any pname, true otherwise
   3439  **/
   3440 bool FunctionalTest3_4::inspectActiveSubroutineUniformiv(GLuint program_id, const GLchar** uniform_names) const
   3441 {
   3442 	const glw::Functions& gl						   = m_context.getRenderContext().getFunctions();
   3443 	bool				  result					   = true;
   3444 	GLint				  n_active_subroutine_uniforms = 0;
   3445 
   3446 	inspectionDetails details[] = {
   3447 		{ GL_NUM_COMPATIBLE_SUBROUTINES, m_n_active_subroutines },
   3448 		{ GL_UNIFORM_SIZE, m_n_active_subroutine_uniform_size },
   3449 		{ GL_UNIFORM_NAME_LENGTH, 0 },
   3450 	};
   3451 	const GLuint n_details = sizeof(details) / sizeof(details[0]);
   3452 
   3453 	/* Get amount of active subroutine uniforms */
   3454 	gl.getProgramStageiv(program_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &n_active_subroutine_uniforms);
   3455 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramStageiv");
   3456 
   3457 	for (GLint uniform = 0; uniform < n_active_subroutine_uniforms; ++uniform)
   3458 	{
   3459 		GLint name_length = (GLint)strlen(uniform_names[uniform]);
   3460 
   3461 		details[2].expected_value = name_length + 1;
   3462 
   3463 		/* Checks from "details" */
   3464 		for (GLuint i = 0; i < n_details; ++i)
   3465 		{
   3466 			if (false ==
   3467 				checkActiveSubroutineUniformiv(program_id, uniform, details[i].pname, details[i].expected_value))
   3468 			{
   3469 				result = false;
   3470 			}
   3471 		}
   3472 
   3473 		/* Check compatible subroutines */
   3474 		std::vector<GLint> compatible_subroutines;
   3475 		compatible_subroutines.resize(m_n_active_subroutines);
   3476 		GLint index_sum = 0;
   3477 
   3478 		gl.getActiveSubroutineUniformiv(program_id, GL_VERTEX_SHADER, uniform, GL_COMPATIBLE_SUBROUTINES,
   3479 										&compatible_subroutines[0]);
   3480 		GLU_EXPECT_NO_ERROR(gl.getError(), "getActiveSubroutineUniformiv");
   3481 
   3482 		/* Expected indices are 0, 1, 2, ... N */
   3483 		for (GLint i = 0; i < m_n_active_subroutines; ++i)
   3484 		{
   3485 			index_sum += compatible_subroutines[i];
   3486 		}
   3487 
   3488 		/* Sum of E1, ..., EN = (E1 + EN) * N / 2 */
   3489 		if (((m_n_active_subroutines - 1) * m_n_active_subroutines) / 2 != index_sum)
   3490 		{
   3491 			tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   3492 
   3493 			message << "Error. Invalid result. Function: getActiveSubroutineUniformiv. idnex: " << uniform
   3494 					<< ". pname: " << Utils::pnameToStr(GL_COMPATIBLE_SUBROUTINES) << ". Results: ";
   3495 
   3496 			for (GLint i = 1; i < m_n_active_subroutines; ++i)
   3497 			{
   3498 				message << compatible_subroutines[i];
   3499 			}
   3500 
   3501 			message << tcu::TestLog::EndMessage;
   3502 
   3503 			result = false;
   3504 		}
   3505 	}
   3506 
   3507 	return result;
   3508 }
   3509 
   3510 /** Test if getActiveSubroutineUniformName results are as expected
   3511  *
   3512  * @param program_id    Program object id
   3513  * @param uniform_names Array of subroutine uniform names available in program
   3514  *
   3515  * @result false in case of invalid result, true otherwise
   3516  **/
   3517 bool FunctionalTest3_4::inspectActiveSubroutineUniformName(GLuint program_id, const GLchar** uniform_names) const
   3518 {
   3519 	const glw::Functions& gl						   = m_context.getRenderContext().getFunctions();
   3520 	bool				  result					   = true;
   3521 	GLint				  n_active_subroutine_uniforms = 0;
   3522 	std::vector<GLchar>   active_uniform_name;
   3523 
   3524 	gl.getProgramStageiv(program_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &n_active_subroutine_uniforms);
   3525 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramStageiv");
   3526 
   3527 	active_uniform_name.resize(m_n_active_subroutine_uniform_name_length + 1);
   3528 
   3529 	for (GLint uniform = 0; uniform < n_active_subroutine_uniforms; ++uniform)
   3530 	{
   3531 		bool is_name_ok = false;
   3532 
   3533 		gl.getActiveSubroutineUniformName(program_id, GL_VERTEX_SHADER, uniform, (GLsizei)active_uniform_name.size(),
   3534 										  0 /* length */, &active_uniform_name[0]);
   3535 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveSubroutineUniformName");
   3536 
   3537 		for (GLint name = 0; name < n_active_subroutine_uniforms; ++name)
   3538 		{
   3539 			if (0 == strcmp(uniform_names[name], &active_uniform_name[0]))
   3540 			{
   3541 				is_name_ok = true;
   3542 				break;
   3543 			}
   3544 		}
   3545 
   3546 		if (false == is_name_ok)
   3547 		{
   3548 			m_context.getTestContext().getLog()
   3549 				<< tcu::TestLog::Message
   3550 				<< "Error. Invalid result. Function: getActiveSubroutineUniformName. idnex: " << uniform
   3551 				<< ". Result: " << &active_uniform_name[0] << tcu::TestLog::EndMessage;
   3552 
   3553 			result = false;
   3554 			break;
   3555 		}
   3556 	}
   3557 
   3558 	return result;
   3559 }
   3560 
   3561 /** Test if getActiveSubroutineUniformName results are as expected
   3562  *
   3563  * @param program_id       Program object id
   3564  * @param subroutine_names Array of subroutine names available in program
   3565  *
   3566  * @result false in case of invalid result, true otherwise
   3567  **/
   3568 bool FunctionalTest3_4::inspectActiveSubroutineName(GLuint program_id, const GLchar** subroutine_names) const
   3569 {
   3570 	const glw::Functions& gl				   = m_context.getRenderContext().getFunctions();
   3571 	bool				  result			   = true;
   3572 	GLint				  n_active_subroutines = 0;
   3573 	std::vector<GLchar>   active_subroutine_name;
   3574 
   3575 	gl.getProgramStageiv(program_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINES, &n_active_subroutines);
   3576 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramStageiv");
   3577 
   3578 	active_subroutine_name.resize(m_n_active_subroutine_name_length + 1);
   3579 
   3580 	for (GLint uniform = 0; uniform < n_active_subroutines; ++uniform)
   3581 	{
   3582 		bool is_name_ok = false;
   3583 
   3584 		gl.getActiveSubroutineName(program_id, GL_VERTEX_SHADER, uniform, (GLsizei)active_subroutine_name.size(),
   3585 								   0 /* length */, &active_subroutine_name[0]);
   3586 		GLU_EXPECT_NO_ERROR(gl.getError(), "getActiveSubroutineName");
   3587 
   3588 		for (GLint name = 0; name < n_active_subroutines; ++name)
   3589 		{
   3590 			if (0 == strcmp(subroutine_names[name], &active_subroutine_name[0]))
   3591 			{
   3592 				is_name_ok = true;
   3593 				break;
   3594 			}
   3595 		}
   3596 
   3597 		if (false == is_name_ok)
   3598 		{
   3599 			m_context.getTestContext().getLog()
   3600 				<< tcu::TestLog::Message
   3601 				<< "Error. Invalid result. Function: getActiveSubroutineName. idnex: " << uniform
   3602 				<< ". Result: " << &active_subroutine_name[0] << tcu::TestLog::EndMessage;
   3603 
   3604 			result = false;
   3605 			break;
   3606 		}
   3607 	}
   3608 
   3609 	return result;
   3610 }
   3611 
   3612 /** Test if it is possible to "bind" all subroutines uniforms with all subroutines
   3613  *
   3614  * @param program_id       Program object id
   3615  * @param subroutine_names Array of subroutine names available in program
   3616  * @param uniform_names    Array of subroutine uniform names available in program
   3617  *
   3618  * @result false in case of invalid result, true otherwise
   3619  **/
   3620 bool FunctionalTest3_4::inspectSubroutineBinding(GLuint program_id, const GLchar** subroutine_names,
   3621 												 const GLchar** uniform_names, bool use_program_query) const
   3622 {
   3623 	const glw::Functions& gl						   = m_context.getRenderContext().getFunctions();
   3624 	bool				  result					   = true;
   3625 	GLint				  n_active_subroutines		   = 0;
   3626 	GLint				  n_active_subroutine_uniforms = 0;
   3627 	std::vector<GLuint>   subroutine_uniforms;
   3628 	GLuint				  queried_subroutine_index = 0;
   3629 
   3630 	gl.getProgramStageiv(program_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINES, &n_active_subroutines);
   3631 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramStageiv");
   3632 
   3633 	gl.getProgramStageiv(program_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &n_active_subroutine_uniforms);
   3634 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramStageiv");
   3635 
   3636 	subroutine_uniforms.resize(n_active_subroutine_uniforms);
   3637 
   3638 	for (GLint uniform = 0; uniform < n_active_subroutine_uniforms; ++uniform)
   3639 	{
   3640 		GLuint uniform_location = getSubroutineUniformLocation(program_id, uniform_names[uniform], use_program_query);
   3641 
   3642 		for (GLint routine = 0; routine < n_active_subroutines; ++routine)
   3643 		{
   3644 			GLuint routine_index = getSubroutineIndex(program_id, subroutine_names[routine], use_program_query);
   3645 
   3646 			subroutine_uniforms[uniform] = routine_index;
   3647 
   3648 			gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, n_active_subroutine_uniforms, &subroutine_uniforms[0]);
   3649 			GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   3650 
   3651 			gl.getUniformSubroutineuiv(GL_VERTEX_SHADER, uniform_location, &queried_subroutine_index);
   3652 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformSubroutineuiv");
   3653 
   3654 			if (queried_subroutine_index != routine_index)
   3655 			{
   3656 				m_context.getTestContext().getLog()
   3657 					<< tcu::TestLog::Message << "Error. Invalid result. Function: gl.getUniformSubroutineuiv."
   3658 					<< " Subroutine uniform: " << uniform << ", name: " << uniform_names[uniform]
   3659 					<< ", location: " << uniform_location << ". Subroutine: " << routine
   3660 					<< ", name: " << subroutine_names[routine] << ", index: " << routine_index
   3661 					<< ". Result: " << queried_subroutine_index << tcu::TestLog::EndMessage;
   3662 
   3663 				result = false;
   3664 			}
   3665 		}
   3666 	}
   3667 
   3668 	return result;
   3669 }
   3670 
   3671 /** Execute draw call and verify results
   3672  *
   3673  * @param program_id                   Program object id
   3674  * @param first_routine_name           Name of subroutine that shall be used aas first_routine
   3675  * @param second_routine_name          Name of subroutine that shall be used aas second_routine
   3676  * @param uniform_names                Name of uniforms
   3677  * @param expected_results             Test data. [0] is used as input data. All are used as expected_results
   3678  * @param use_program_query            If true GetProgram* API will be used
   3679  *
   3680  * @return false in case of invalid result, true otherwise
   3681  **/
   3682 bool FunctionalTest3_4::testDraw(GLuint program_id, const GLchar* first_routine_name, const GLchar* second_routine_name,
   3683 								 const GLchar** uniform_names, const Utils::vec4<GLfloat> expected_results[5],
   3684 								 bool use_program_query) const
   3685 {
   3686 	static const GLuint   n_varyings			 = 5;
   3687 	const glw::Functions& gl					 = m_context.getRenderContext().getFunctions();
   3688 	bool				  result				 = true;
   3689 	GLuint				  subroutine_uniforms[2] = { 0 };
   3690 
   3691 	/* Get subroutine uniform locations */
   3692 	GLint first_routine_location = getSubroutineUniformLocation(program_id, uniform_names[0], use_program_query);
   3693 
   3694 	GLint second_routine_location = getSubroutineUniformLocation(program_id, uniform_names[1], use_program_query);
   3695 
   3696 	/* Get subroutine indices */
   3697 	GLuint first_routine_index = getSubroutineIndex(program_id, first_routine_name, use_program_query);
   3698 
   3699 	GLuint second_routine_index = getSubroutineIndex(program_id, second_routine_name, use_program_query);
   3700 
   3701 	/* Map uniforms with subroutines */
   3702 	subroutine_uniforms[first_routine_location]  = first_routine_index;
   3703 	subroutine_uniforms[second_routine_location] = second_routine_index;
   3704 
   3705 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, 2 /* number of uniforms */, &subroutine_uniforms[0]);
   3706 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   3707 
   3708 	/* Get location of input_data */
   3709 	GLint input_data_location = gl.getUniformLocation(program_id, "input_data");
   3710 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
   3711 
   3712 	if (-1 == input_data_location)
   3713 	{
   3714 		TCU_FAIL("Uniform is not available");
   3715 	}
   3716 
   3717 	/* Set up input_data */
   3718 	gl.uniform4f(input_data_location, expected_results[0].m_x, expected_results[0].m_y, expected_results[0].m_z,
   3719 				 expected_results[0].m_w);
   3720 	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f");
   3721 
   3722 	/* Execute draw call with transform feedback */
   3723 	gl.beginTransformFeedback(GL_POINTS);
   3724 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
   3725 
   3726 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   3727 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
   3728 
   3729 	gl.endTransformFeedback();
   3730 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
   3731 
   3732 	/* Verify results */
   3733 	GLfloat* feedback_data = (GLfloat*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   3734 	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
   3735 
   3736 	Utils::vec4<GLfloat> results[5];
   3737 
   3738 	results[0].m_x = feedback_data[0];
   3739 	results[0].m_y = feedback_data[1];
   3740 	results[0].m_z = feedback_data[2];
   3741 	results[0].m_w = feedback_data[3];
   3742 
   3743 	results[1].m_x = feedback_data[4];
   3744 	results[1].m_y = feedback_data[5];
   3745 	results[1].m_z = feedback_data[6];
   3746 	results[1].m_w = feedback_data[7];
   3747 
   3748 	results[2].m_x = feedback_data[8];
   3749 	results[2].m_y = feedback_data[9];
   3750 	results[2].m_z = feedback_data[10];
   3751 	results[2].m_w = feedback_data[11];
   3752 
   3753 	results[3].m_x = feedback_data[12];
   3754 	results[3].m_y = feedback_data[13];
   3755 	results[3].m_z = feedback_data[14];
   3756 	results[3].m_w = feedback_data[15];
   3757 
   3758 	results[4].m_x = feedback_data[16];
   3759 	results[4].m_y = feedback_data[17];
   3760 	results[4].m_z = feedback_data[18];
   3761 	results[4].m_w = feedback_data[19];
   3762 
   3763 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   3764 	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
   3765 
   3766 	for (GLuint i = 0; i < n_varyings; ++i)
   3767 	{
   3768 		result = result && (results[i] == expected_results[i]);
   3769 	}
   3770 
   3771 	if (false == result)
   3772 	{
   3773 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   3774 											<< "Error. Invalid result. First routine: " << first_routine_name
   3775 											<< ". Second routine: " << second_routine_name << tcu::TestLog::EndMessage;
   3776 
   3777 		tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   3778 
   3779 		message << "Results:";
   3780 
   3781 		for (GLuint i = 0; i < n_varyings; ++i)
   3782 		{
   3783 			results[i].log(message);
   3784 		}
   3785 
   3786 		message << tcu::TestLog::EndMessage;
   3787 
   3788 		message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   3789 
   3790 		message << "Expected:";
   3791 
   3792 		for (GLuint i = 0; i < n_varyings; ++i)
   3793 		{
   3794 			expected_results[i].log(message);
   3795 		}
   3796 
   3797 		message << tcu::TestLog::EndMessage;
   3798 	}
   3799 
   3800 	return result;
   3801 }
   3802 
   3803 /** Constructor
   3804  *
   3805  * @param context CTS context
   3806  **/
   3807 FunctionalTest5::FunctionalTest5(deqp::Context& context)
   3808 	: TestCase(context, "eight_subroutines_four_uniforms", "Verify multiple subroutine sets")
   3809 {
   3810 }
   3811 
   3812 /** Execute test
   3813  *
   3814  * @return tcu::TestNode::STOP
   3815  **/
   3816 tcu::TestNode::IterateResult FunctionalTest5::iterate()
   3817 {
   3818 	static const GLchar* vertex_shader_code =
   3819 		"#version 400 core\n"
   3820 		"#extension GL_ARB_shader_subroutine : require\n"
   3821 		"\n"
   3822 		"precision highp float;\n"
   3823 		"\n"
   3824 		"// Subroutine types\n"
   3825 		"subroutine vec4  routine_type_1(in vec4 left, in vec4 right);\n"
   3826 		"subroutine vec4  routine_type_2(in vec4 iparam);\n"
   3827 		"subroutine vec4  routine_type_3(in vec4 a,    in vec4 b,    in vec4 c);\n"
   3828 		"subroutine bvec4 routine_type_4(in vec4 left, in vec4 right);\n"
   3829 		"\n"
   3830 		"// Subroutine definitions\n"
   3831 		"// 1st type\n"
   3832 		"subroutine(routine_type_1) vec4 add(in vec4 left, in vec4 right)\n"
   3833 		"{\n"
   3834 		"    return left + right;\n"
   3835 		"}\n"
   3836 		"\n"
   3837 		"subroutine(routine_type_1) vec4 subtract(in vec4 left, in vec4 right)\n"
   3838 		"{\n"
   3839 		"    return left - right;\n"
   3840 		"}\n"
   3841 		"\n"
   3842 		"// 2nd type\n"
   3843 		"subroutine(routine_type_2) vec4 square(in vec4 iparam)\n"
   3844 		"{\n"
   3845 		"    return iparam * iparam;\n"
   3846 		"}\n"
   3847 		"\n"
   3848 		"subroutine(routine_type_2) vec4 square_root(in vec4 iparam)\n"
   3849 		"{\n"
   3850 		"    return sqrt(iparam);\n"
   3851 		"}\n"
   3852 		"\n"
   3853 		"// 3rd type\n"
   3854 		"subroutine(routine_type_3) vec4 do_fma(in vec4 a, in vec4 b, in vec4 c)\n"
   3855 		"{\n"
   3856 		"    return fma(a, b, c);\n"
   3857 		"}\n"
   3858 		"\n"
   3859 		"subroutine(routine_type_3) vec4 blend(in vec4 a, in vec4 b, in vec4 c)\n"
   3860 		"{\n"
   3861 		"    return c * a + (vec4(1) - c) * b;\n"
   3862 		"}\n"
   3863 		"\n"
   3864 		"// 4th type\n"
   3865 		"subroutine(routine_type_4) bvec4 are_equal(in vec4 left, in vec4 right)\n"
   3866 		"{\n"
   3867 		"    return equal(left, right);\n"
   3868 		"}\n"
   3869 		"\n"
   3870 		"subroutine(routine_type_4) bvec4 are_greater(in vec4 left, in vec4 right)\n"
   3871 		"{\n"
   3872 		"    return greaterThan(left, right);\n"
   3873 		"}\n"
   3874 		"\n"
   3875 		"// Sub routine uniforms\n"
   3876 		"subroutine uniform routine_type_1 first_routine;\n"
   3877 		"subroutine uniform routine_type_2 second_routine;\n"
   3878 		"subroutine uniform routine_type_3 third_routine;\n"
   3879 		"subroutine uniform routine_type_4 fourth_routine;\n"
   3880 		"\n"
   3881 		"// Input data\n"
   3882 		"uniform vec4 first_input;\n"
   3883 		"uniform vec4 second_input;\n"
   3884 		"uniform vec4 third_input;\n"
   3885 		"\n"
   3886 		"// Output\n"
   3887 		"out  vec4 out_result_from_first_routine;\n"
   3888 		"out  vec4 out_result_from_second_routine;\n"
   3889 		"out  vec4 out_result_from_third_routine;\n"
   3890 		"out uvec4 out_result_from_fourth_routine;\n"
   3891 		"\n"
   3892 		"void main()\n"
   3893 		"{\n"
   3894 		"    out_result_from_first_routine  =       first_routine (first_input, second_input);\n"
   3895 		"    out_result_from_second_routine =       second_routine(first_input);\n"
   3896 		"    out_result_from_third_routine  =       third_routine (first_input, second_input, third_input);\n"
   3897 		"    out_result_from_fourth_routine = uvec4(fourth_routine(first_input, second_input));\n"
   3898 		"}\n"
   3899 		"\n";
   3900 
   3901 	static const GLchar* subroutine_names[4][2] = {
   3902 		{ "add", "subtract" }, { "square", "square_root" }, { "do_fma", "blend" }, { "are_equal", "are_greater" }
   3903 	};
   3904 
   3905 	static const GLchar* subroutine_uniform_names[4][1] = {
   3906 		{ "first_routine" }, { "second_routine" }, { "third_routine" }, { "fourth_routine" }
   3907 	};
   3908 
   3909 	static const GLuint n_subroutine_types	 = sizeof(subroutine_names) / sizeof(subroutine_names[0]);
   3910 	static const GLuint n_subroutines_per_type = sizeof(subroutine_names[0]) / sizeof(subroutine_names[0][0]);
   3911 	static const GLuint n_subroutine_uniforms_per_type =
   3912 		sizeof(subroutine_uniform_names[0]) / sizeof(subroutine_uniform_names[0][0]);
   3913 
   3914 	static const GLchar* uniform_names[] = { "first_input", "second_input", "third_input" };
   3915 	static const GLuint  n_uniform_names = sizeof(uniform_names) / sizeof(uniform_names[0]);
   3916 
   3917 	static const GLchar* varying_names[] = { "out_result_from_first_routine", "out_result_from_second_routine",
   3918 											 "out_result_from_third_routine", "out_result_from_fourth_routine" };
   3919 	static const GLuint n_varyings					   = sizeof(varying_names) / sizeof(varying_names[0]);
   3920 	static const GLuint transform_feedback_buffer_size = n_varyings * sizeof(GLfloat) * 4 /* vec4 */;
   3921 
   3922 	/* Test data */
   3923 	static const Utils::vec4<GLfloat> input_data[3] = { Utils::vec4<GLfloat>(1.0f, 4.0f, 9.0f, 16.0f),
   3924 														Utils::vec4<GLfloat>(16.0f, 9.0f, 4.0f, 1.0f),
   3925 														Utils::vec4<GLfloat>(0.25f, 0.5f, 0.75f, 1.0f) };
   3926 
   3927 	static const Utils::vec4<GLfloat> expected_result_from_first_routine[2] = {
   3928 		Utils::vec4<GLfloat>(17.0f, 13.0f, 13.0f, 17.0f), Utils::vec4<GLfloat>(-15.0f, -5.0f, 5.0f, 15.0f)
   3929 	};
   3930 
   3931 	static const Utils::vec4<GLfloat> expected_result_from_second_routine[2] = {
   3932 		Utils::vec4<GLfloat>(1.0f, 16.0f, 81.0f, 256.0f), Utils::vec4<GLfloat>(1.0f, 2.0f, 3.0f, 4.0f)
   3933 	};
   3934 
   3935 	static const Utils::vec4<GLfloat> expected_result_from_third_routine[2] = {
   3936 		Utils::vec4<GLfloat>(16.25f, 36.5f, 36.75f, 17.0f), Utils::vec4<GLfloat>(12.25f, 6.5f, 7.75f, 16.0f)
   3937 	};
   3938 
   3939 	static const Utils::vec4<GLuint> expected_result_from_fourth_routine[2] = { Utils::vec4<GLuint>(0, 0, 0, 0),
   3940 																				Utils::vec4<GLuint>(0, 0, 1, 1) };
   3941 
   3942 	/* All combinations of subroutines */
   3943 	static const GLuint subroutine_combinations[][4] = {
   3944 		{ 0, 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 1, 0 }, { 0, 0, 1, 1 }, { 0, 1, 0, 0 }, { 0, 1, 0, 1 },
   3945 		{ 0, 1, 1, 0 }, { 0, 1, 1, 1 }, { 1, 0, 0, 0 }, { 1, 0, 0, 1 }, { 1, 0, 1, 0 }, { 1, 0, 1, 1 },
   3946 		{ 1, 1, 0, 0 }, { 1, 1, 0, 1 }, { 1, 1, 1, 0 }, { 1, 1, 1, 1 }
   3947 	};
   3948 	static const GLuint n_subroutine_combinations =
   3949 		sizeof(subroutine_combinations) / sizeof(subroutine_combinations[0]);
   3950 
   3951 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   3952 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   3953 	{
   3954 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   3955 	}
   3956 
   3957 	/* Result */
   3958 	bool result = true;
   3959 
   3960 	/* GL objects */
   3961 	Utils::program	 program(m_context);
   3962 	Utils::buffer	  transform_feedback_buffer(m_context);
   3963 	Utils::vertexArray vao(m_context);
   3964 
   3965 	/* Init GL objects */
   3966 	program.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* test */, vertex_shader_code, varying_names,
   3967 				  n_varyings);
   3968 
   3969 	program.use();
   3970 
   3971 	vao.generate();
   3972 	vao.bind();
   3973 
   3974 	transform_feedback_buffer.generate();
   3975 	transform_feedback_buffer.update(GL_TRANSFORM_FEEDBACK_BUFFER, transform_feedback_buffer_size, 0 /* data */,
   3976 									 GL_DYNAMIC_COPY);
   3977 	transform_feedback_buffer.bindRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, transform_feedback_buffer_size);
   3978 
   3979 	/* Get subroutine uniform locations and subroutine indices */
   3980 	for (GLuint type = 0; type < n_subroutine_types; ++type)
   3981 	{
   3982 		for (GLuint uniform = 0; uniform < n_subroutine_uniforms_per_type; ++uniform)
   3983 		{
   3984 			m_subroutine_uniform_locations[type][uniform] =
   3985 				program.getSubroutineUniformLocation(subroutine_uniform_names[type][uniform], GL_VERTEX_SHADER);
   3986 		}
   3987 
   3988 		for (GLuint routine = 0; routine < n_subroutines_per_type; ++routine)
   3989 		{
   3990 			m_subroutine_indices[type][routine] =
   3991 				program.getSubroutineIndex(subroutine_names[type][routine], GL_VERTEX_SHADER);
   3992 		}
   3993 	}
   3994 
   3995 	/* Get uniform locations */
   3996 	for (GLuint i = 0; i < n_uniform_names; ++i)
   3997 	{
   3998 		m_uniform_locations[i] = program.getUniformLocation(uniform_names[i]);
   3999 	}
   4000 
   4001 	/* Draw with each routine combination */
   4002 	for (GLuint i = 0; i < n_subroutine_combinations; ++i)
   4003 	{
   4004 		Utils::vec4<GLfloat> first_routine_result;
   4005 		Utils::vec4<GLfloat> second_routine_result;
   4006 		Utils::vec4<GLfloat> third_routine_result;
   4007 		Utils::vec4<GLuint>  fourth_routine_result;
   4008 
   4009 		testDraw(subroutine_combinations[i], input_data, first_routine_result, second_routine_result,
   4010 				 third_routine_result, fourth_routine_result);
   4011 
   4012 		if (false == verify(first_routine_result, second_routine_result, third_routine_result, fourth_routine_result,
   4013 							expected_result_from_first_routine[subroutine_combinations[i][0]],
   4014 							expected_result_from_second_routine[subroutine_combinations[i][1]],
   4015 							expected_result_from_third_routine[subroutine_combinations[i][2]],
   4016 							expected_result_from_fourth_routine[subroutine_combinations[i][3]]))
   4017 		{
   4018 			logError(subroutine_names, subroutine_combinations[i], input_data, first_routine_result,
   4019 					 second_routine_result, third_routine_result, fourth_routine_result,
   4020 					 expected_result_from_first_routine[subroutine_combinations[i][0]],
   4021 					 expected_result_from_second_routine[subroutine_combinations[i][1]],
   4022 					 expected_result_from_third_routine[subroutine_combinations[i][2]],
   4023 					 expected_result_from_fourth_routine[subroutine_combinations[i][3]]);
   4024 
   4025 			result = false;
   4026 		}
   4027 	}
   4028 
   4029 	/* Done */
   4030 	if (true == result)
   4031 	{
   4032 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4033 	}
   4034 	else
   4035 	{
   4036 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4037 	}
   4038 
   4039 	return tcu::TestNode::STOP;
   4040 }
   4041 
   4042 /** Log error message
   4043  *
   4044  * @param subroutine_names               Array of subroutine names
   4045  * @param subroutine_combination         Combination of subroutines
   4046  * @param input_data                     Input data
   4047  * @param first_routine_result           Result of first routine
   4048  * @param second_routine_result          Result of second routine
   4049  * @param third_routine_result           Result of third routine
   4050  * @param fourth_routine_result          Result of fourth routine
   4051  * @param first_routine_expected_result  Expected result of first routine
   4052  * @param second_routine_expected_result Expected result of second routine
   4053  * @param third_routine_expected_result  Expected result of third routine
   4054  * @param fourth_routine_expected_result Expected result of fourth routine
   4055  **/
   4056 void FunctionalTest5::logError(const glw::GLchar* subroutine_names[4][2], const glw::GLuint subroutine_combination[4],
   4057 							   const Utils::vec4<glw::GLfloat>  input_data[3],
   4058 							   const Utils::vec4<glw::GLfloat>& first_routine_result,
   4059 							   const Utils::vec4<glw::GLfloat>& second_routine_result,
   4060 							   const Utils::vec4<glw::GLfloat>& third_routine_result,
   4061 							   const Utils::vec4<glw::GLuint>&  fourth_routine_result,
   4062 							   const Utils::vec4<glw::GLfloat>& first_routine_expected_result,
   4063 							   const Utils::vec4<glw::GLfloat>& second_routine_expected_result,
   4064 							   const Utils::vec4<glw::GLfloat>& third_routine_expected_result,
   4065 							   const Utils::vec4<glw::GLuint>&  fourth_routine_expected_result) const
   4066 {
   4067 	m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result."
   4068 										<< tcu::TestLog::EndMessage;
   4069 
   4070 	tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   4071 
   4072 	message << "Function: " << subroutine_names[0][subroutine_combination[0]] << "( ";
   4073 	input_data[0].log(message);
   4074 	message << ", ";
   4075 	input_data[1].log(message);
   4076 	message << " ). Result: ";
   4077 	first_routine_result.log(message);
   4078 	message << ". Expected: ";
   4079 	first_routine_expected_result.log(message);
   4080 
   4081 	message << tcu::TestLog::EndMessage;
   4082 
   4083 	message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   4084 
   4085 	message << "Function: " << subroutine_names[1][subroutine_combination[1]] << "( ";
   4086 	input_data[0].log(message);
   4087 	message << " ). Result: ";
   4088 	second_routine_result.log(message);
   4089 	message << ". Expected: ";
   4090 	second_routine_expected_result.log(message);
   4091 
   4092 	message << tcu::TestLog::EndMessage;
   4093 
   4094 	message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   4095 
   4096 	message << "Function: " << subroutine_names[2][subroutine_combination[2]] << "( ";
   4097 	input_data[0].log(message);
   4098 	message << ", ";
   4099 	input_data[1].log(message);
   4100 	message << ", ";
   4101 	input_data[2].log(message);
   4102 	message << "). Result: ";
   4103 	third_routine_result.log(message);
   4104 	message << ". Expected: ";
   4105 	third_routine_expected_result.log(message);
   4106 
   4107 	message << tcu::TestLog::EndMessage;
   4108 
   4109 	message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   4110 
   4111 	message << "Function: " << subroutine_names[3][subroutine_combination[3]] << "( ";
   4112 	input_data[0].log(message);
   4113 	message << ", ";
   4114 	input_data[1].log(message);
   4115 	message << ", ";
   4116 	message << " ). Result: ";
   4117 	fourth_routine_result.log(message);
   4118 	message << ". Expected: ";
   4119 	fourth_routine_expected_result.log(message);
   4120 
   4121 	message << tcu::TestLog::EndMessage;
   4122 }
   4123 
   4124 /** Execute draw call and capture results
   4125  *
   4126  * @param subroutine_combination    Combination of subroutines
   4127  * @param input_data                Input data
   4128  * @param out_first_routine_result  Result of first routine
   4129  * @param out_second_routine_result Result of second routine
   4130  * @param out_third_routine_result  Result of third routine
   4131  * @param out_fourth_routine_result Result of fourth routine
   4132  **/
   4133 void FunctionalTest5::testDraw(const glw::GLuint			   subroutine_combination[4],
   4134 							   const Utils::vec4<glw::GLfloat> input_data[3],
   4135 							   Utils::vec4<glw::GLfloat>&	  out_first_routine_result,
   4136 							   Utils::vec4<glw::GLfloat>&	  out_second_routine_result,
   4137 							   Utils::vec4<glw::GLfloat>&	  out_third_routine_result,
   4138 							   Utils::vec4<glw::GLuint>&	   out_fourth_routine_result) const
   4139 {
   4140 	static const GLuint   n_uniforms = sizeof(m_uniform_locations) / sizeof(m_uniform_locations[0]);
   4141 	const glw::Functions& gl		 = m_context.getRenderContext().getFunctions();
   4142 	GLuint				  subroutine_indices[4];
   4143 	static const GLuint   n_subroutine_uniforms = sizeof(subroutine_indices) / sizeof(subroutine_indices[0]);
   4144 
   4145 	/* Prepare subroutine uniform data */
   4146 	for (GLuint i = 0; i < n_subroutine_uniforms; ++i)
   4147 	{
   4148 		const GLuint location = m_subroutine_uniform_locations[i][0];
   4149 
   4150 		subroutine_indices[location] = m_subroutine_indices[i][subroutine_combination[i]];
   4151 	}
   4152 
   4153 	/* Set up subroutine uniforms */
   4154 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, n_subroutine_uniforms, &subroutine_indices[0]);
   4155 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   4156 
   4157 	/* Set up input data uniforms */
   4158 	for (GLuint i = 0; i < n_uniforms; ++i)
   4159 	{
   4160 		gl.uniform4f(m_uniform_locations[i], input_data[i].m_x, input_data[i].m_y, input_data[i].m_z,
   4161 					 input_data[i].m_w);
   4162 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f");
   4163 	}
   4164 
   4165 	/* Execute draw call with transform feedback */
   4166 	gl.beginTransformFeedback(GL_POINTS);
   4167 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
   4168 
   4169 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   4170 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
   4171 
   4172 	gl.endTransformFeedback();
   4173 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
   4174 
   4175 	/* Capture results */
   4176 	GLvoid* feedback_data = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   4177 	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
   4178 
   4179 	GLfloat* float_ptr = (GLfloat*)feedback_data;
   4180 
   4181 	/* First result */
   4182 	out_first_routine_result.m_x = float_ptr[0];
   4183 	out_first_routine_result.m_y = float_ptr[1];
   4184 	out_first_routine_result.m_z = float_ptr[2];
   4185 	out_first_routine_result.m_w = float_ptr[3];
   4186 
   4187 	/* Second result */
   4188 	out_second_routine_result.m_x = float_ptr[4];
   4189 	out_second_routine_result.m_y = float_ptr[5];
   4190 	out_second_routine_result.m_z = float_ptr[6];
   4191 	out_second_routine_result.m_w = float_ptr[7];
   4192 
   4193 	/* Third result */
   4194 	out_third_routine_result.m_x = float_ptr[8];
   4195 	out_third_routine_result.m_y = float_ptr[9];
   4196 	out_third_routine_result.m_z = float_ptr[10];
   4197 	out_third_routine_result.m_w = float_ptr[11];
   4198 
   4199 	/* Fourth result */
   4200 	GLuint* uint_ptr			  = (GLuint*)(float_ptr + 12);
   4201 	out_fourth_routine_result.m_x = uint_ptr[0];
   4202 	out_fourth_routine_result.m_y = uint_ptr[1];
   4203 	out_fourth_routine_result.m_z = uint_ptr[2];
   4204 	out_fourth_routine_result.m_w = uint_ptr[3];
   4205 
   4206 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   4207 	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
   4208 }
   4209 
   4210 /** Verify if results match expected results
   4211  *
   4212  * @param first_routine_result           Result of first routine
   4213  * @param second_routine_result          Result of second routine
   4214  * @param third_routine_result           Result of third routine
   4215  * @param fourth_routine_result          Result of fourth routine
   4216  * @param first_routine_expected_result  Expected result of first routine
   4217  * @param second_routine_expected_result Expected result of second routine
   4218  * @param third_routine_expected_result  Expected result of third routine
   4219  * @param fourth_routine_expected_result Expected result of fourth routine
   4220  **/
   4221 bool FunctionalTest5::verify(const Utils::vec4<glw::GLfloat>& first_routine_result,
   4222 							 const Utils::vec4<glw::GLfloat>& second_routine_result,
   4223 							 const Utils::vec4<glw::GLfloat>& third_routine_result,
   4224 							 const Utils::vec4<glw::GLuint>&  fourth_routine_result,
   4225 							 const Utils::vec4<glw::GLfloat>& first_routine_expected_result,
   4226 							 const Utils::vec4<glw::GLfloat>& second_routine_expected_result,
   4227 							 const Utils::vec4<glw::GLfloat>& third_routine_expected_result,
   4228 							 const Utils::vec4<glw::GLuint>&  fourth_routine_expected_result) const
   4229 {
   4230 	bool result = true;
   4231 
   4232 	result = result && (first_routine_result == first_routine_expected_result);
   4233 	result = result && (second_routine_result == second_routine_expected_result);
   4234 	result = result && (third_routine_result == third_routine_expected_result);
   4235 	result = result && (fourth_routine_result == fourth_routine_expected_result);
   4236 
   4237 	return result;
   4238 }
   4239 
   4240 /** Constructor
   4241  *
   4242  * @param context CTS context
   4243  **/
   4244 FunctionalTest6::FunctionalTest6(deqp::Context& context)
   4245 	: TestCase(context, "static_subroutine_call", "Verify that subroutine can be called in a static manner")
   4246 {
   4247 }
   4248 
   4249 /** Execute test
   4250  *
   4251  * @return tcu::TestNode::STOP
   4252  **/
   4253 tcu::TestNode::IterateResult FunctionalTest6::iterate()
   4254 {
   4255 	static const GLchar* vertex_shader_code = "#version 400 core\n"
   4256 											  "#extension GL_ARB_shader_subroutine : require\n"
   4257 											  "\n"
   4258 											  "precision highp float;\n"
   4259 											  "\n"
   4260 											  "// Subroutine type\n"
   4261 											  "subroutine vec4 routine_type(in vec4 iparam);\n"
   4262 											  "\n"
   4263 											  "// Subroutine definition\n"
   4264 											  "subroutine(routine_type) vec4 square(in vec4 iparam)\n"
   4265 											  "{\n"
   4266 											  "    return iparam * iparam;\n"
   4267 											  "}\n"
   4268 											  "\n"
   4269 											  "// Sub routine uniform\n"
   4270 											  "subroutine uniform routine_type routine;\n"
   4271 											  "\n"
   4272 											  "// Input data\n"
   4273 											  "uniform vec4 input_data;\n"
   4274 											  "\n"
   4275 											  "// Output\n"
   4276 											  "out  vec4 out_result;\n"
   4277 											  "\n"
   4278 											  "void main()\n"
   4279 											  "{\n"
   4280 											  "    out_result  = square(input_data);\n"
   4281 											  "}\n"
   4282 											  "\n";
   4283 
   4284 	static const GLchar* varying_name = "out_result";
   4285 
   4286 	/* Test data */
   4287 	static const Utils::vec4<GLfloat> input_data(1.0f, 4.0f, 9.0f, 16.0f);
   4288 
   4289 	static const Utils::vec4<GLfloat> expected_result(1.0f, 16.0f, 81.0f, 256.0f);
   4290 
   4291 	static const GLuint transform_feedback_buffer_size = 4 * sizeof(GLfloat);
   4292 
   4293 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   4294 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   4295 	{
   4296 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   4297 	}
   4298 
   4299 	/* GL objects */
   4300 	Utils::program	 program(m_context);
   4301 	Utils::buffer	  transform_feedback_buffer(m_context);
   4302 	Utils::vertexArray vao(m_context);
   4303 
   4304 	/* Init GL objects */
   4305 	program.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* test */, vertex_shader_code, &varying_name,
   4306 				  1 /* n_varyings */);
   4307 
   4308 	program.use();
   4309 
   4310 	vao.generate();
   4311 	vao.bind();
   4312 
   4313 	transform_feedback_buffer.generate();
   4314 	transform_feedback_buffer.update(GL_TRANSFORM_FEEDBACK_BUFFER, transform_feedback_buffer_size, 0 /* data */,
   4315 									 GL_DYNAMIC_COPY);
   4316 	transform_feedback_buffer.bindRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, transform_feedback_buffer_size);
   4317 
   4318 	/* Test */
   4319 	{
   4320 		const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
   4321 		const GLint			  uniform_location = gl.getUniformLocation(program.m_program_object_id, "input_data");
   4322 
   4323 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
   4324 
   4325 		if (-1 == uniform_location)
   4326 		{
   4327 			TCU_FAIL("Uniform is not available");
   4328 		}
   4329 
   4330 		/* Set up input data uniforms */
   4331 		gl.uniform4f(uniform_location, input_data.m_x, input_data.m_y, input_data.m_z, input_data.m_w);
   4332 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f");
   4333 
   4334 		/* Execute draw call with transform feedback */
   4335 		gl.beginTransformFeedback(GL_POINTS);
   4336 		GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
   4337 
   4338 		gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   4339 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
   4340 
   4341 		gl.endTransformFeedback();
   4342 		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
   4343 
   4344 		/* Capture results */
   4345 		GLfloat* feedback_data = (GLfloat*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   4346 		GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
   4347 
   4348 		Utils::vec4<GLfloat> result(feedback_data[0], feedback_data[1], feedback_data[2], feedback_data[3]);
   4349 
   4350 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   4351 		GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
   4352 
   4353 		/* Verify */
   4354 		if (expected_result == result)
   4355 		{
   4356 			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4357 		}
   4358 		else
   4359 		{
   4360 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result."
   4361 												<< tcu::TestLog::EndMessage;
   4362 
   4363 			tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   4364 
   4365 			message << "Function: square( ";
   4366 			input_data.log(message);
   4367 			message << " ). Result: ";
   4368 			result.log(message);
   4369 			message << ". Expected: ";
   4370 			expected_result.log(message);
   4371 
   4372 			message << tcu::TestLog::EndMessage;
   4373 
   4374 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4375 		}
   4376 	}
   4377 
   4378 	/* Done */
   4379 	return tcu::TestNode::STOP;
   4380 }
   4381 
   4382 /** Constructor
   4383  *
   4384  * @param context CTS context
   4385  **/
   4386 FunctionalTest7_8::FunctionalTest7_8(deqp::Context& context)
   4387 	: TestCase(context, "arrayed_subroutine_uniforms", "Verify that subroutine can be called in a static manner")
   4388 {
   4389 }
   4390 
   4391 /** Execute test
   4392  *
   4393  * @return tcu::TestNode::STOP
   4394  **/
   4395 tcu::TestNode::IterateResult FunctionalTest7_8::iterate()
   4396 {
   4397 	static const GLchar* vertex_shader_code =
   4398 		"#version 400 core\n"
   4399 		"#extension GL_ARB_shader_subroutine : require\n"
   4400 		"\n"
   4401 		"precision highp float;\n"
   4402 		"\n"
   4403 		"// Subroutine type\n"
   4404 		"subroutine vec4 routine_type(in vec4 left, in vec4 right);\n"
   4405 		"\n"
   4406 		"// Subroutine definitions\n"
   4407 		"subroutine(routine_type) vec4 add(in vec4 left, in vec4 right)\n"
   4408 		"{\n"
   4409 		"    return left + right;\n"
   4410 		"}\n"
   4411 		"\n"
   4412 		"subroutine(routine_type) vec4 multiply(in vec4 left, in vec4 right)\n"
   4413 		"{\n"
   4414 		"    return left * right;\n"
   4415 		"}\n"
   4416 		"\n"
   4417 		"// Sub routine uniform\n"
   4418 		"subroutine uniform routine_type routine[4];\n"
   4419 		"\n"
   4420 		"// Input data\n"
   4421 		"uniform vec4  uni_left;\n"
   4422 		"uniform vec4  uni_right;\n"
   4423 		"uniform uvec4 uni_indices;\n"
   4424 		"\n"
   4425 		"// Output\n"
   4426 		"out vec4 out_combined;\n"
   4427 		"out vec4 out_combined_inverted;\n"
   4428 		"out vec4 out_constant;\n"
   4429 		"out vec4 out_constant_inverted;\n"
   4430 		"out vec4 out_dynamic;\n"
   4431 		"out vec4 out_dynamic_inverted;\n"
   4432 		"out vec4 out_loop;\n"
   4433 		"out uint out_array_length;\n"
   4434 		"\n"
   4435 		"void main()\n"
   4436 		"{\n"
   4437 		"    out_combined          = routine[3](routine[2](routine[1](routine[0](uni_left, uni_right), uni_right), "
   4438 		"uni_right), uni_right);\n"
   4439 		"    out_combined_inverted = routine[0](routine[1](routine[2](routine[3](uni_left, uni_right), uni_right), "
   4440 		"uni_right), uni_right);\n"
   4441 		"    \n"
   4442 		"    out_constant          = routine[3](routine[2](routine[1](routine[0](vec4(1, 2, 3, 4), vec4(-5, -6, -7, "
   4443 		"-8)), vec4(-1, -2, -3, -4)), vec4(5, 6, 7, 8)), vec4(1, 2, 3, 4));\n"
   4444 		"    out_constant_inverted = routine[0](routine[1](routine[2](routine[3](vec4(1, 2, 3, 4), vec4(-5, -6, -7, "
   4445 		"-8)), vec4(-1, -2, -3, -4)), vec4(5, 6, 7, 8)), vec4(1, 2, 3, 4));\n"
   4446 		"    \n"
   4447 		"    out_dynamic           = "
   4448 		"routine[uni_indices.w](routine[uni_indices.z](routine[uni_indices.y](routine[uni_indices.x](uni_left, "
   4449 		"uni_right), uni_right), uni_right), uni_right);\n"
   4450 		"    out_dynamic_inverted  = "
   4451 		"routine[uni_indices.x](routine[uni_indices.y](routine[uni_indices.z](routine[uni_indices.w](uni_left, "
   4452 		"uni_right), uni_right), uni_right), uni_right);\n"
   4453 		"    \n"
   4454 		"    out_loop              = uni_left;\n"
   4455 		"    for (uint i = 0u; i < routine.length(); ++i)\n"
   4456 		"    {\n"
   4457 		"        out_loop          = routine[i](out_loop, uni_right);\n"
   4458 		"    }\n"
   4459 		"    \n"
   4460 		"    out_array_length      = routine.length() + 6 - (uni_indices.x + uni_indices.y + uni_indices.z + "
   4461 		"uni_indices.w);\n"
   4462 		"}\n"
   4463 		"\n";
   4464 
   4465 	static const GLchar* subroutine_names[] = {
   4466 		"add", "multiply",
   4467 	};
   4468 	static const GLuint n_subroutine_names = sizeof(subroutine_names) / sizeof(subroutine_names[0]);
   4469 
   4470 	static const GLchar* subroutine_uniform_names[] = { "routine[0]", "routine[1]", "routine[2]", "routine[3]" };
   4471 	static const GLuint  n_subroutine_uniform_names =
   4472 		sizeof(subroutine_uniform_names) / sizeof(subroutine_uniform_names[0]);
   4473 
   4474 	static const GLchar* uniform_names[] = {
   4475 		"uni_left", "uni_right", "uni_indices",
   4476 	};
   4477 	static const GLuint n_uniform_names = sizeof(uniform_names) / sizeof(uniform_names[0]);
   4478 
   4479 	static const GLchar* varying_names[] = { "out_combined", "out_combined_inverted",
   4480 											 "out_constant", "out_constant_inverted",
   4481 											 "out_dynamic",  "out_dynamic_inverted",
   4482 											 "out_loop",	 "out_array_length" };
   4483 
   4484 	static const GLuint n_varyings					   = sizeof(varying_names) / sizeof(varying_names[0]);
   4485 	static const GLuint transform_feedback_buffer_size = n_varyings * 4 * sizeof(GLfloat);
   4486 
   4487 	/* Test data */
   4488 	static const Utils::vec4<GLfloat> uni_left(-1.0f, 0.75f, -0.5f, 0.25f);
   4489 	static const Utils::vec4<GLfloat> uni_right(1.0f, -0.75f, 0.5f, -0.25f);
   4490 	static const Utils::vec4<GLuint>  uni_indices(1, 2, 0, 3);
   4491 
   4492 	static const GLuint subroutine_combinations[][4] = {
   4493 		{ 0, 0, 0, 0 }, /* + + + + */
   4494 		{ 0, 0, 0, 1 }, /* + + + * */
   4495 		{ 0, 0, 1, 0 }, /* + + * + */
   4496 		{ 0, 0, 1, 1 }, /* + + * * */
   4497 		{ 0, 1, 0, 0 }, /* + * + + */
   4498 		{ 0, 1, 0, 1 }, /* + * + * */
   4499 		{ 0, 1, 1, 0 }, /* + * * + */
   4500 		{ 0, 1, 1, 1 }, /* + * * * */
   4501 		{ 1, 0, 0, 0 }, /* * + + + */
   4502 		{ 1, 0, 0, 1 }, /* * + + * */
   4503 		{ 1, 0, 1, 0 }, /* * + * + */
   4504 		{ 1, 0, 1, 1 }, /* * + * * */
   4505 		{ 1, 1, 0, 0 }, /* * * + + */
   4506 		{ 1, 1, 0, 1 }, /* * * + * */
   4507 		{ 1, 1, 1, 0 }, /* * * * + */
   4508 		{ 1, 1, 1, 1 }  /* * * * * */
   4509 	};
   4510 	static const GLuint n_subroutine_combinations =
   4511 		sizeof(subroutine_combinations) / sizeof(subroutine_combinations[0]);
   4512 
   4513 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   4514 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   4515 	{
   4516 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   4517 	}
   4518 
   4519 	/* GL objects */
   4520 	Utils::program	 program(m_context);
   4521 	Utils::buffer	  transform_feedback_buffer(m_context);
   4522 	Utils::vertexArray vao(m_context);
   4523 
   4524 	bool result = true;
   4525 
   4526 	/* Init GL objects */
   4527 	program.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* test */, vertex_shader_code, varying_names,
   4528 				  n_varyings);
   4529 
   4530 	program.use();
   4531 
   4532 	vao.generate();
   4533 	vao.bind();
   4534 
   4535 	transform_feedback_buffer.generate();
   4536 
   4537 	/* Get subroutine indices */
   4538 	for (GLuint routine = 0; routine < n_subroutine_names; ++routine)
   4539 	{
   4540 		m_subroutine_indices[routine] = program.getSubroutineIndex(subroutine_names[routine], GL_VERTEX_SHADER);
   4541 	}
   4542 
   4543 	/* Get subroutine uniform locations */
   4544 	for (GLuint uniform = 0; uniform < n_subroutine_uniform_names; ++uniform)
   4545 	{
   4546 		m_subroutine_uniform_locations[uniform] =
   4547 			program.getSubroutineUniformLocation(subroutine_uniform_names[uniform], GL_VERTEX_SHADER);
   4548 	}
   4549 
   4550 	/* Get uniform locations */
   4551 	for (GLuint i = 0; i < n_uniform_names; ++i)
   4552 	{
   4553 		m_uniform_locations[i] = program.getUniformLocation(uniform_names[i]);
   4554 	}
   4555 
   4556 	/* Test */
   4557 	for (GLuint i = 0; i < n_subroutine_combinations; ++i)
   4558 	{
   4559 		/* Clean */
   4560 		transform_feedback_buffer.update(GL_TRANSFORM_FEEDBACK_BUFFER, transform_feedback_buffer_size, 0 /* data */,
   4561 										 GL_DYNAMIC_COPY);
   4562 		transform_feedback_buffer.bindRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, transform_feedback_buffer_size);
   4563 
   4564 		/* Verify */
   4565 		if (false == testDraw(subroutine_combinations[i], uni_left, uni_right, uni_indices))
   4566 		{
   4567 			result = false;
   4568 		}
   4569 	}
   4570 
   4571 	if (true == result)
   4572 	{
   4573 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4574 	}
   4575 	else
   4576 	{
   4577 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4578 	}
   4579 
   4580 	/* Done */
   4581 	return tcu::TestNode::STOP;
   4582 }
   4583 
   4584 /* Calculate result of function applied to operands
   4585  *
   4586  * @param function Function id, 0 is sum, 1 is multiplication
   4587  * @param left     Left operand
   4588  * @param right    Right operand
   4589  * @param out      Function result
   4590  **/
   4591 void FunctionalTest7_8::calculate(glw::GLuint function, const Utils::vec4<glw::GLfloat>& left,
   4592 								  const Utils::vec4<glw::GLfloat>& right, Utils::vec4<glw::GLfloat>& out) const
   4593 {
   4594 	if (0 == function)
   4595 	{
   4596 		out.m_x = left.m_x + right.m_x;
   4597 		out.m_y = left.m_y + right.m_y;
   4598 		out.m_z = left.m_z + right.m_z;
   4599 		out.m_w = left.m_w + right.m_w;
   4600 	}
   4601 	else
   4602 	{
   4603 		out.m_x = left.m_x * right.m_x;
   4604 		out.m_y = left.m_y * right.m_y;
   4605 		out.m_z = left.m_z * right.m_z;
   4606 		out.m_w = left.m_w * right.m_w;
   4607 	}
   4608 }
   4609 
   4610 /** Calculate expected values for all operations
   4611  *
   4612  * @param combination           Function combination, first applied function is at index [0]
   4613  * @param left                  Left operand
   4614  * @param right                 Right operand
   4615  * @param indices               Indices used by dynamic calls
   4616  * @param out_combined          Expected result of "combined" operation
   4617  * @param out_combined_inverted Expected result of "combined_inverted" operation
   4618  * @param out_constant          Expected result of "constant" operation
   4619  * @param out_constant_inverted Expected result of "constant_inverted" operation
   4620  * @param out_dynamic           Expected result of "dynamic" operation
   4621  * @param out_dynamic_inverted  Expected result of "out_dynamic_inverted" operation
   4622  * @param out_loop              Expected result of "loop" operation
   4623  **/
   4624 void FunctionalTest7_8::calculate(
   4625 	const glw::GLuint combination[4], const Utils::vec4<glw::GLfloat>& left, const Utils::vec4<glw::GLfloat>& right,
   4626 	const Utils::vec4<glw::GLuint>& indices, Utils::vec4<glw::GLfloat>& out_combined,
   4627 	Utils::vec4<glw::GLfloat>& out_combined_inverted, Utils::vec4<glw::GLfloat>& out_constant,
   4628 	Utils::vec4<glw::GLfloat>& out_constant_inverted, Utils::vec4<glw::GLfloat>& out_dynamic,
   4629 	Utils::vec4<glw::GLfloat>& out_dynamic_inverted, Utils::vec4<glw::GLfloat>& out_loop) const
   4630 {
   4631 	/* Indices used by "dynamic" operations, range <0..4> */
   4632 	const GLuint dynamic_combination[4] = { combination[indices.m_x], combination[indices.m_y],
   4633 											combination[indices.m_z], combination[indices.m_w] };
   4634 
   4635 	/* Values used by "constant" operations, come from shader code */
   4636 	const Utils::vec4<glw::GLfloat> constant_values[] = { Utils::vec4<glw::GLfloat>(1, 2, 3, 4),
   4637 														  Utils::vec4<glw::GLfloat>(-5, -6, -7, -8),
   4638 														  Utils::vec4<glw::GLfloat>(-1, -2, -3, -4),
   4639 														  Utils::vec4<glw::GLfloat>(5, 6, 7, 8),
   4640 														  Utils::vec4<glw::GLfloat>(1, 2, 3, 4) };
   4641 
   4642 	/* Start values */
   4643 	Utils::vec4<glw::GLfloat> combined			= left;
   4644 	Utils::vec4<glw::GLfloat> combined_inverted = left;
   4645 	Utils::vec4<glw::GLfloat> constant			= constant_values[0];
   4646 	Utils::vec4<glw::GLfloat> constant_inverted = constant_values[0];
   4647 	Utils::vec4<glw::GLfloat> dynamic			= left;
   4648 	Utils::vec4<glw::GLfloat> dynamic_inverted  = left;
   4649 
   4650 	/* Calculate expected results */
   4651 	for (GLuint i = 0; i < 4; ++i)
   4652 	{
   4653 		GLuint function					 = combination[i];
   4654 		GLuint function_inverted		 = combination[3 - i];
   4655 		GLuint dynamic_function			 = dynamic_combination[i];
   4656 		GLuint dynamic_function_inverted = dynamic_combination[3 - i];
   4657 
   4658 		calculate(function, combined, right, combined);
   4659 		calculate(function_inverted, combined_inverted, right, combined_inverted);
   4660 		calculate(function, constant, constant_values[i + 1], constant);
   4661 		calculate(function_inverted, constant_inverted, constant_values[i + 1], constant_inverted);
   4662 		calculate(dynamic_function, dynamic, right, dynamic);
   4663 		calculate(dynamic_function_inverted, dynamic_inverted, right, dynamic_inverted);
   4664 	}
   4665 
   4666 	/* Store results */
   4667 	out_combined		  = combined;
   4668 	out_combined_inverted = combined_inverted;
   4669 	out_constant		  = constant;
   4670 	out_constant_inverted = constant_inverted;
   4671 	out_dynamic			  = dynamic;
   4672 	out_dynamic_inverted  = dynamic_inverted;
   4673 	out_loop			  = combined;
   4674 }
   4675 
   4676 /** Log error
   4677  *
   4678  * @param combination   Operations combination
   4679  * @param left          Left operand
   4680  * @param right         Right operand
   4681  * @param indices       Inidices used by "dynamic" calls
   4682  * @param vec4_expected Expected results
   4683  * @param vec4_result   Results
   4684  * @param array_length  Length of array
   4685  * @param result        Comparison results
   4686  **/
   4687 void FunctionalTest7_8::logError(const glw::GLuint combination[4], const Utils::vec4<glw::GLfloat>& left,
   4688 								 const Utils::vec4<glw::GLfloat>& right, const Utils::vec4<glw::GLuint>& indices,
   4689 								 const Utils::vec4<glw::GLfloat> vec4_expected[7],
   4690 								 const Utils::vec4<glw::GLfloat> vec4_result[7], glw::GLuint array_length,
   4691 								 bool result[7]) const
   4692 {
   4693 	static const GLuint n_functions  = 4;
   4694 	static const GLuint n_operations = 7;
   4695 
   4696 	/* Indices used by "dynamic" operations, range <0..4> */
   4697 	const GLuint dynamic_combination[4] = { combination[indices.m_x], combination[indices.m_y],
   4698 											combination[indices.m_z], combination[indices.m_w] };
   4699 
   4700 	/* Function symbols */
   4701 	GLchar functions[4];
   4702 	GLchar functions_inverted[4];
   4703 	GLchar functions_dynamic[4];
   4704 	GLchar functions_dynamic_inverted[4];
   4705 
   4706 	for (GLuint i = 0; i < n_functions; ++i)
   4707 	{
   4708 		GLchar function			= (0 == combination[i]) ? '+' : '*';
   4709 		GLchar dynamic_function = (0 == dynamic_combination[i]) ? '+' : '*';
   4710 
   4711 		functions[i]									= function;
   4712 		functions_inverted[n_functions - i - 1]			= function;
   4713 		functions_dynamic[i]							= dynamic_function;
   4714 		functions_dynamic_inverted[n_functions - i - 1] = dynamic_function;
   4715 	}
   4716 
   4717 	/* Values used by "constant" operations, come from shader code */
   4718 	const Utils::vec4<glw::GLfloat> constant_values[] = { Utils::vec4<glw::GLfloat>(1, 2, 3, 4),
   4719 														  Utils::vec4<glw::GLfloat>(-5, -6, -7, -8),
   4720 														  Utils::vec4<glw::GLfloat>(-1, -2, -3, -4),
   4721 														  Utils::vec4<glw::GLfloat>(5, 6, 7, 8),
   4722 														  Utils::vec4<glw::GLfloat>(1, 2, 3, 4) };
   4723 
   4724 	/* Values used by non-"constant" operations */
   4725 	Utils::vec4<glw::GLfloat> dynamic_values[5];
   4726 	dynamic_values[0] = left;
   4727 	dynamic_values[1] = right;
   4728 	dynamic_values[2] = right;
   4729 	dynamic_values[3] = right;
   4730 	dynamic_values[4] = right;
   4731 
   4732 	/* For each operation */
   4733 	for (GLuint i = 0; i < n_operations; ++i)
   4734 	{
   4735 		/* If result is failure */
   4736 		if (false == result[i])
   4737 		{
   4738 			const GLchar*					 description = 0;
   4739 			const Utils::vec4<glw::GLfloat>* input		 = 0;
   4740 			const GLchar*					 operation   = 0;
   4741 
   4742 			switch (i)
   4743 			{
   4744 			case 0:
   4745 				description = "Call made with predefined array indices";
   4746 				input		= dynamic_values;
   4747 				operation   = functions;
   4748 				break;
   4749 			case 1:
   4750 				description = "Call made with predefined array indices in inverted order";
   4751 				input		= dynamic_values;
   4752 				operation   = functions_inverted;
   4753 				break;
   4754 			case 2:
   4755 				description = "Call made with predefined array indices, for constant values";
   4756 				input		= constant_values;
   4757 				operation   = functions;
   4758 				break;
   4759 			case 3:
   4760 				description = "Call made with predefined array indices in inverted order, for constant values";
   4761 				input		= constant_values;
   4762 				operation   = functions_inverted;
   4763 				break;
   4764 			case 4:
   4765 				description = "Call made with dynamic array indices";
   4766 				input		= dynamic_values;
   4767 				operation   = functions_dynamic;
   4768 				break;
   4769 			case 5:
   4770 				description = "Call made with dynamic array indices in inverted order";
   4771 				input		= dynamic_values;
   4772 				operation   = functions_dynamic_inverted;
   4773 				break;
   4774 			case 6:
   4775 				description = "Call made with loop";
   4776 				input		= dynamic_values;
   4777 				operation   = functions;
   4778 				break;
   4779 			}
   4780 
   4781 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result."
   4782 												<< tcu::TestLog::EndMessage;
   4783 
   4784 			m_context.getTestContext().getLog() << tcu::TestLog::Message << description << tcu::TestLog::EndMessage;
   4785 
   4786 			tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   4787 
   4788 			message << "Operation: ((((";
   4789 			input[0].log(message);
   4790 			for (GLuint function = 0; function < n_functions; ++function)
   4791 			{
   4792 				message << " " << operation[function] << " ";
   4793 
   4794 				input[function + 1].log(message);
   4795 
   4796 				message << ")";
   4797 			}
   4798 
   4799 			message << tcu::TestLog::EndMessage;
   4800 
   4801 			message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   4802 
   4803 			message << "Result: ";
   4804 			vec4_result[i].log(message);
   4805 
   4806 			message << tcu::TestLog::EndMessage;
   4807 
   4808 			message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   4809 
   4810 			message << "Expected: ";
   4811 			vec4_expected[i].log(message);
   4812 
   4813 			message << tcu::TestLog::EndMessage;
   4814 		}
   4815 
   4816 		/* Check array length, it should be 4 */
   4817 		if (4 != array_length)
   4818 		{
   4819 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   4820 												<< "Error. Invalid array length: " << array_length << ". Expected 4."
   4821 												<< tcu::TestLog::EndMessage;
   4822 		}
   4823 	}
   4824 }
   4825 
   4826 /** Execute draw call and verifies captrued varyings
   4827  *
   4828  * @param combination           Function combination, first applied function is at index [0]
   4829  * @param left                  Left operand
   4830  * @param right                 Right operand
   4831  * @param indices               Indices used by dynamic calls
   4832  *
   4833  * @return true if all results match expected values, false otherwise
   4834  **/
   4835 bool FunctionalTest7_8::testDraw(const glw::GLuint combination[4], const Utils::vec4<glw::GLfloat>& left,
   4836 								 const Utils::vec4<glw::GLfloat>& right, const Utils::vec4<glw::GLuint>& indices) const
   4837 {
   4838 	const glw::Functions& gl			  = m_context.getRenderContext().getFunctions();
   4839 	static const GLuint   n_vec4_varyings = 7;
   4840 	bool				  result		  = true;
   4841 	GLuint				  subroutine_indices[4];
   4842 	static const GLuint   n_subroutine_uniforms = sizeof(subroutine_indices) / sizeof(subroutine_indices[0]);
   4843 
   4844 	/* Prepare expected results */
   4845 	Utils::vec4<glw::GLfloat> expected_results[7];
   4846 	calculate(combination, left, right, indices, expected_results[0], expected_results[1], expected_results[2],
   4847 			  expected_results[3], expected_results[4], expected_results[5], expected_results[6]);
   4848 
   4849 	/* Set up input data uniforms */
   4850 	gl.uniform4f(m_uniform_locations[0], left.m_x, left.m_y, left.m_z, left.m_w);
   4851 	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f");
   4852 
   4853 	gl.uniform4f(m_uniform_locations[1], right.m_x, right.m_y, right.m_z, right.m_w);
   4854 	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f");
   4855 
   4856 	gl.uniform4ui(m_uniform_locations[2], indices.m_x, indices.m_y, indices.m_z, indices.m_w);
   4857 	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4ui");
   4858 
   4859 	/* Prepare subroutine uniform data */
   4860 	for (GLuint i = 0; i < n_subroutine_uniforms; ++i)
   4861 	{
   4862 		const GLuint location = m_subroutine_uniform_locations[i];
   4863 
   4864 		subroutine_indices[location] = m_subroutine_indices[combination[i]];
   4865 	}
   4866 
   4867 	/* Set up subroutine uniforms */
   4868 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, n_subroutine_uniforms, &subroutine_indices[0]);
   4869 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   4870 
   4871 	/* Execute draw call with transform feedback */
   4872 	gl.beginTransformFeedback(GL_POINTS);
   4873 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
   4874 
   4875 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   4876 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
   4877 
   4878 	gl.endTransformFeedback();
   4879 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
   4880 
   4881 	/* Capture results */
   4882 	GLvoid* feedback_data = (GLvoid*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   4883 	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
   4884 
   4885 	Utils::vec4<GLfloat> vec4_results[7];
   4886 	bool				 results[7];
   4887 	GLfloat*			 float_data = (GLfloat*)feedback_data;
   4888 	for (GLuint i = 0; i < n_vec4_varyings; ++i)
   4889 	{
   4890 		vec4_results[i].m_x = float_data[i * 4 + 0];
   4891 		vec4_results[i].m_y = float_data[i * 4 + 1];
   4892 		vec4_results[i].m_z = float_data[i * 4 + 2];
   4893 		vec4_results[i].m_w = float_data[i * 4 + 3];
   4894 	}
   4895 
   4896 	GLuint* uint_data	= (GLuint*)(float_data + (n_vec4_varyings)*4);
   4897 	GLuint  array_length = uint_data[0];
   4898 
   4899 	/* Unmap buffer */
   4900 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   4901 	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
   4902 
   4903 	/* Verification */
   4904 	for (GLuint i = 0; i < n_vec4_varyings; ++i)
   4905 	{
   4906 		results[i] = (vec4_results[i] == expected_results[i]);
   4907 		result	 = result && results[i];
   4908 	}
   4909 
   4910 	result = result && (4 == array_length);
   4911 
   4912 	/* Log error if any */
   4913 	if (false == result)
   4914 	{
   4915 		logError(combination, left, right, indices, expected_results, vec4_results, array_length, results);
   4916 	}
   4917 
   4918 	/* Done */
   4919 	return result;
   4920 }
   4921 
   4922 /** Constructor.
   4923  *
   4924  *  @param context Rendering context.
   4925  *
   4926  **/
   4927 FunctionalTest9::FunctionalTest9(deqp::Context& context)
   4928 	: TestCase(context, "subroutines_3_subroutine_types_and_subroutine_uniforms_one_function",
   4929 			   "Makes sure that program with one function associated with 3 different "
   4930 			   "subroutine types and 3 subroutine uniforms using that function compiles "
   4931 			   "and works as expected")
   4932 	, m_has_test_passed(true)
   4933 	, m_n_points_to_draw(16) /* arbitrary value */
   4934 	, m_po_id(0)
   4935 	, m_vao_id(0)
   4936 	, m_vs_id(0)
   4937 	, m_xfb_bo_id(0)
   4938 {
   4939 	/* Left blank intentionally */
   4940 }
   4941 
   4942 /** De-initializes GL objects that may have been created during test execution. */
   4943 void FunctionalTest9::deinit()
   4944 {
   4945 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4946 
   4947 	if (m_po_id != 0)
   4948 	{
   4949 		gl.deleteProgram(m_po_id);
   4950 
   4951 		m_po_id = 0;
   4952 	}
   4953 
   4954 	if (m_vao_id != 0)
   4955 	{
   4956 		gl.deleteVertexArrays(1, &m_vao_id);
   4957 
   4958 		m_vao_id = 0;
   4959 	}
   4960 
   4961 	if (m_vs_id != 0)
   4962 	{
   4963 		gl.deleteShader(m_vs_id);
   4964 
   4965 		m_vs_id = 0;
   4966 	}
   4967 
   4968 	if (m_xfb_bo_id != 0)
   4969 	{
   4970 		gl.deleteBuffers(1, &m_xfb_bo_id);
   4971 
   4972 		m_xfb_bo_id = 0;
   4973 	}
   4974 }
   4975 
   4976 /** Retrieves body of a vertex shader that should be used
   4977  *  for the testing purposes.
   4978  **/
   4979 std::string FunctionalTest9::getVertexShaderBody() const
   4980 {
   4981 	return "#version 400\n"
   4982 		   "\n"
   4983 		   "#extension GL_ARB_shader_subroutine : require\n"
   4984 		   "\n"
   4985 		   "subroutine void subroutineType1(inout float);\n"
   4986 		   "subroutine void subroutineType2(inout float);\n"
   4987 		   "subroutine void subroutineType3(inout float);\n"
   4988 		   "\n"
   4989 		   "subroutine(subroutineType1, subroutineType2, subroutineType3) void function(inout float result)\n"
   4990 		   "{\n"
   4991 		   "    result += float(0.123) + float(gl_VertexID);\n"
   4992 		   "}\n"
   4993 		   "\n"
   4994 		   "subroutine uniform subroutineType1 subroutine_uniform1;\n"
   4995 		   "subroutine uniform subroutineType2 subroutine_uniform2;\n"
   4996 		   "subroutine uniform subroutineType3 subroutine_uniform3;\n"
   4997 		   "\n"
   4998 		   "out vec4 result;\n"
   4999 		   "\n"
   5000 		   "void main()\n"
   5001 		   "{\n"
   5002 		   "    result = vec4(0, 1, 2, 3);\n"
   5003 		   "\n"
   5004 		   "    subroutine_uniform1(result.x);\n"
   5005 		   "    subroutine_uniform2(result.y);\n"
   5006 		   "    subroutine_uniform3(result.z);\n"
   5007 		   "\n"
   5008 		   "    result.w += result.x + result.y + result.z;\n"
   5009 		   "}\n";
   5010 }
   5011 
   5012 /** Initializes all GL objects required to run the test. */
   5013 void FunctionalTest9::initTest()
   5014 {
   5015 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5016 
   5017 	/* Set up program object */
   5018 	const char* xfb_varyings[] = { "result" };
   5019 
   5020 	const unsigned int n_xfb_varyings = sizeof(xfb_varyings) / sizeof(xfb_varyings[0]);
   5021 	if (!Utils::buildProgram(gl, getVertexShaderBody(), "",					  /* tc_body */
   5022 							 "",											  /* te_body */
   5023 							 "",											  /* gs_body */
   5024 							 "",											  /* fs_body */
   5025 							 xfb_varyings, n_xfb_varyings, &m_vs_id, DE_NULL, /* out_tc_id */
   5026 							 DE_NULL,										  /* out_te_id */
   5027 							 DE_NULL,										  /* out_gs_id */
   5028 							 DE_NULL,										  /* out_fs_id */
   5029 							 &m_po_id))
   5030 	{
   5031 		TCU_FAIL("Program failed to link successfully");
   5032 	}
   5033 
   5034 	/* Set up a buffer object we will use to hold XFB data */
   5035 	const unsigned int xfb_bo_size = static_cast<unsigned int>(sizeof(float) * 4 /* components */ * m_n_points_to_draw);
   5036 
   5037 	gl.genBuffers(1, &m_xfb_bo_id);
   5038 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
   5039 
   5040 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id);
   5041 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
   5042 
   5043 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id);
   5044 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
   5045 
   5046 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_bo_size, DE_NULL, /* data */
   5047 				  GL_STATIC_COPY);
   5048 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
   5049 
   5050 	/* Generate & bind a VAO */
   5051 	gl.genVertexArrays(1, &m_vao_id);
   5052 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
   5053 
   5054 	gl.bindVertexArray(m_vao_id);
   5055 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
   5056 }
   5057 
   5058 /** Executes test iteration.
   5059  *
   5060  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   5061  */
   5062 tcu::TestNode::IterateResult FunctionalTest9::iterate()
   5063 {
   5064 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5065 
   5066 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   5067 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   5068 	{
   5069 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   5070 	}
   5071 	initTest();
   5072 
   5073 	/* Issue a draw call to make use of the three subroutine uniforms that we've defined */
   5074 	gl.useProgram(m_po_id);
   5075 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   5076 
   5077 	gl.beginTransformFeedback(GL_POINTS);
   5078 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
   5079 	{
   5080 		gl.drawArrays(GL_POINTS, 0 /* first */, m_n_points_to_draw);
   5081 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   5082 	}
   5083 	gl.endTransformFeedback();
   5084 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
   5085 
   5086 	/* Map the XFB BO storage into process space */
   5087 	const glw::GLvoid* xfb_data_ptr = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   5088 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
   5089 
   5090 	verifyXFBData(xfb_data_ptr);
   5091 
   5092 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   5093 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
   5094 
   5095 	/* All done */
   5096 	if (m_has_test_passed)
   5097 	{
   5098 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5099 	}
   5100 	else
   5101 	{
   5102 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5103 	}
   5104 
   5105 	return STOP;
   5106 }
   5107 
   5108 /** Verifies the data XFBed out by the vertex shader. Should the data
   5109  *  be found invalid, m_has_test_passed will be set to false.
   5110  *
   5111  *  @param data_ptr XFB data.
   5112  **/
   5113 void FunctionalTest9::verifyXFBData(const glw::GLvoid* data_ptr)
   5114 {
   5115 	const float			epsilon			= 1e-5f;
   5116 	bool				should_continue = true;
   5117 	const glw::GLfloat* traveller_ptr   = (const glw::GLfloat*)data_ptr;
   5118 
   5119 	for (unsigned int n_point = 0; n_point < m_n_points_to_draw && should_continue; ++n_point)
   5120 	{
   5121 		tcu::Vec4 expected_result(0, 1, 2, 3);
   5122 
   5123 		for (unsigned int n_component = 0; n_component < 3 /* xyz */; ++n_component)
   5124 		{
   5125 			expected_result[n_component] += 0.123f + float(n_point);
   5126 		}
   5127 
   5128 		expected_result[3 /* w */] += expected_result[0] + expected_result[1] + expected_result[2];
   5129 
   5130 		if (de::abs(expected_result[0] - traveller_ptr[0]) > epsilon ||
   5131 			de::abs(expected_result[1] - traveller_ptr[1]) > epsilon ||
   5132 			de::abs(expected_result[2] - traveller_ptr[2]) > epsilon ||
   5133 			de::abs(expected_result[3] - traveller_ptr[3]) > epsilon)
   5134 		{
   5135 			m_testCtx.getLog() << tcu::TestLog::Message << "XFBed data is invalid. Expected:"
   5136 														   "("
   5137 							   << expected_result[0] << ", " << expected_result[1] << ", " << expected_result[2] << ", "
   5138 							   << expected_result[3] << "), found:(" << traveller_ptr[0] << ", " << traveller_ptr[1]
   5139 							   << ", " << traveller_ptr[2] << ", " << traveller_ptr[3] << ")."
   5140 							   << tcu::TestLog::EndMessage;
   5141 
   5142 			m_has_test_passed = false;
   5143 			should_continue   = false;
   5144 		}
   5145 
   5146 		traveller_ptr += 4; /* xyzw */
   5147 	}						/* for (all rendered points) */
   5148 }
   5149 
   5150 /** Constructor
   5151  *
   5152  * @param context CTS context
   5153  **/
   5154 FunctionalTest10::FunctionalTest10(deqp::Context& context)
   5155 	: TestCase(context, "arrays_of_arrays_of_uniforms", "Verify that arrays of arrays of uniforms works as expected")
   5156 {
   5157 }
   5158 
   5159 /** Execute test
   5160  *
   5161  * @return tcu::TestNode::STOP
   5162  **/
   5163 tcu::TestNode::IterateResult FunctionalTest10::iterate()
   5164 {
   5165 	static const GLchar* vertex_shader_code = "#version 400 core\n"
   5166 											  "#extension GL_ARB_arrays_of_arrays  : require\n"
   5167 											  "#extension GL_ARB_shader_subroutine : require\n"
   5168 											  "\n"
   5169 											  "precision highp float;\n"
   5170 											  "\n"
   5171 											  "// Subroutine type\n"
   5172 											  "subroutine int routine_type(in int iparam);\n"
   5173 											  "\n"
   5174 											  "// Subroutine definitions\n"
   5175 											  "subroutine(routine_type) int increment(in int iparam)\n"
   5176 											  "{\n"
   5177 											  "    return iparam + 1;\n"
   5178 											  "}\n"
   5179 											  "\n"
   5180 											  "subroutine(routine_type) int decrement(in int iparam)\n"
   5181 											  "{\n"
   5182 											  "    return iparam - 1;\n"
   5183 											  "}\n"
   5184 											  "\n"
   5185 											  "// Sub routine uniform\n"
   5186 											  "subroutine uniform routine_type routine[4][4];\n"
   5187 											  "\n"
   5188 											  "// Output\n"
   5189 											  "out int out_result;\n"
   5190 											  "\n"
   5191 											  "void main()\n"
   5192 											  "{\n"
   5193 											  "    int result = 0;\n"
   5194 											  "    \n"
   5195 											  "    for (uint j = 0; j < routine.length(); ++j)\n"
   5196 											  "    {\n"
   5197 											  "        for (uint i = 0; i < routine[j].length(); ++i)\n"
   5198 											  "        {\n"
   5199 											  "            result = routine[j][i](result);\n"
   5200 											  "        }\n"
   5201 											  "    }\n"
   5202 											  "    \n"
   5203 											  "    out_result = result;\n"
   5204 											  "}\n"
   5205 											  "\n";
   5206 
   5207 	static const GLchar* subroutine_names[] = {
   5208 		"increment", "decrement",
   5209 	};
   5210 	static const GLuint n_subroutine_names = sizeof(subroutine_names) / sizeof(subroutine_names[0]);
   5211 
   5212 	static const GLchar* subroutine_uniform_names[] = {
   5213 		"routine[0][0]", "routine[1][0]", "routine[2][0]", "routine[3][0]", "routine[0][1]", "routine[1][1]",
   5214 		"routine[2][1]", "routine[3][1]", "routine[0][2]", "routine[1][2]", "routine[2][2]", "routine[3][2]",
   5215 		"routine[0][3]", "routine[1][3]", "routine[2][3]", "routine[3][3]"
   5216 	};
   5217 	static const GLuint n_subroutine_uniform_names =
   5218 		sizeof(subroutine_uniform_names) / sizeof(subroutine_uniform_names[0]);
   5219 
   5220 	static const GLchar* varying_name					= "out_result";
   5221 	static const GLuint  transform_feedback_buffer_size = sizeof(GLint);
   5222 
   5223 	static const GLuint configuration_increment[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   5224 
   5225 	static const GLuint configuration_decrement[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
   5226 
   5227 	static const GLuint configuration_mix[16] = { 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1 };
   5228 
   5229 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   5230 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   5231 	{
   5232 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   5233 	}
   5234 
   5235 	/* Do not execute the test if GL_ARB_arrays_of_arrays is not supported */
   5236 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_arrays_of_arrays"))
   5237 	{
   5238 		throw tcu::NotSupportedError("GL_ARB_arrays_of_arrays is not supported.");
   5239 	}
   5240 
   5241 	bool result = true;
   5242 
   5243 	/* GL objects */
   5244 	Utils::program	 program(m_context);
   5245 	Utils::buffer	  transform_feedback_buffer(m_context);
   5246 	Utils::vertexArray vao(m_context);
   5247 
   5248 	/* Init GL objects */
   5249 	program.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* test */, vertex_shader_code, &varying_name,
   5250 				  1 /* n_varyings */);
   5251 
   5252 	program.use();
   5253 
   5254 	vao.generate();
   5255 	vao.bind();
   5256 
   5257 	transform_feedback_buffer.generate();
   5258 	transform_feedback_buffer.update(GL_TRANSFORM_FEEDBACK_BUFFER, transform_feedback_buffer_size, 0 /* data */,
   5259 									 GL_DYNAMIC_COPY);
   5260 	transform_feedback_buffer.bindRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, transform_feedback_buffer_size);
   5261 
   5262 	/* Get subroutine indices */
   5263 	for (GLuint routine = 0; routine < n_subroutine_names; ++routine)
   5264 	{
   5265 		m_subroutine_indices[routine] = program.getSubroutineIndex(subroutine_names[routine], GL_VERTEX_SHADER);
   5266 	}
   5267 
   5268 	/* Get subroutine uniform locations */
   5269 	for (GLuint uniform = 0; uniform < n_subroutine_uniform_names; ++uniform)
   5270 	{
   5271 		m_subroutine_uniform_locations[uniform] =
   5272 			program.getSubroutineUniformLocation(subroutine_uniform_names[uniform], GL_VERTEX_SHADER);
   5273 	}
   5274 
   5275 	/* Test */
   5276 	GLint increment_result = testDraw(configuration_increment);
   5277 	GLint decrement_result = testDraw(configuration_decrement);
   5278 	GLint mix_result	   = testDraw(configuration_mix);
   5279 
   5280 	/* Verify */
   5281 	if (16 != increment_result)
   5282 	{
   5283 		result = false;
   5284 	}
   5285 
   5286 	if (-16 != decrement_result)
   5287 	{
   5288 		result = false;
   5289 	}
   5290 	if (0 != mix_result)
   5291 	{
   5292 		result = false;
   5293 	}
   5294 
   5295 	/* Set test result */
   5296 	if (true == result)
   5297 	{
   5298 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5299 	}
   5300 	else
   5301 	{
   5302 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result."
   5303 											<< " Incrementation applied 16 times: " << increment_result
   5304 											<< ". Decrementation applied 16 times: " << decrement_result
   5305 											<< ". Incrementation and decrementation applied 8 times: " << mix_result
   5306 											<< tcu::TestLog::EndMessage;
   5307 
   5308 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5309 	}
   5310 
   5311 	/* Done */
   5312 	return tcu::TestNode::STOP;
   5313 }
   5314 
   5315 /** Execute draw call and return captured varying
   5316  *
   5317  * @param routine_indices Configuration of subroutine uniforms
   5318  *
   5319  * @return Value of varying captured with transform feedback
   5320  **/
   5321 GLint FunctionalTest10::testDraw(const GLuint routine_indices[16]) const
   5322 {
   5323 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5324 	GLuint				  subroutine_indices[16];
   5325 	static const GLuint   n_subroutine_uniforms = sizeof(subroutine_indices) / sizeof(subroutine_indices[0]);
   5326 
   5327 	/* Prepare subroutine uniform data */
   5328 	for (GLuint i = 0; i < n_subroutine_uniforms; ++i)
   5329 	{
   5330 		const GLuint location = m_subroutine_uniform_locations[i];
   5331 
   5332 		subroutine_indices[location] = m_subroutine_indices[routine_indices[i]];
   5333 	}
   5334 
   5335 	/* Set up subroutine uniforms */
   5336 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, n_subroutine_uniforms, &subroutine_indices[0]);
   5337 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   5338 
   5339 	/* Execute draw call with transform feedback */
   5340 	gl.beginTransformFeedback(GL_POINTS);
   5341 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
   5342 
   5343 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   5344 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
   5345 
   5346 	gl.endTransformFeedback();
   5347 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
   5348 
   5349 	/* Capture results */
   5350 	GLint* feedback_data = (GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   5351 	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
   5352 
   5353 	GLint result = feedback_data[0];
   5354 
   5355 	/* Unmap buffer */
   5356 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   5357 	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
   5358 
   5359 	return result;
   5360 }
   5361 
   5362 /* Definitions of constants used by FunctionalTest11 */
   5363 const GLuint FunctionalTest11::m_texture_height = 32;
   5364 const GLuint FunctionalTest11::m_texture_width  = 32;
   5365 
   5366 /** Constructor
   5367  *
   5368  * @param context CTS context
   5369  **/
   5370 FunctionalTest11::FunctionalTest11(deqp::Context& context)
   5371 	: TestCase(context, "globals_sampling_output_discard_function_calls", "Verify that global variables, texture "
   5372 																		  "sampling, fragment output, fragment discard "
   5373 																		  "and function calls work as expected")
   5374 {
   5375 }
   5376 
   5377 /** Execute test
   5378  *
   5379  * @return tcu::TestNode::STOP
   5380  **/
   5381 tcu::TestNode::IterateResult FunctionalTest11::iterate()
   5382 {
   5383 	static const GLchar* fragment_shader_code =
   5384 		"#version 400 core\n"
   5385 		"#extension GL_ARB_shader_subroutine : require\n"
   5386 		"\n"
   5387 		"precision highp float;\n"
   5388 		"\n"
   5389 		"// Output\n"
   5390 		"layout(location = 0) out vec4 out_color;\n"
   5391 		"\n"
   5392 		"// Global variables\n"
   5393 		"vec4 success_color;\n"
   5394 		"vec4 failure_color;\n"
   5395 		"\n"
   5396 		"// Samplers\n"
   5397 		"uniform sampler2D sampler_1;\n"
   5398 		"uniform sampler2D sampler_2;\n"
   5399 		"\n"
   5400 		"// Functions\n"
   5401 		"bool are_same(in vec4 left, in vec4 right)\n"
   5402 		"{\n"
   5403 		"    bvec4 result;\n"
   5404 		"\n"
   5405 		"    result.x = (left.x == right.x);\n"
   5406 		"    result.y = (left.y == right.y);\n"
   5407 		"    result.z = (left.z == right.z);\n"
   5408 		"    result.w = (left.w == right.w);\n"
   5409 		"\n"
   5410 		"    return all(result);\n"
   5411 		"}\n"
   5412 		"\n"
   5413 		"bool are_different(in vec4 left, in vec4 right)\n"
   5414 		"{\n"
   5415 		"    bvec4 result;\n"
   5416 		"\n"
   5417 		"    result.x = (left.x != right.x);\n"
   5418 		"    result.y = (left.y != right.y);\n"
   5419 		"    result.z = (left.z != right.z);\n"
   5420 		"    result.w = (left.w != right.w);\n"
   5421 		"\n"
   5422 		"    return any(result);\n"
   5423 		"}\n"
   5424 		"\n"
   5425 		"// Subroutine types\n"
   5426 		"subroutine void discard_fragment_type(void);\n"
   5427 		"subroutine void set_global_colors_type(void);\n"
   5428 		"subroutine vec4 sample_texture_type(in vec2);\n"
   5429 		"subroutine bool comparison_type(in vec4 left, in vec4 right);\n"
   5430 		"subroutine void test_type(void);\n"
   5431 		"\n"
   5432 		"// Subroutine definitions\n"
   5433 		"// discard_fragment_type\n"
   5434 		"subroutine(discard_fragment_type) void discard_yes(void)\n"
   5435 		"{\n"
   5436 		"    discard;\n"
   5437 		"}\n"
   5438 		"\n"
   5439 		"subroutine(discard_fragment_type) void discard_no(void)\n"
   5440 		"{\n"
   5441 		"}\n"
   5442 		"\n"
   5443 		"// set_global_colors_type\n"
   5444 		"subroutine(set_global_colors_type) void red_pass_blue_fail(void)\n"
   5445 		"{\n"
   5446 		"    success_color = vec4(1, 0, 0, 1);\n"
   5447 		"    failure_color = vec4(0, 0, 1, 1);\n"
   5448 		"}\n"
   5449 		"\n"
   5450 		"subroutine(set_global_colors_type) void blue_pass_red_fail(void)\n"
   5451 		"{\n"
   5452 		"    success_color = vec4(0, 0, 1, 1);\n"
   5453 		"    failure_color = vec4(1, 0, 0, 1);\n"
   5454 		"}\n"
   5455 		"\n"
   5456 		"// sample_texture_type\n"
   5457 		"subroutine(sample_texture_type) vec4 first_sampler(in vec2 coord)\n"
   5458 		"{\n"
   5459 		"    return texture(sampler_1, coord);\n"
   5460 		"}\n"
   5461 		"\n"
   5462 		"subroutine(sample_texture_type) vec4 second_sampler(in vec2 coord)\n"
   5463 		"{\n"
   5464 		"    return texture(sampler_2, coord);\n"
   5465 		"}\n"
   5466 		"\n"
   5467 		"// comparison_type\n"
   5468 		"subroutine(comparison_type) bool check_equal(in vec4 left, in vec4 right)\n"
   5469 		"{\n"
   5470 		"    return are_same(left, right);\n"
   5471 		"}\n"
   5472 		"\n"
   5473 		"subroutine(comparison_type) bool check_not_equal(in vec4 left, in vec4 right)\n"
   5474 		"{\n"
   5475 		"    return are_different(left, right);\n"
   5476 		"}\n"
   5477 		"\n"
   5478 		"// Subroutine uniforms\n"
   5479 		"subroutine uniform discard_fragment_type  discard_fragment;\n"
   5480 		"subroutine uniform set_global_colors_type set_global_colors;\n"
   5481 		"subroutine uniform sample_texture_type    sample_texture;\n"
   5482 		"subroutine uniform comparison_type        compare;\n"
   5483 		"\n"
   5484 		"// Subroutine definitions\n"
   5485 		"// test_type\n"
   5486 		"subroutine(test_type) void test_with_discard(void)\n"
   5487 		"{\n"
   5488 		"    discard_fragment();"
   5489 		"\n"
   5490 		"    out_color = failure_color;\n"
   5491 		"\n"
   5492 		"    set_global_colors();\n"
   5493 		"\n"
   5494 		"    vec4 sampled_color = sample_texture(gl_PointCoord);\n"
   5495 		"\n"
   5496 		"    bool comparison_result = compare(success_color, sampled_color);\n"
   5497 		"\n"
   5498 		"    if (true == comparison_result)\n"
   5499 		"    {\n"
   5500 		"        out_color = success_color;\n"
   5501 		"    }\n"
   5502 		"    else\n"
   5503 		"    {\n"
   5504 		"        out_color = failure_color;\n"
   5505 		"    }\n"
   5506 		"}\n"
   5507 		"\n"
   5508 		"subroutine(test_type) void test_without_discard(void)\n"
   5509 		"{\n"
   5510 		"    set_global_colors();\n"
   5511 		"\n"
   5512 		"    vec4 sampled_color = sample_texture(gl_PointCoord);\n"
   5513 		"\n"
   5514 		"    bool comparison_result = compare(success_color, sampled_color);\n"
   5515 		"\n"
   5516 		"    if (true == comparison_result)\n"
   5517 		"    {\n"
   5518 		"        out_color = success_color;\n"
   5519 		"    }\n"
   5520 		"    else\n"
   5521 		"    {\n"
   5522 		"        out_color = failure_color;\n"
   5523 		"    }\n"
   5524 		"}\n"
   5525 		"\n"
   5526 		"// Subroutine uniforms\n"
   5527 		"subroutine uniform test_type test;\n"
   5528 		"\n"
   5529 		"void main()\n"
   5530 		"{\n"
   5531 		"    // Set colors\n"
   5532 		"    success_color = vec4(0.5, 0.5, 0.5, 0.5);\n"
   5533 		"    failure_color = vec4(0.5, 0.5, 0.5, 0.5);\n"
   5534 		"\n"
   5535 		"    test();\n"
   5536 		"}\n"
   5537 		"\n";
   5538 
   5539 	static const GLchar* geometry_shader_code = "#version 400 core\n"
   5540 												"#extension GL_ARB_shader_subroutine : require\n"
   5541 												"\n"
   5542 												"precision highp float;\n"
   5543 												"\n"
   5544 												"layout(points)                           in;\n"
   5545 												"layout(triangle_strip, max_vertices = 4) out;\n"
   5546 												"\n"
   5547 												"void main()\n"
   5548 												"{\n"
   5549 												"    gl_Position = vec4(-1, -1, 0, 1);\n"
   5550 												"    EmitVertex();\n"
   5551 												"    \n"
   5552 												"    gl_Position = vec4(-1,  1, 0, 1);\n"
   5553 												"    EmitVertex();\n"
   5554 												"    \n"
   5555 												"    gl_Position = vec4( 1, -1, 0, 1);\n"
   5556 												"    EmitVertex();\n"
   5557 												"    \n"
   5558 												"    gl_Position = vec4( 1,  1, 0, 1);\n"
   5559 												"    EmitVertex();\n"
   5560 												"    \n"
   5561 												"    EndPrimitive();\n"
   5562 												"}\n"
   5563 												"\n";
   5564 
   5565 	static const GLchar* vertex_shader_code = "#version 400 core\n"
   5566 											  "#extension GL_ARB_shader_subroutine : require\n"
   5567 											  "\n"
   5568 											  "precision highp float;\n"
   5569 											  "\n"
   5570 											  "void main()\n"
   5571 											  "{\n"
   5572 											  "}\n"
   5573 											  "\n";
   5574 
   5575 	static const GLchar* subroutine_names[][2] = { { "discard_yes", "discard_no" },
   5576 												   { "red_pass_blue_fail", "blue_pass_red_fail" },
   5577 												   { "first_sampler", "second_sampler" },
   5578 												   { "check_equal", "check_not_equal" },
   5579 												   { "test_with_discard", "test_without_discard" } };
   5580 	static const GLuint n_subroutine_types = sizeof(subroutine_names) / sizeof(subroutine_names[0]);
   5581 
   5582 	static const GLchar* subroutine_uniform_names[] = { "discard_fragment", "set_global_colors", "sample_texture",
   5583 														"compare", "test" };
   5584 	static const GLuint n_subroutine_uniform_names =
   5585 		sizeof(subroutine_uniform_names) / sizeof(subroutine_uniform_names[0]);
   5586 
   5587 	static const GLchar* uniform_names[] = {
   5588 		"sampler_1", "sampler_2",
   5589 	};
   5590 	static const GLuint n_uniform_names = sizeof(uniform_names) / sizeof(uniform_names[0]);
   5591 
   5592 	/* Colors */
   5593 	static const GLubyte blue_color[4]  = { 0, 0, 255, 255 };
   5594 	static const GLubyte clean_color[4] = { 0, 0, 0, 0 };
   5595 	static const GLubyte red_color[4]   = { 255, 0, 0, 255 };
   5596 
   5597 	/* Configurations */
   5598 	static const testConfiguration test_configurations[] = {
   5599 		testConfiguration(
   5600 			"Expect red color from 1st sampler", red_color, 1 /* discard_fragment  : discard_no         */,
   5601 			0 /* set_global_colors : red_pass_blue_fail */, 0 /* sample_texture    : first_sampler      */,
   5602 			0 /* compare           : check_equal        */, 0 /* test              : test_with_discard  */, 1 /* red */,
   5603 			0 /* blue */),
   5604 
   5605 		testConfiguration(
   5606 			"Test \"without discard\" option, expect no blue color from 2nd sampler", blue_color,
   5607 			0 /* discard_fragment  : discard_yes           */, 1 /* set_global_colors : blue_pass_red_fail    */,
   5608 			1 /* sample_texture    : second_sampler        */, 1 /* compare           : check_not_equal       */,
   5609 			1 /* test              : test_without_discard  */, 0 /* blue */, 1 /* red */),
   5610 
   5611 		testConfiguration("Fragment shoud be discarded", clean_color, 0 /* discard_fragment  : discard_yes        */,
   5612 						  0 /* set_global_colors : red_pass_blue_fail */,
   5613 						  0 /* sample_texture    : first_sampler      */,
   5614 						  0 /* compare           : check_equal        */,
   5615 						  0 /* test              : test_with_discard  */, 1 /* red */, 0 /* blue */),
   5616 
   5617 		testConfiguration(
   5618 			"Expect blue color from 1st sampler", blue_color, 1 /* discard_fragment  : discard_no         */,
   5619 			1 /* set_global_colors : blue_pass_red_fail */, 0 /* sample_texture    : first_sampler      */,
   5620 			0 /* compare           : check_equal        */, 0 /* test              : test_with_discard  */,
   5621 			0 /* blue */, 1 /* red */),
   5622 
   5623 		testConfiguration(
   5624 			"Expect red color from 2nd sampler", red_color, 1 /* discard_fragment  : discard_no         */,
   5625 			0 /* set_global_colors : red_pass_blue_fail */, 1 /* sample_texture    : second_sampler     */,
   5626 			0 /* compare           : check_equal        */, 0 /* test              : test_with_discard  */,
   5627 			0 /* blue */, 1 /* red */),
   5628 
   5629 		testConfiguration(
   5630 			"Expect no blue color from 2nd sampler", blue_color, 1 /* discard_fragment  : discard_no         */,
   5631 			1 /* set_global_colors : blue_pass_red_fail */, 1 /* sample_texture    : second_sampler     */,
   5632 			1 /* compare           : check_not_equal    */, 0 /* test              : test_with_discard  */,
   5633 			0 /* blue */, 1 /* red */),
   5634 	};
   5635 	static const GLuint n_test_cases = sizeof(test_configurations) / sizeof(test_configurations[0]);
   5636 
   5637 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   5638 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   5639 	{
   5640 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   5641 	}
   5642 
   5643 	/* GL objects */
   5644 	Utils::texture	 blue_texture(m_context);
   5645 	Utils::texture	 color_texture(m_context);
   5646 	Utils::framebuffer framebuffer(m_context);
   5647 	Utils::program	 program(m_context);
   5648 	Utils::texture	 red_texture(m_context);
   5649 	Utils::vertexArray vao(m_context);
   5650 
   5651 	/* Init GL objects */
   5652 	program.build(0 /* cs */, fragment_shader_code /* fs */, geometry_shader_code /* gs */, 0 /* tcs */, 0 /* test */,
   5653 				  vertex_shader_code, 0 /* varying_names */, 0 /* n_varyings */);
   5654 
   5655 	program.use();
   5656 
   5657 	vao.generate();
   5658 	vao.bind();
   5659 
   5660 	blue_texture.create(m_texture_width, m_texture_height, GL_RGBA8);
   5661 	color_texture.create(m_texture_width, m_texture_height, GL_RGBA8);
   5662 	red_texture.create(m_texture_width, m_texture_height, GL_RGBA8);
   5663 
   5664 	framebuffer.generate();
   5665 	framebuffer.bind();
   5666 	framebuffer.attachTexture(GL_COLOR_ATTACHMENT0, color_texture.m_id, m_texture_width, m_texture_height);
   5667 
   5668 	/* Get subroutine indices */
   5669 	for (GLuint type = 0; type < n_subroutine_types; ++type)
   5670 	{
   5671 		m_subroutine_indices[type][0] = program.getSubroutineIndex(subroutine_names[type][0], GL_FRAGMENT_SHADER);
   5672 		m_subroutine_indices[type][1] = program.getSubroutineIndex(subroutine_names[type][1], GL_FRAGMENT_SHADER);
   5673 	}
   5674 
   5675 	/* Get subroutine uniform locations */
   5676 	for (GLuint uniform = 0; uniform < n_subroutine_uniform_names; ++uniform)
   5677 	{
   5678 		m_subroutine_uniform_locations[uniform] =
   5679 			program.getSubroutineUniformLocation(subroutine_uniform_names[uniform], GL_FRAGMENT_SHADER);
   5680 	}
   5681 
   5682 	/* Get uniform locations */
   5683 	for (GLuint i = 0; i < n_uniform_names; ++i)
   5684 	{
   5685 		m_uniform_locations[i] = program.getUniformLocation(uniform_names[i]);
   5686 	}
   5687 
   5688 	/* Prepare textures */
   5689 	fillTexture(blue_texture, blue_color);
   5690 	fillTexture(color_texture, clean_color);
   5691 	fillTexture(red_texture, red_color);
   5692 
   5693 	m_source_textures[0] = blue_texture.m_id;
   5694 	m_source_textures[1] = red_texture.m_id;
   5695 
   5696 	framebuffer.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
   5697 
   5698 	/* Test */
   5699 	bool result = true;
   5700 	for (GLuint i = 0; i < n_test_cases; ++i)
   5701 	{
   5702 		/* Clean output texture */
   5703 		framebuffer.clear(GL_COLOR_BUFFER_BIT);
   5704 
   5705 		/* Execute test */
   5706 		if (false == testDraw(test_configurations[i].m_routines, test_configurations[i].m_samplers,
   5707 							  test_configurations[i].m_expected_color, color_texture))
   5708 		{
   5709 			m_context.getTestContext().getLog()
   5710 				<< tcu::TestLog::Message << "Error. Failure for configuration: " << test_configurations[i].m_description
   5711 				<< tcu::TestLog::EndMessage;
   5712 
   5713 			result = false;
   5714 		}
   5715 	}
   5716 
   5717 	/* Set result */
   5718 	if (true == result)
   5719 	{
   5720 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5721 	}
   5722 	else
   5723 	{
   5724 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5725 	}
   5726 
   5727 	/* Done */
   5728 	return tcu::TestNode::STOP;
   5729 }
   5730 
   5731 /** Fill texture with specified color
   5732  *
   5733  * @param texture Texture instance
   5734  * @param color   Color
   5735  **/
   5736 void FunctionalTest11::fillTexture(Utils::texture& texture, const glw::GLubyte color[4]) const
   5737 {
   5738 	std::vector<GLubyte> texture_data;
   5739 
   5740 	/* Prepare texture data */
   5741 	texture_data.resize(m_texture_width * m_texture_height * 4);
   5742 
   5743 	for (GLuint y = 0; y < m_texture_height; ++y)
   5744 	{
   5745 		const GLuint line_offset = y * m_texture_width * 4;
   5746 
   5747 		for (GLuint x = 0; x < m_texture_width; ++x)
   5748 		{
   5749 			const GLuint point_offset = x * 4 + line_offset;
   5750 
   5751 			texture_data[point_offset + 0] = color[0]; /* red */
   5752 			texture_data[point_offset + 1] = color[1]; /* green */
   5753 			texture_data[point_offset + 2] = color[2]; /* blue */
   5754 			texture_data[point_offset + 3] = color[3]; /* alpha */
   5755 		}
   5756 	}
   5757 
   5758 	texture.update(m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
   5759 }
   5760 
   5761 /** Execute draw call and verify results
   5762  *
   5763  * @param routine_configuration Configurations of routines to be used
   5764  * @param sampler_configuration Configuration of textures to be bound to samplers
   5765  * @param expected_color        Expected color of result image
   5766  *
   5767  * @return true if result image is filled with expected color, false otherwise
   5768  **/
   5769 bool FunctionalTest11::testDraw(const glw::GLuint routine_configuration[5], const glw::GLuint sampler_configuration[2],
   5770 								const glw::GLubyte expected_color[4], Utils::texture& color_texture) const
   5771 {
   5772 	const glw::Functions& gl					= m_context.getRenderContext().getFunctions();
   5773 	static const GLint	n_samplers			= 2;
   5774 	static const GLint	n_subroutine_uniforms = 5;
   5775 	GLuint				  subroutine_indices[5];
   5776 
   5777 	/* Set samplers */
   5778 	for (GLuint i = 0; i < n_samplers; ++i)
   5779 	{
   5780 		const GLuint location = m_uniform_locations[i];
   5781 		const GLuint texture  = m_source_textures[sampler_configuration[i]];
   5782 
   5783 		gl.activeTexture(GL_TEXTURE0 + i);
   5784 		GLU_EXPECT_NO_ERROR(gl.getError(), "ActiveTexture");
   5785 
   5786 		gl.bindTexture(GL_TEXTURE_2D, texture);
   5787 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   5788 
   5789 		gl.uniform1i(location, i);
   5790 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
   5791 	}
   5792 
   5793 	gl.activeTexture(GL_TEXTURE0 + 0);
   5794 
   5795 	/* Set subroutine uniforms */
   5796 	for (GLuint i = 0; i < n_subroutine_uniforms; ++i)
   5797 	{
   5798 		const GLuint location = m_subroutine_uniform_locations[i];
   5799 		const GLuint routine  = routine_configuration[i];
   5800 
   5801 		subroutine_indices[location] = m_subroutine_indices[i][routine];
   5802 	}
   5803 
   5804 	gl.uniformSubroutinesuiv(GL_FRAGMENT_SHADER, 5, subroutine_indices);
   5805 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   5806 
   5807 	/* Draw */
   5808 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   5809 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
   5810 
   5811 	/* Capture result */
   5812 	std::vector<GLubyte> captured_data;
   5813 	captured_data.resize(m_texture_width * m_texture_height * 4);
   5814 
   5815 	color_texture.get(GL_RGBA, GL_UNSIGNED_BYTE, &captured_data[0]);
   5816 
   5817 	/* Verify result */
   5818 	for (GLuint y = 0; y < m_texture_height; ++y)
   5819 	{
   5820 		const GLuint line_offset = y * m_texture_width * 4;
   5821 
   5822 		for (GLuint x = 0; x < m_texture_width; ++x)
   5823 		{
   5824 			const GLuint point_offset   = x * 4 + line_offset;
   5825 			bool		 is_as_expected = true;
   5826 
   5827 			is_as_expected = is_as_expected && (expected_color[0] == captured_data[point_offset + 0]); /* red */
   5828 			is_as_expected = is_as_expected && (expected_color[1] == captured_data[point_offset + 1]); /* green */
   5829 			is_as_expected = is_as_expected && (expected_color[2] == captured_data[point_offset + 2]); /* blue */
   5830 			is_as_expected = is_as_expected && (expected_color[3] == captured_data[point_offset + 3]); /* alpha */
   5831 
   5832 			if (false == is_as_expected)
   5833 			{
   5834 				return false;
   5835 			}
   5836 		}
   5837 	}
   5838 
   5839 	/* Done */
   5840 	return true;
   5841 }
   5842 
   5843 /* Constatns used by FunctionalTest12 */
   5844 const glw::GLuint FunctionalTest12::m_texture_height = 16;
   5845 const glw::GLuint FunctionalTest12::m_texture_width  = 16;
   5846 
   5847 /** Constructor
   5848  *
   5849  * @param context CTS context
   5850  **/
   5851 FunctionalTest12::FunctionalTest12(deqp::Context& context)
   5852 	: TestCase(context, "ssbo_atomic_image_load_store",
   5853 			   "Verify that SSBO, atomic counters and image load store work as expected")
   5854 	, m_left_image(0)
   5855 	, m_right_image(0)
   5856 {
   5857 }
   5858 
   5859 /** Execute test
   5860  *
   5861  * @return tcu::TestNode::STOP
   5862  **/
   5863 tcu::TestNode::IterateResult FunctionalTest12::iterate()
   5864 {
   5865 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   5866 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   5867 	{
   5868 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   5869 	}
   5870 
   5871 	bool result = true;
   5872 
   5873 	/* Test atomic counters */
   5874 	if (true == m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_atomic_counters"))
   5875 	{
   5876 		if (false == testAtomic())
   5877 		{
   5878 			result = false;
   5879 		}
   5880 	}
   5881 
   5882 	/* Test shader storage buffer */
   5883 	if (true == m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_storage_buffer_object"))
   5884 	{
   5885 		if (false == testSSBO())
   5886 		{
   5887 			result = false;
   5888 		}
   5889 	}
   5890 
   5891 	/* Test image load store */
   5892 	if (true == m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_image_load_store"))
   5893 	{
   5894 		if (false == testImage())
   5895 		{
   5896 			result = false;
   5897 		}
   5898 	}
   5899 
   5900 	/* Set result */
   5901 	if (true == result)
   5902 	{
   5903 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5904 	}
   5905 	else
   5906 	{
   5907 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5908 	}
   5909 
   5910 	/* Done */
   5911 	return tcu::TestNode::STOP;
   5912 }
   5913 
   5914 /** Fill texture with specified color
   5915  *
   5916  * @param texture Texture instance
   5917  * @param color   Color
   5918  **/
   5919 void FunctionalTest12::fillTexture(Utils::texture& texture, const glw::GLuint color[4]) const
   5920 {
   5921 	std::vector<GLuint> texture_data;
   5922 
   5923 	/* Prepare texture data */
   5924 	texture_data.resize(m_texture_width * m_texture_height * 4);
   5925 
   5926 	for (GLuint y = 0; y < m_texture_height; ++y)
   5927 	{
   5928 		const GLuint line_offset = y * m_texture_width * 4;
   5929 
   5930 		for (GLuint x = 0; x < m_texture_width; ++x)
   5931 		{
   5932 			const GLuint point_offset = x * 4 + line_offset;
   5933 
   5934 			texture_data[point_offset + 0] = color[0]; /* red */
   5935 			texture_data[point_offset + 1] = color[1]; /* green */
   5936 			texture_data[point_offset + 2] = color[2]; /* blue */
   5937 			texture_data[point_offset + 3] = color[3]; /* alpha */
   5938 		}
   5939 	}
   5940 
   5941 	texture.update(m_texture_width, m_texture_height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &texture_data[0]);
   5942 }
   5943 
   5944 /** Test atomic counters
   5945  *
   5946  * @return true if test pass, false otherwise
   5947  **/
   5948 bool FunctionalTest12::testAtomic()
   5949 {
   5950 	static const GLchar* fragment_shader_code = "#version 400 core\n"
   5951 												"#extension GL_ARB_shader_atomic_counters : require\n"
   5952 												"#extension GL_ARB_shader_subroutine      : require\n"
   5953 												"\n"
   5954 												"precision highp float;\n"
   5955 												"\n"
   5956 												"layout(location = 0) out uint out_color;\n"
   5957 												"\n"
   5958 												"layout(binding = 0, offset = 8) uniform atomic_uint one;\n"
   5959 												"layout(binding = 0, offset = 4) uniform atomic_uint two;\n"
   5960 												"layout(binding = 0, offset = 0) uniform atomic_uint three;\n"
   5961 												"\n"
   5962 												"subroutine void atomic_routine(void)\n;"
   5963 												"\n"
   5964 												"subroutine(atomic_routine) void increment_two(void)\n"
   5965 												"{\n"
   5966 												"    out_color = atomicCounterIncrement(two);\n"
   5967 												"}\n"
   5968 												"\n"
   5969 												"subroutine(atomic_routine) void decrement_three(void)\n"
   5970 												"{\n"
   5971 												"    out_color = atomicCounterDecrement(three);\n"
   5972 												"}\n"
   5973 												"\n"
   5974 												"subroutine(atomic_routine) void read_one(void)\n"
   5975 												"{\n"
   5976 												"    out_color = atomicCounter(one);\n"
   5977 												"}\n"
   5978 												"\n"
   5979 												"subroutine uniform atomic_routine routine;\n"
   5980 												"\n"
   5981 												"void main()\n"
   5982 												"{\n"
   5983 												"    routine();\n"
   5984 												"}\n"
   5985 												"\n";
   5986 
   5987 	static const GLchar* geometry_shader_code = "#version 400 core\n"
   5988 												"#extension GL_ARB_shader_subroutine : require\n"
   5989 												"\n"
   5990 												"precision highp float;\n"
   5991 												"\n"
   5992 												"layout(points)                           in;\n"
   5993 												"layout(triangle_strip, max_vertices = 4) out;\n"
   5994 												"\n"
   5995 												"void main()\n"
   5996 												"{\n"
   5997 												"    gl_Position = vec4(-1, -1, 0, 1);\n"
   5998 												"    EmitVertex();\n"
   5999 												"    \n"
   6000 												"    gl_Position = vec4(-1,  1, 0, 1);\n"
   6001 												"    EmitVertex();\n"
   6002 												"    \n"
   6003 												"    gl_Position = vec4( 1, -1, 0, 1);\n"
   6004 												"    EmitVertex();\n"
   6005 												"    \n"
   6006 												"    gl_Position = vec4( 1,  1, 0, 1);\n"
   6007 												"    EmitVertex();\n"
   6008 												"    \n"
   6009 												"    EndPrimitive();\n"
   6010 												"}\n"
   6011 												"\n";
   6012 
   6013 	static const GLchar* vertex_shader_code = "#version 400 core\n"
   6014 											  "#extension GL_ARB_shader_subroutine : require\n"
   6015 											  "\n"
   6016 											  "precision highp float;\n"
   6017 											  "\n"
   6018 											  "void main()\n"
   6019 											  "{\n"
   6020 											  "}\n"
   6021 											  "\n";
   6022 
   6023 	static const GLchar* subroutine_names[] = { "increment_two", "decrement_three", "read_one" };
   6024 
   6025 	/* Test data */
   6026 	static const glw::GLuint atomic_buffer_data[] = { m_texture_width * m_texture_height,
   6027 													  m_texture_width * m_texture_height,
   6028 													  m_texture_width * m_texture_height };
   6029 
   6030 	static const glw::GLuint expected_incremented_two[] = { atomic_buffer_data[0], 2 * atomic_buffer_data[1],
   6031 															atomic_buffer_data[2] };
   6032 
   6033 	static const glw::GLuint expected_decremented_three[] = { 0, expected_incremented_two[1],
   6034 															  expected_incremented_two[2] };
   6035 
   6036 	static const glw::GLuint expected_read_one[] = { expected_decremented_three[0], expected_decremented_three[1],
   6037 													 expected_decremented_three[2] };
   6038 
   6039 	/* GL objects */
   6040 	Utils::buffer	  atomic_buffer(m_context);
   6041 	Utils::texture	 color_texture(m_context);
   6042 	Utils::framebuffer framebuffer(m_context);
   6043 	Utils::program	 program(m_context);
   6044 	Utils::vertexArray vao(m_context);
   6045 
   6046 	/* Init GL objects */
   6047 	program.build(0 /* cs */, fragment_shader_code /* fs */, geometry_shader_code /* gs */, 0 /* tcs */, 0 /* test */,
   6048 				  vertex_shader_code, 0 /* varying_names */, 0 /* n_varyings */);
   6049 
   6050 	program.use();
   6051 
   6052 	vao.generate();
   6053 	vao.bind();
   6054 
   6055 	color_texture.create(m_texture_width, m_texture_height, GL_R32UI);
   6056 
   6057 	atomic_buffer.generate();
   6058 	atomic_buffer.update(GL_ATOMIC_COUNTER_BUFFER, sizeof(atomic_buffer_data), (GLvoid*)atomic_buffer_data,
   6059 						 GL_STATIC_DRAW);
   6060 	atomic_buffer.bindRange(GL_ATOMIC_COUNTER_BUFFER, 0 /* index */, 0 /* offset */, sizeof(atomic_buffer_data));
   6061 
   6062 	framebuffer.generate();
   6063 	framebuffer.bind();
   6064 	framebuffer.attachTexture(GL_COLOR_ATTACHMENT0, color_texture.m_id, m_texture_width, m_texture_height);
   6065 	framebuffer.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
   6066 	framebuffer.clear(GL_COLOR_BUFFER_BIT);
   6067 
   6068 	/* Subroutine indices */
   6069 	GLuint increment_two   = program.getSubroutineIndex(subroutine_names[0], GL_FRAGMENT_SHADER);
   6070 	GLuint decrement_three = program.getSubroutineIndex(subroutine_names[1], GL_FRAGMENT_SHADER);
   6071 	GLuint read_one		   = program.getSubroutineIndex(subroutine_names[2], GL_FRAGMENT_SHADER);
   6072 
   6073 	/* Test */
   6074 	bool result = true;
   6075 
   6076 	if (false == testAtomicDraw(increment_two, expected_incremented_two))
   6077 	{
   6078 		result = false;
   6079 	}
   6080 
   6081 	if (false == testAtomicDraw(decrement_three, expected_decremented_three))
   6082 	{
   6083 		result = false;
   6084 	}
   6085 
   6086 	if (false == testAtomicDraw(read_one, expected_read_one))
   6087 	{
   6088 		result = false;
   6089 	}
   6090 
   6091 	/* Done */
   6092 	return result;
   6093 }
   6094 
   6095 /** Execture draw call and verify results
   6096  *
   6097  * @param subroutine_index Index of subroutine that shall be used during draw call
   6098  * @param expected_results Expected results
   6099  *
   6100  * @return true if results are as expected, false otherwise
   6101  **/
   6102 bool FunctionalTest12::testAtomicDraw(GLuint subroutine_index, const GLuint expected_results[3]) const
   6103 {
   6104 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6105 
   6106 	/* Set subroutine uniforms */
   6107 	gl.uniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &subroutine_index);
   6108 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   6109 
   6110 	/* Draw */
   6111 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   6112 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
   6113 
   6114 	/* Capture results */
   6115 	GLuint* atomic_results = (GLuint*)gl.mapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_READ_ONLY);
   6116 	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
   6117 
   6118 	/* Verify */
   6119 	bool result = (0 == memcmp(expected_results, atomic_results, 3 * sizeof(GLuint)));
   6120 
   6121 	if (false == result)
   6122 	{
   6123 		m_context.getTestContext().getLog()
   6124 			<< tcu::TestLog::Message << "Error. Invalid result. "
   6125 			<< "Result: [ " << atomic_results[0] << ", " << atomic_results[1] << ", " << atomic_results[2] << " ] "
   6126 			<< "Expected: [ " << expected_results[0] << ", " << expected_results[1] << ", " << expected_results[2]
   6127 			<< " ]" << tcu::TestLog::EndMessage;
   6128 	}
   6129 
   6130 	/* Unmap buffer */
   6131 	gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
   6132 	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
   6133 
   6134 	/* Done */
   6135 	return result;
   6136 }
   6137 
   6138 /** Test image load store
   6139  *
   6140  * @return true if test pass, false otherwise
   6141  **/
   6142 bool FunctionalTest12::testImage()
   6143 {
   6144 	static const GLchar* fragment_shader_code =
   6145 		"#version 400 core\n"
   6146 		"#extension GL_ARB_shader_image_load_store : require\n"
   6147 		"#extension GL_ARB_shader_subroutine       : require\n"
   6148 		"\n"
   6149 		"precision highp float;\n"
   6150 		"\n"
   6151 		"layout(location = 0) out uvec4 out_color;\n"
   6152 		"\n"
   6153 		"layout(rgba32ui) uniform uimage2D left_image;\n"
   6154 		"layout(rgba32ui) uniform uimage2D right_image;\n"
   6155 		"\n"
   6156 		"subroutine void image_routine(void);\n"
   6157 		"\n"
   6158 		"subroutine(image_routine) void left_to_right(void)\n"
   6159 		"{\n"
   6160 		"    out_color = imageLoad (left_image,  ivec2(gl_FragCoord.xy));\n"
   6161 		"                imageStore(right_image, ivec2(gl_FragCoord.xy), out_color);\n"
   6162 		"}\n"
   6163 		"\n"
   6164 		"subroutine(image_routine) void right_to_left(void)\n"
   6165 		"{\n"
   6166 		"    out_color = imageLoad (right_image, ivec2(gl_FragCoord.xy));\n"
   6167 		"                imageStore(left_image,  ivec2(gl_FragCoord.xy), out_color);\n"
   6168 		"}\n"
   6169 		"\n"
   6170 		"subroutine uniform image_routine routine;\n"
   6171 		"\n"
   6172 		"void main()\n"
   6173 		"{\n"
   6174 		"    routine();\n"
   6175 		"}\n"
   6176 		"\n";
   6177 
   6178 	static const GLchar* geometry_shader_code = "#version 400 core\n"
   6179 												"#extension GL_ARB_shader_subroutine : require\n"
   6180 												"\n"
   6181 												"precision highp float;\n"
   6182 												"\n"
   6183 												"layout(points)                           in;\n"
   6184 												"layout(triangle_strip, max_vertices = 4) out;\n"
   6185 												"\n"
   6186 												"void main()\n"
   6187 												"{\n"
   6188 												"    gl_Position = vec4(-1, -1, 0, 1);\n"
   6189 												"    EmitVertex();\n"
   6190 												"    \n"
   6191 												"    gl_Position = vec4(-1,  1, 0, 1);\n"
   6192 												"    EmitVertex();\n"
   6193 												"    \n"
   6194 												"    gl_Position = vec4( 1, -1, 0, 1);\n"
   6195 												"    EmitVertex();\n"
   6196 												"    \n"
   6197 												"    gl_Position = vec4( 1,  1, 0, 1);\n"
   6198 												"    EmitVertex();\n"
   6199 												"    \n"
   6200 												"    EndPrimitive();\n"
   6201 												"}\n"
   6202 												"\n";
   6203 
   6204 	static const GLchar* vertex_shader_code = "#version 400 core\n"
   6205 											  "#extension GL_ARB_shader_subroutine : require\n"
   6206 											  "\n"
   6207 											  "precision highp float;\n"
   6208 											  "\n"
   6209 											  "void main()\n"
   6210 											  "{\n"
   6211 											  "}\n"
   6212 											  "\n";
   6213 
   6214 	static const GLchar* subroutine_names[] = { "left_to_right", "right_to_left" };
   6215 
   6216 	static const GLchar* uniform_names[] = { "left_image", "right_image" };
   6217 
   6218 	/* Test data */
   6219 	static const GLuint blue_color[4]  = { 0, 0, 255, 255 };
   6220 	static const GLuint clean_color[4] = { 16, 32, 64, 128 };
   6221 	static const GLuint red_color[4]   = { 255, 0, 0, 255 };
   6222 
   6223 	/* GL objects */
   6224 	Utils::texture	 blue_texture(m_context);
   6225 	Utils::texture	 destination_texture(m_context);
   6226 	Utils::texture	 color_texture(m_context);
   6227 	Utils::framebuffer framebuffer(m_context);
   6228 	Utils::program	 program(m_context);
   6229 	Utils::texture	 red_texture(m_context);
   6230 	Utils::vertexArray vao(m_context);
   6231 
   6232 	/* Init GL objects */
   6233 	program.build(0 /* cs */, fragment_shader_code /* fs */, geometry_shader_code /* gs */, 0 /* tcs */, 0 /* test */,
   6234 				  vertex_shader_code, 0 /* varying_names */, 0 /* n_varyings */);
   6235 
   6236 	program.use();
   6237 
   6238 	vao.generate();
   6239 	vao.bind();
   6240 
   6241 	blue_texture.create(m_texture_width, m_texture_height, GL_RGBA32UI);
   6242 	destination_texture.create(m_texture_width, m_texture_height, GL_RGBA32UI);
   6243 	color_texture.create(m_texture_width, m_texture_height, GL_RGBA32UI);
   6244 	red_texture.create(m_texture_width, m_texture_height, GL_RGBA32UI);
   6245 
   6246 	fillTexture(blue_texture, blue_color);
   6247 	fillTexture(destination_texture, clean_color);
   6248 	fillTexture(red_texture, red_color);
   6249 
   6250 	framebuffer.generate();
   6251 	framebuffer.bind();
   6252 	framebuffer.attachTexture(GL_COLOR_ATTACHMENT0, color_texture.m_id, m_texture_width, m_texture_height);
   6253 	framebuffer.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
   6254 	framebuffer.clear(GL_COLOR_BUFFER_BIT);
   6255 
   6256 	/* Subroutine indices */
   6257 	GLuint left_to_right = program.getSubroutineIndex(subroutine_names[0], GL_FRAGMENT_SHADER);
   6258 	GLuint right_to_left = program.getSubroutineIndex(subroutine_names[1], GL_FRAGMENT_SHADER);
   6259 
   6260 	/* Uniform locations */
   6261 	m_left_image  = program.getUniformLocation(uniform_names[0]);
   6262 	m_right_image = program.getUniformLocation(uniform_names[1]);
   6263 
   6264 	/* Test */
   6265 	bool result = true;
   6266 
   6267 	if (false == testImageDraw(left_to_right, blue_texture, destination_texture, blue_color, blue_color))
   6268 	{
   6269 		result = false;
   6270 	}
   6271 
   6272 	if (false == testImageDraw(left_to_right, red_texture, destination_texture, red_color, red_color))
   6273 	{
   6274 		result = false;
   6275 	}
   6276 
   6277 	if (false == testImageDraw(right_to_left, destination_texture, blue_texture, blue_color, blue_color))
   6278 	{
   6279 		result = false;
   6280 	}
   6281 
   6282 	if (false == testImageDraw(right_to_left, destination_texture, red_texture, red_color, red_color))
   6283 	{
   6284 		result = false;
   6285 	}
   6286 
   6287 	if (false == testImageDraw(left_to_right, blue_texture, red_texture, blue_color, blue_color))
   6288 	{
   6289 		result = false;
   6290 	}
   6291 
   6292 	/* Done */
   6293 	return result;
   6294 }
   6295 
   6296 /** Execute draw call and verifies results
   6297  *
   6298  * @param subroutine_index     Index of subroutine that shall be used during draw call
   6299  * @param left                 "Left" texture
   6300  * @param right                "Right" texture
   6301  * @param expected_left_color  Expected color of "left" texture
   6302  * @param expected_right_color Expected color of "right" texture
   6303  *
   6304  * @return true if verification result is positive, false otherwise
   6305  **/
   6306 bool FunctionalTest12::testImageDraw(GLuint subroutine_index, Utils::texture& left, Utils::texture& right,
   6307 									 const GLuint expected_left_color[4], const GLuint expected_right_color[4]) const
   6308 {
   6309 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6310 
   6311 	/* Set subroutine uniforms */
   6312 	gl.uniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &subroutine_index);
   6313 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   6314 
   6315 	/* Set up image units */
   6316 	gl.uniform1i(m_left_image, 0);
   6317 	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
   6318 
   6319 	gl.uniform1i(m_right_image, 1);
   6320 	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
   6321 
   6322 	gl.bindImageTexture(0, left.m_id, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI);
   6323 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
   6324 
   6325 	gl.bindImageTexture(1, right.m_id, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI);
   6326 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
   6327 
   6328 	/* Draw */
   6329 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   6330 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
   6331 
   6332 	/* Verify results */
   6333 	bool result = true;
   6334 
   6335 	if (false == verifyTexture(left, expected_left_color))
   6336 	{
   6337 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   6338 											<< "Error. Invalid result. Left texture is filled with wrong color."
   6339 											<< tcu::TestLog::EndMessage;
   6340 		result = false;
   6341 	}
   6342 
   6343 	if (false == verifyTexture(right, expected_right_color))
   6344 	{
   6345 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   6346 											<< "Error. Invalid result. Right texture is filled with wrong color."
   6347 											<< tcu::TestLog::EndMessage;
   6348 		result = false;
   6349 	}
   6350 
   6351 	/* Done */
   6352 	return result;
   6353 }
   6354 
   6355 /** Test shader storage buffer
   6356  *
   6357  * @return true if test pass, false otherwise
   6358  **/
   6359 bool FunctionalTest12::testSSBO()
   6360 {
   6361 	static const GLchar* fragment_shader_code = "#version 400 core\n"
   6362 												"#extension GL_ARB_shader_storage_buffer_object : require\n"
   6363 												"#extension GL_ARB_shader_subroutine            : require\n"
   6364 												"\n"
   6365 												"precision highp float;\n"
   6366 												"\n"
   6367 												"layout(location = 0) out uvec4 out_color;\n"
   6368 												"\n"
   6369 												"layout(std140, binding = 0) buffer Buffer\n"
   6370 												"{\n"
   6371 												"    uvec4 entry;\n"
   6372 												"};\n"
   6373 												"\n"
   6374 												"subroutine void ssbo_routine(void)\n;"
   6375 												"\n"
   6376 												"subroutine(ssbo_routine) void increment(void)\n"
   6377 												"{\n"
   6378 												"    out_color.x = atomicAdd(entry.x, 1);\n"
   6379 												"    out_color.y = atomicAdd(entry.y, 1);\n"
   6380 												"    out_color.z = atomicAdd(entry.z, 1);\n"
   6381 												"    out_color.w = atomicAdd(entry.w, 1);\n"
   6382 												"}\n"
   6383 												"\n"
   6384 												"subroutine(ssbo_routine) void decrement(void)\n"
   6385 												"{\n"
   6386 												"    out_color.x = atomicAdd(entry.x, -1);\n"
   6387 												"    out_color.y = atomicAdd(entry.y, -1);\n"
   6388 												"    out_color.z = atomicAdd(entry.z, -1);\n"
   6389 												"    out_color.w = atomicAdd(entry.w, -1);\n"
   6390 												"}\n"
   6391 												"\n"
   6392 												"subroutine uniform ssbo_routine routine;\n"
   6393 												"\n"
   6394 												"void main()\n"
   6395 												"{\n"
   6396 												"    routine();\n"
   6397 												"}\n"
   6398 												"\n";
   6399 
   6400 	static const GLchar* geometry_shader_code = "#version 400 core\n"
   6401 												"#extension GL_ARB_shader_subroutine : require\n"
   6402 												"\n"
   6403 												"precision highp float;\n"
   6404 												"\n"
   6405 												"layout(points)                           in;\n"
   6406 												"layout(triangle_strip, max_vertices = 4) out;\n"
   6407 												"\n"
   6408 												"void main()\n"
   6409 												"{\n"
   6410 												"    gl_Position = vec4(-1, -1, 0, 1);\n"
   6411 												"    EmitVertex();\n"
   6412 												"    \n"
   6413 												"    gl_Position = vec4(-1,  1, 0, 1);\n"
   6414 												"    EmitVertex();\n"
   6415 												"    \n"
   6416 												"    gl_Position = vec4( 1, -1, 0, 1);\n"
   6417 												"    EmitVertex();\n"
   6418 												"    \n"
   6419 												"    gl_Position = vec4( 1,  1, 0, 1);\n"
   6420 												"    EmitVertex();\n"
   6421 												"    \n"
   6422 												"    EndPrimitive();\n"
   6423 												"}\n"
   6424 												"\n";
   6425 
   6426 	static const GLchar* vertex_shader_code = "#version 400 core\n"
   6427 											  "#extension GL_ARB_shader_subroutine : require\n"
   6428 											  "\n"
   6429 											  "precision highp float;\n"
   6430 											  "\n"
   6431 											  "void main()\n"
   6432 											  "{\n"
   6433 											  "}\n"
   6434 											  "\n";
   6435 
   6436 	static const GLchar* subroutine_names[] = { "increment", "decrement" };
   6437 
   6438 	/* Test data */
   6439 	static const glw::GLuint buffer_data[] = { m_texture_width * m_texture_height + 1,
   6440 											   m_texture_width * m_texture_height + 2,
   6441 											   m_texture_width * m_texture_height + 3,
   6442 											   m_texture_width * m_texture_height + 4 };
   6443 
   6444 	static const glw::GLuint expected_incremented[] = { m_texture_width * m_texture_height + buffer_data[0],
   6445 														m_texture_width * m_texture_height + buffer_data[1],
   6446 														m_texture_width * m_texture_height + buffer_data[2],
   6447 														m_texture_width * m_texture_height + buffer_data[3] };
   6448 
   6449 	static const glw::GLuint expected_decremented[] = { buffer_data[0], buffer_data[1], buffer_data[2],
   6450 														buffer_data[3] };
   6451 
   6452 	/* GL objects */
   6453 	Utils::buffer	  buffer(m_context);
   6454 	Utils::texture	 color_texture(m_context);
   6455 	Utils::framebuffer framebuffer(m_context);
   6456 	Utils::program	 program(m_context);
   6457 	Utils::vertexArray vao(m_context);
   6458 
   6459 	/* Init GL objects */
   6460 	program.build(0 /* cs */, fragment_shader_code /* fs */, geometry_shader_code /* gs */, 0 /* tcs */, 0 /* test */,
   6461 				  vertex_shader_code, 0 /* varying_names */, 0 /* n_varyings */);
   6462 
   6463 	program.use();
   6464 
   6465 	vao.generate();
   6466 	vao.bind();
   6467 
   6468 	color_texture.create(m_texture_width, m_texture_height, GL_RGBA32UI);
   6469 
   6470 	buffer.generate();
   6471 	buffer.update(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), (GLvoid*)buffer_data, GL_STATIC_DRAW);
   6472 	buffer.bindRange(GL_SHADER_STORAGE_BUFFER, 0 /* index */, 0 /* offset */, sizeof(buffer_data));
   6473 
   6474 	framebuffer.generate();
   6475 	framebuffer.bind();
   6476 	framebuffer.attachTexture(GL_COLOR_ATTACHMENT0, color_texture.m_id, m_texture_width, m_texture_height);
   6477 	framebuffer.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
   6478 	framebuffer.clear(GL_COLOR_BUFFER_BIT);
   6479 
   6480 	/* Subroutine indices */
   6481 	GLuint increment = program.getSubroutineIndex(subroutine_names[0], GL_FRAGMENT_SHADER);
   6482 	GLuint decrement = program.getSubroutineIndex(subroutine_names[1], GL_FRAGMENT_SHADER);
   6483 
   6484 	/* Test */
   6485 	bool result = true;
   6486 
   6487 	if (false == testSSBODraw(increment, expected_incremented))
   6488 	{
   6489 		result = false;
   6490 	}
   6491 
   6492 	if (false == testSSBODraw(decrement, expected_decremented))
   6493 	{
   6494 		result = false;
   6495 	}
   6496 
   6497 	/* Done */
   6498 	return result;
   6499 }
   6500 
   6501 /** Execute draw call and verify results
   6502  *
   6503  * @param subroutine_index Index of subroutine that shall be used by draw call
   6504  * @param expected_results Expected results
   6505  *
   6506  *
   6507  **/
   6508 bool FunctionalTest12::testSSBODraw(GLuint subroutine_index, const GLuint expected_results[4]) const
   6509 {
   6510 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6511 
   6512 	/* Set subroutine uniforms */
   6513 	gl.uniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &subroutine_index);
   6514 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   6515 
   6516 	/* Draw */
   6517 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   6518 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
   6519 
   6520 	/* Capture results */
   6521 	GLuint* ssbo_results = (GLuint*)gl.mapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);
   6522 	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
   6523 
   6524 	/* Verify */
   6525 	bool result = (0 == memcmp(expected_results, ssbo_results, 4 * sizeof(GLuint)));
   6526 
   6527 	if (false == result)
   6528 	{
   6529 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result. "
   6530 											<< "Result: [ " << ssbo_results[0] << ", " << ssbo_results[1] << ", "
   6531 											<< ssbo_results[2] << ", " << ssbo_results[3] << " ] "
   6532 											<< "Expected: [ " << expected_results[0] << ", " << expected_results[1]
   6533 											<< ", " << expected_results[2] << ", " << expected_results[3] << " ]"
   6534 											<< tcu::TestLog::EndMessage;
   6535 	}
   6536 
   6537 	/* Unmap buffer */
   6538 	gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
   6539 	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
   6540 
   6541 	/* Done */
   6542 	return result;
   6543 }
   6544 
   6545 /** Check if texture is filled with expected color
   6546  *
   6547  * @param texture        Texture instance
   6548  * @param expected_color Expected color
   6549  *
   6550  * @return true if texture is filled with specified color, false otherwise
   6551  **/
   6552 bool FunctionalTest12::verifyTexture(Utils::texture& texture, const GLuint expected_color[4]) const
   6553 {
   6554 	std::vector<GLuint> results;
   6555 	results.resize(m_texture_width * m_texture_height * 4);
   6556 
   6557 	texture.get(GL_RGBA_INTEGER, GL_UNSIGNED_INT, &results[0]);
   6558 
   6559 	for (GLuint y = 0; y < m_texture_height; ++y)
   6560 	{
   6561 		const GLuint line_offset = y * m_texture_width * 4;
   6562 
   6563 		for (GLuint x = 0; x < m_texture_width; ++x)
   6564 		{
   6565 			const GLuint point_offset = line_offset + x * 4;
   6566 			bool		 result		  = true;
   6567 
   6568 			result = result && (results[point_offset + 0] == expected_color[0]);
   6569 			result = result && (results[point_offset + 1] == expected_color[1]);
   6570 			result = result && (results[point_offset + 2] == expected_color[2]);
   6571 			result = result && (results[point_offset + 3] == expected_color[3]);
   6572 
   6573 			if (false == result)
   6574 			{
   6575 				return false;
   6576 			}
   6577 		}
   6578 	}
   6579 
   6580 	return true;
   6581 }
   6582 
   6583 /** Constructor.
   6584  *
   6585  *  @param context Rendering context.
   6586  *
   6587  **/
   6588 FunctionalTest13::FunctionalTest13(deqp::Context& context)
   6589 	: TestCase(context, "subroutines_with_separate_shader_objects",
   6590 			   "Verifies that subroutines work correctly when used in separate "
   6591 			   "shader objects")
   6592 	, m_fbo_id(0)
   6593 	, m_pipeline_id(0)
   6594 	, m_read_buffer(DE_NULL)
   6595 	, m_to_height(4)
   6596 	, m_to_id(0)
   6597 	, m_to_width(4)
   6598 	, m_vao_id(0)
   6599 	, m_has_test_passed(true)
   6600 {
   6601 	memset(m_fs_po_ids, 0, sizeof(m_fs_po_ids));
   6602 	memset(m_gs_po_ids, 0, sizeof(m_gs_po_ids));
   6603 	memset(m_tc_po_ids, 0, sizeof(m_tc_po_ids));
   6604 	memset(m_te_po_ids, 0, sizeof(m_te_po_ids));
   6605 	memset(m_vs_po_ids, 0, sizeof(m_vs_po_ids));
   6606 }
   6607 
   6608 /** Deinitializes all GL objects that may have been created during test
   6609  *  execution, as well as releases all process-side buffers that may have
   6610  *  been allocated during the process.
   6611  *  The function also restores default GL state configuration.
   6612  **/
   6613 void FunctionalTest13::deinit()
   6614 {
   6615 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6616 
   6617 	if (m_fbo_id != 0)
   6618 	{
   6619 		gl.deleteFramebuffers(1, &m_fbo_id);
   6620 
   6621 		m_fbo_id = 0;
   6622 	}
   6623 
   6624 	if (m_pipeline_id != 0)
   6625 	{
   6626 		gl.deleteProgramPipelines(1, &m_pipeline_id);
   6627 
   6628 		m_pipeline_id = 0;
   6629 	}
   6630 
   6631 	if (m_read_buffer != DE_NULL)
   6632 	{
   6633 		delete[] m_read_buffer;
   6634 
   6635 		m_read_buffer = DE_NULL;
   6636 	}
   6637 
   6638 	for (unsigned int n_id = 0; n_id < 2 /* po id variants */; ++n_id)
   6639 	{
   6640 		if (m_fs_po_ids[n_id] != 0)
   6641 		{
   6642 			gl.deleteProgram(m_fs_po_ids[n_id]);
   6643 
   6644 			m_fs_po_ids[n_id] = 0;
   6645 		}
   6646 
   6647 		if (m_gs_po_ids[n_id] != 0)
   6648 		{
   6649 			gl.deleteProgram(m_gs_po_ids[n_id]);
   6650 
   6651 			m_gs_po_ids[n_id] = 0;
   6652 		}
   6653 
   6654 		if (m_tc_po_ids[n_id] != 0)
   6655 		{
   6656 			gl.deleteProgram(m_tc_po_ids[n_id]);
   6657 
   6658 			m_tc_po_ids[n_id] = 0;
   6659 		}
   6660 
   6661 		if (m_te_po_ids[n_id] != 0)
   6662 		{
   6663 			gl.deleteProgram(m_te_po_ids[n_id]);
   6664 
   6665 			m_te_po_ids[n_id] = 0;
   6666 		}
   6667 
   6668 		if (m_vs_po_ids[n_id] != 0)
   6669 		{
   6670 			gl.deleteProgram(m_vs_po_ids[n_id]);
   6671 
   6672 			m_vs_po_ids[n_id] = 0;
   6673 		}
   6674 	} /* for (both shader program object variants) */
   6675 
   6676 	if (m_to_id != 0)
   6677 	{
   6678 		gl.deleteTextures(1, &m_to_id);
   6679 
   6680 		m_to_id = 0;
   6681 	}
   6682 
   6683 	if (m_vao_id != 0)
   6684 	{
   6685 		gl.deleteVertexArrays(1, &m_vao_id);
   6686 
   6687 		m_vao_id = 0;
   6688 	}
   6689 
   6690 	/* Restore default GL_PATCH_VERTICES setting value */
   6691 	gl.patchParameteri(GL_PATCH_VERTICES, 3);
   6692 
   6693 	/* Restore default GL_PACK_ALIGNMENT setting value */
   6694 	gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
   6695 }
   6696 
   6697 /** Retrieves body of a fragment shader that should be used for the test.
   6698  *  The subroutine implementations are slightly changed, depending on the
   6699  *  index of the shader, as specified by the caller.
   6700  *
   6701  *  @param n_id Index of the shader.
   6702  *
   6703  *  @return Requested string.
   6704  **/
   6705 std::string FunctionalTest13::getFragmentShaderBody(unsigned int n_id)
   6706 {
   6707 	std::stringstream result_sstream;
   6708 
   6709 	/* Pre-amble */
   6710 	result_sstream << "#version 400\n"
   6711 					  "\n"
   6712 					  "#extension GL_ARB_shader_subroutine : require\n"
   6713 					  "\n"
   6714 					  /* Sub-routine */
   6715 					  "subroutine void SubroutineFSType(inout vec4 result);\n"
   6716 					  "\n"
   6717 					  "subroutine(SubroutineFSType) void SubroutineFS1(inout vec4 result)\n"
   6718 					  "{\n"
   6719 					  "    result += vec4("
   6720 				   << float(n_id + 1) / 10.0f << ", " << float(n_id + 2) / 10.0f << ", " << float(n_id + 3) / 10.0f
   6721 				   << ", " << float(n_id + 4) / 10.0f
   6722 				   << ");\n"
   6723 					  "}\n"
   6724 					  "subroutine(SubroutineFSType) void SubroutineFS2(inout vec4 result)\n"
   6725 					  "{\n"
   6726 					  "    result += vec4("
   6727 				   << float(n_id + 1) / 20.0f << ", " << float(n_id + 2) / 20.0f << ", " << float(n_id + 3) / 20.0f
   6728 				   << ", " << float(n_id + 4) / 20.0f << ");\n"
   6729 														 "}\n"
   6730 														 "\n"
   6731 														 "subroutine uniform SubroutineFSType function;\n"
   6732 														 "\n"
   6733 														 /* Input block */
   6734 														 "in GS_DATA\n"
   6735 														 "{\n"
   6736 														 "    vec4 data;\n"
   6737 														 "} in_gs;\n"
   6738 														 "\n"
   6739 														 "out vec4 result;\n"
   6740 														 /* main() declaration */
   6741 														 "void main()\n"
   6742 														 "{\n"
   6743 														 "    vec4 data = in_gs.data;\n"
   6744 														 "    function(data);\n"
   6745 														 "\n"
   6746 														 "    result = data;\n"
   6747 														 "}\n";
   6748 
   6749 	return result_sstream.str();
   6750 }
   6751 
   6752 /** Retrieves body of a geometry shader that should be used for the test.
   6753  *  The subroutine implementations are slightly changed, depending on the
   6754  *  index of the shader, as specified by the caller.
   6755  *
   6756  *  @param n_id Index of the shader.
   6757  *
   6758  *  @return Requested string.
   6759  **/
   6760 std::string FunctionalTest13::getGeometryShaderBody(unsigned int n_id)
   6761 {
   6762 	std::stringstream result_sstream;
   6763 
   6764 	/* Pre-amble */
   6765 	result_sstream << "#version 400\n"
   6766 					  "\n"
   6767 					  "#extension GL_ARB_shader_subroutine : require\n"
   6768 					  "\n"
   6769 					  "layout(points)                           in;\n"
   6770 					  "layout(triangle_strip, max_vertices = 4) out;\n"
   6771 					  /* Sub-routine */
   6772 					  "subroutine void SubroutineGSType(inout vec4 result);\n"
   6773 					  "\n"
   6774 					  "subroutine(SubroutineGSType) void SubroutineGS1(inout vec4 result)\n"
   6775 					  "{\n"
   6776 					  "    result += vec4(0, 0, 0, "
   6777 				   << float(n_id + 1) * 0.425f << ");\n"
   6778 												  "}\n"
   6779 												  "subroutine(SubroutineGSType) void SubroutineGS2(inout vec4 result)\n"
   6780 												  "{\n"
   6781 												  "    result += vec4(0, 0, 0, "
   6782 				   << float(n_id + 1) * 0.0425f << ");\n"
   6783 												   "}\n"
   6784 												   "\n"
   6785 												   "subroutine uniform SubroutineGSType function;\n"
   6786 												   "\n"
   6787 												   /* Input block */
   6788 												   "in TE_DATA\n"
   6789 												   "{\n"
   6790 												   "    vec4 data;\n"
   6791 												   "} in_te[];\n"
   6792 												   "\n"
   6793 												   /* Output block */
   6794 												   "out GS_DATA\n"
   6795 												   "{\n"
   6796 												   "    vec4 data;\n"
   6797 												   "} out_gs;\n"
   6798 												   "\n"
   6799 												   "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n"
   6800 												   "out gl_PerVertex { vec4 gl_Position; };\n"
   6801 												   /* main() declaration */
   6802 												   "void main()\n"
   6803 												   "{\n"
   6804 												   "    vec4 data = in_te[0].data;\n"
   6805 												   "\n"
   6806 												   "    function(data);\n"
   6807 												   "\n"
   6808 												   "    gl_Position = vec4(1, -1, 0, 1);\n"
   6809 												   "    out_gs.data = data;\n"
   6810 												   "    EmitVertex();\n"
   6811 												   "\n"
   6812 												   "    gl_Position = vec4(-1, -1, 0, 1);\n"
   6813 												   "    out_gs.data = data;\n"
   6814 												   "    EmitVertex();\n"
   6815 												   "\n"
   6816 												   "    gl_Position = vec4(1, 1, 0, 1);\n"
   6817 												   "    out_gs.data = data;\n"
   6818 												   "    EmitVertex();\n"
   6819 												   "\n"
   6820 												   "    gl_Position = vec4(-1, 1, 0, 1);\n"
   6821 												   "    out_gs.data = data;\n"
   6822 												   "    EmitVertex();\n"
   6823 												   "    EndPrimitive();\n"
   6824 												   "}\n";
   6825 
   6826 	return result_sstream.str();
   6827 }
   6828 
   6829 /** Retrieves body of a tessellation control shader that should be used for the test.
   6830  *  The subroutine implementations are slightly changed, depending on the
   6831  *  index of the shader, as specified by the caller.
   6832  *
   6833  *  @param n_id Index of the shader.
   6834  *
   6835  *  @return Requested string.
   6836  **/
   6837 std::string FunctionalTest13::getTessellationControlShaderBody(unsigned int n_id)
   6838 {
   6839 	std::stringstream result_sstream;
   6840 
   6841 	/* Pre-amble */
   6842 	result_sstream << "#version 400\n"
   6843 					  "\n"
   6844 					  "#extension GL_ARB_shader_subroutine : require\n"
   6845 					  "\n"
   6846 					  "layout(vertices = 4) out;\n"
   6847 					  /* Sub-routine */
   6848 					  "subroutine void SubroutineTCType(inout vec4 result);\n"
   6849 					  "\n"
   6850 					  "subroutine(SubroutineTCType) void SubroutineTC1(inout vec4 result)\n"
   6851 					  "{\n"
   6852 					  "    result += vec4(0, "
   6853 				   << float(n_id + 1) * 0.25f << ", 0, 0);\n"
   6854 												 "}\n"
   6855 												 "subroutine(SubroutineTCType) void SubroutineTC2(inout vec4 result)\n"
   6856 												 "{\n"
   6857 												 "    result += vec4(0, "
   6858 				   << float(n_id + 1) * 0.025f
   6859 				   << ", 0, 0);\n"
   6860 					  "}\n"
   6861 					  "\n"
   6862 					  "subroutine uniform SubroutineTCType function;\n"
   6863 					  "\n"
   6864 					  /* Input block */
   6865 					  "in VS_DATA\n"
   6866 					  "{\n"
   6867 					  "    vec4 data;\n"
   6868 					  "} in_vs[];\n"
   6869 					  "\n"
   6870 					  /* Output block */
   6871 					  "out TC_DATA\n"
   6872 					  "{\n"
   6873 					  "    vec4 data;\n"
   6874 					  "} out_tc[];\n"
   6875 					  "\n"
   6876 					  "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n"
   6877 					  "out gl_PerVertex { vec4 gl_Position; } gl_out[];\n"
   6878 					  /* main() declaration */
   6879 					  "void main()\n"
   6880 					  "{\n"
   6881 					  "    gl_TessLevelOuter[0]                = 1.0;\n"
   6882 					  "    gl_TessLevelOuter[1]                = 1.0;\n"
   6883 					  "    gl_TessLevelOuter[2]                = 1.0;\n"
   6884 					  "    gl_TessLevelOuter[3]                = 1.0;\n"
   6885 					  "    gl_TessLevelInner[0]                = 1.0;\n"
   6886 					  "    gl_TessLevelInner[1]                = 1.0;\n"
   6887 					  "    gl_out[gl_InvocationID].gl_Position = gl_in[0].gl_Position;\n"
   6888 					  "    out_tc[gl_InvocationID].data        = in_vs[0].data;\n"
   6889 					  "\n"
   6890 					  "    function(out_tc[gl_InvocationID].data);\n"
   6891 					  "}\n";
   6892 
   6893 	return result_sstream.str();
   6894 }
   6895 
   6896 /** Retrieves body of a tessellation evaluation shader that should be used for the test.
   6897  *  The subroutine implementations are slightly changed, depending on the
   6898  *  index of the shader, as specified by the caller.
   6899  *
   6900  *  @param n_id Index of the shader.
   6901  *
   6902  *  @return Requested string.
   6903  **/
   6904 std::string FunctionalTest13::getTessellationEvaluationShaderBody(unsigned int n_id)
   6905 {
   6906 	std::stringstream result_sstream;
   6907 
   6908 	/* Pre-amble */
   6909 	result_sstream << "#version 400\n"
   6910 					  "\n"
   6911 					  "#extension GL_ARB_shader_subroutine : require\n"
   6912 					  "\n"
   6913 					  "layout(quads, point_mode) in;\n"
   6914 					  /* Sub-routine */
   6915 					  "subroutine void SubroutineTEType(inout vec4 result);\n"
   6916 					  "\n"
   6917 					  "subroutine(SubroutineTEType) void SubroutineTE1(inout vec4 result)\n"
   6918 					  "{\n"
   6919 					  "    result += vec4(0, 0, "
   6920 				   << float(n_id + 1) * 0.325f << ", 0);\n"
   6921 												  "}\n"
   6922 												  "subroutine(SubroutineTEType) void SubroutineTE2(inout vec4 result)\n"
   6923 												  "{\n"
   6924 												  "    result += vec4(0, 0, "
   6925 				   << float(n_id + 1) * 0.0325f << ", 0);\n"
   6926 												   "}\n"
   6927 												   "\n"
   6928 												   "subroutine uniform SubroutineTEType function;\n"
   6929 												   "\n"
   6930 												   /* Input block */
   6931 												   "in TC_DATA\n"
   6932 												   "{\n"
   6933 												   "    vec4 data;\n"
   6934 												   "} in_tc[];\n"
   6935 												   "\n"
   6936 												   /* Output block */
   6937 												   "out TE_DATA\n"
   6938 												   "{\n"
   6939 												   "    vec4 data;\n"
   6940 												   "} out_te;\n"
   6941 												   "\n"
   6942 												   "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n"
   6943 												   "out gl_PerVertex { vec4 gl_Position; };\n"
   6944 												   /* main() declaration */
   6945 												   "void main()\n"
   6946 												   "{\n"
   6947 												   "    gl_Position = gl_in[0].gl_Position;\n"
   6948 												   "    out_te.data = in_tc[0].data;\n"
   6949 												   "\n"
   6950 												   "    function(out_te.data);\n"
   6951 												   "}\n";
   6952 
   6953 	return result_sstream.str();
   6954 }
   6955 
   6956 /** Retrieves body of a vertex shader that should be used for the test.
   6957  *  The subroutine implementations are slightly changed, depending on the
   6958  *  index of the shader, as specified by the caller.
   6959  *
   6960  *  @param n_id Index of the shader.
   6961  *
   6962  *  @return Requested string.
   6963  **/
   6964 std::string FunctionalTest13::getVertexShaderBody(unsigned int n_id)
   6965 {
   6966 	std::stringstream result_sstream;
   6967 
   6968 	/* Pre-amble */
   6969 	result_sstream << "#version 400\n"
   6970 					  "\n"
   6971 					  "#extension GL_ARB_shader_subroutine : require\n"
   6972 					  "\n"
   6973 					  /* Sub-routine */
   6974 					  "subroutine void SubroutineVSType(inout vec4 result);\n"
   6975 					  "\n"
   6976 					  "subroutine(SubroutineVSType) void SubroutineVS1(inout vec4 result)\n"
   6977 					  "{\n"
   6978 					  "    result += vec4("
   6979 				   << float(n_id + 1) * 0.125f << ", 0, 0, 0);\n"
   6980 												  "}\n"
   6981 												  "subroutine(SubroutineVSType) void SubroutineVS2(inout vec4 result)\n"
   6982 												  "{\n"
   6983 												  "    result += vec4("
   6984 				   << float(n_id + 1) * 0.0125f << ", 0, 0, 0);\n"
   6985 												   "}\n"
   6986 												   "\n"
   6987 												   "subroutine uniform SubroutineVSType function;\n"
   6988 												   "\n"
   6989 												   /* Output block */
   6990 												   "out VS_DATA\n"
   6991 												   "{\n"
   6992 												   "    vec4 data;\n"
   6993 												   "} out_vs;\n"
   6994 												   "\n"
   6995 												   "out gl_PerVertex { vec4 gl_Position; };\n"
   6996 												   /* main() declaration */
   6997 												   "void main()\n"
   6998 												   "{\n"
   6999 												   "    gl_Position = vec4(0, 0, 0, 1);\n"
   7000 												   "    out_vs.data = vec4(0);\n"
   7001 												   "\n"
   7002 												   "    function(out_vs.data);\n"
   7003 												   "\n"
   7004 												   "}\n";
   7005 
   7006 	return result_sstream.str();
   7007 }
   7008 
   7009 /** Initializes all GL objects required to run the test. Also modifies a few
   7010  *  GL states in order for the test to run correctly.
   7011  **/
   7012 void FunctionalTest13::initTest()
   7013 {
   7014 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   7015 
   7016 	/* Set up viewport */
   7017 	gl.viewport(0 /* x */, 0 /* y */, m_to_width, m_to_height);
   7018 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed.");
   7019 
   7020 	/* Make sure no program is used */
   7021 	gl.useProgram(0);
   7022 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   7023 
   7024 	/* Generate a pipeline object */
   7025 	gl.genProgramPipelines(1, &m_pipeline_id);
   7026 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed.");
   7027 
   7028 	gl.bindProgramPipeline(m_pipeline_id);
   7029 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed.");
   7030 
   7031 	/* Initialize all shader programs */
   7032 	for (unsigned int n_id = 0; n_id < 2 /* variants for each shader type */; ++n_id)
   7033 	{
   7034 		std::string fs_body			= getFragmentShaderBody(n_id);
   7035 		const char* fs_body_raw_ptr = fs_body.c_str();
   7036 		std::string gs_body			= getGeometryShaderBody(n_id);
   7037 		const char* gs_body_raw_ptr = gs_body.c_str();
   7038 		std::string tc_body			= getTessellationControlShaderBody(n_id);
   7039 		const char* tc_body_raw_ptr = tc_body.c_str();
   7040 		std::string te_body			= getTessellationEvaluationShaderBody(n_id);
   7041 		const char* te_body_raw_ptr = te_body.c_str();
   7042 		std::string vs_body			= getVertexShaderBody(n_id);
   7043 		const char* vs_body_raw_ptr = vs_body.c_str();
   7044 
   7045 		m_fs_po_ids[n_id] = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1 /* count */, &fs_body_raw_ptr);
   7046 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed.");
   7047 
   7048 		m_gs_po_ids[n_id] = gl.createShaderProgramv(GL_GEOMETRY_SHADER, 1 /* count */, &gs_body_raw_ptr);
   7049 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed.");
   7050 
   7051 		m_tc_po_ids[n_id] = gl.createShaderProgramv(GL_TESS_CONTROL_SHADER, 1 /* count */, &tc_body_raw_ptr);
   7052 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed.");
   7053 
   7054 		m_te_po_ids[n_id] = gl.createShaderProgramv(GL_TESS_EVALUATION_SHADER, 1 /* count */, &te_body_raw_ptr);
   7055 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed.");
   7056 
   7057 		m_vs_po_ids[n_id] = gl.createShaderProgramv(GL_VERTEX_SHADER, 1 /* count */, &vs_body_raw_ptr);
   7058 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed.");
   7059 
   7060 		/* Verify that all shader program objects have been linked successfully */
   7061 		const glw::GLuint po_ids[] = {
   7062 			m_fs_po_ids[n_id], m_gs_po_ids[n_id], m_tc_po_ids[n_id], m_te_po_ids[n_id], m_vs_po_ids[n_id],
   7063 		};
   7064 		const unsigned int n_po_ids = sizeof(po_ids) / sizeof(po_ids[0]);
   7065 
   7066 		for (unsigned int n_po_id = 0; n_po_id < n_po_ids; ++n_po_id)
   7067 		{
   7068 			glw::GLint  link_status = GL_FALSE;
   7069 			glw::GLuint po_id		= po_ids[n_po_id];
   7070 
   7071 			gl.getProgramiv(po_id, GL_LINK_STATUS, &link_status);
   7072 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
   7073 
   7074 			if (link_status != GL_TRUE)
   7075 			{
   7076 				TCU_FAIL("Shader program object linking failed.");
   7077 			}
   7078 		} /* for (all shader program objects) */
   7079 	}	 /* for (both shader program object variants) */
   7080 
   7081 	/* Generate a texture object. We will use the base mip-map as a render-target */
   7082 	gl.genTextures(1, &m_to_id);
   7083 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
   7084 
   7085 	gl.bindTexture(GL_TEXTURE_2D, m_to_id);
   7086 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   7087 
   7088 	gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, GL_RGBA32F, m_to_width, m_to_height);
   7089 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
   7090 
   7091 	/* Generate and configure a FBO we will use for the draw call */
   7092 	gl.genFramebuffers(1, &m_fbo_id);
   7093 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
   7094 
   7095 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
   7096 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
   7097 
   7098 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_id, 0 /* level */);
   7099 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
   7100 
   7101 	/* Generate & bind a VAO */
   7102 	gl.genVertexArrays(1, &m_vao_id);
   7103 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
   7104 
   7105 	gl.bindVertexArray(m_vao_id);
   7106 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
   7107 
   7108 	/* Set up tessellation */
   7109 	gl.patchParameteri(GL_PATCH_VERTICES, 1);
   7110 	GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteri() call failed.");
   7111 
   7112 	/* Set up pixel storage alignment */
   7113 	gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
   7114 	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call failed.");
   7115 
   7116 	/* Allocate enough space to hold color attachment data */
   7117 	m_read_buffer = (unsigned char*)new float[m_to_width * m_to_height * 4 /* rgba */];
   7118 }
   7119 
   7120 /** Executes test iteration.
   7121  *
   7122  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   7123  */
   7124 tcu::TestNode::IterateResult FunctionalTest13::iterate()
   7125 {
   7126 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   7127 
   7128 	/* Do not execute the test if GL_ARB_shader_subroutine and GL_ARB_separate_shader_objects
   7129 	 * are not supported */
   7130 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   7131 	{
   7132 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   7133 	}
   7134 
   7135 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_separate_shader_objects"))
   7136 	{
   7137 		throw tcu::NotSupportedError("GL_ARB_separate_shader_objects is not supported");
   7138 	}
   7139 
   7140 	/* Initialize all GL objects before we continue */
   7141 	initTest();
   7142 
   7143 	/* Iterate over all possible FS/GS/TC/TE/VS permutations */
   7144 	for (int n_shader_permutation = 0; n_shader_permutation < 32 /* 2^5 */; ++n_shader_permutation)
   7145 	{
   7146 		const unsigned int n_fs_idx = ((n_shader_permutation & (1 << 0)) != 0) ? 1 : 0;
   7147 		const unsigned int n_gs_idx = ((n_shader_permutation & (1 << 1)) != 0) ? 1 : 0;
   7148 		const unsigned int n_tc_idx = ((n_shader_permutation & (1 << 2)) != 0) ? 1 : 0;
   7149 		const unsigned int n_te_idx = ((n_shader_permutation & (1 << 3)) != 0) ? 1 : 0;
   7150 		const unsigned int n_vs_idx = ((n_shader_permutation & (1 << 4)) != 0) ? 1 : 0;
   7151 		const unsigned int fs_po_id = m_fs_po_ids[n_fs_idx];
   7152 		const unsigned int gs_po_id = m_gs_po_ids[n_gs_idx];
   7153 		const unsigned int tc_po_id = m_tc_po_ids[n_tc_idx];
   7154 		const unsigned int te_po_id = m_te_po_ids[n_te_idx];
   7155 		const unsigned int vs_po_id = m_vs_po_ids[n_vs_idx];
   7156 
   7157 		/* Configure fragment shader stage */
   7158 		gl.useProgramStages(m_pipeline_id, GL_FRAGMENT_SHADER_BIT, fs_po_id);
   7159 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed for GL_FRAGMENT_SHADER_BIT bit");
   7160 
   7161 		/* Configure geometry shader stage */
   7162 		gl.useProgramStages(m_pipeline_id, GL_GEOMETRY_SHADER_BIT, gs_po_id);
   7163 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed for GL_GEOMETRY_SHADER_BIT bit");
   7164 
   7165 		/* Configure tessellation control shader stage */
   7166 		gl.useProgramStages(m_pipeline_id, GL_TESS_CONTROL_SHADER_BIT, tc_po_id);
   7167 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed for GL_TESS_CONTROL_SHADER_BIT bit");
   7168 
   7169 		/* Configure tessellation evaluation shader stage */
   7170 		gl.useProgramStages(m_pipeline_id, GL_TESS_EVALUATION_SHADER_BIT, te_po_id);
   7171 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed for GL_TESS_EVALUATION_SHADER_BIT bit");
   7172 
   7173 		/* Configure vertex shader stage */
   7174 		gl.useProgramStages(m_pipeline_id, GL_VERTEX_SHADER_BIT, vs_po_id);
   7175 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed for GL_VERTEX_SHADER_BIT bit");
   7176 
   7177 		/* Validate the pipeline */
   7178 		glw::GLint validate_status = GL_FALSE;
   7179 
   7180 		gl.validateProgramPipeline(m_pipeline_id);
   7181 		GLU_EXPECT_NO_ERROR(gl.getError(), "glValidateProgramPipeline() call failed.");
   7182 
   7183 		gl.getProgramPipelineiv(m_pipeline_id, GL_VALIDATE_STATUS, &validate_status);
   7184 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramPipelineiv() call failed.");
   7185 
   7186 		if (validate_status != GL_TRUE)
   7187 		{
   7188 			TCU_FAIL("Program pipeline has not been validated successfully.");
   7189 		}
   7190 
   7191 		/* Retrieve subroutine indices */
   7192 		GLuint fs_subroutine_indices[2]	= { (GLuint)-1 };
   7193 		GLint  fs_subroutine_uniform_index = 0;
   7194 		GLuint gs_subroutine_indices[2]	= { (GLuint)-1 };
   7195 		GLint  gs_subroutine_uniform_index = 0;
   7196 		GLuint tc_subroutine_indices[2]	= { (GLuint)-1 };
   7197 		GLint  tc_subroutine_uniform_index = 0;
   7198 		GLuint te_subroutine_indices[2]	= { (GLuint)-1 };
   7199 		GLint  te_subroutine_uniform_index = 0;
   7200 		GLuint vs_subroutine_indices[2]	= { (GLuint)-1 };
   7201 		GLint  vs_subroutine_uniform_index = 0;
   7202 
   7203 		for (unsigned int n_subroutine = 0; n_subroutine < 2; ++n_subroutine)
   7204 		{
   7205 			std::stringstream fs_subroutine_name_sstream;
   7206 			std::stringstream gs_subroutine_name_sstream;
   7207 			std::stringstream tc_subroutine_name_sstream;
   7208 			std::stringstream te_subroutine_name_sstream;
   7209 			std::stringstream vs_subroutine_name_sstream;
   7210 
   7211 			fs_subroutine_name_sstream << "SubroutineFS" << (n_subroutine + 1);
   7212 			gs_subroutine_name_sstream << "SubroutineGS" << (n_subroutine + 1);
   7213 			tc_subroutine_name_sstream << "SubroutineTC" << (n_subroutine + 1);
   7214 			te_subroutine_name_sstream << "SubroutineTE" << (n_subroutine + 1);
   7215 			vs_subroutine_name_sstream << "SubroutineVS" << (n_subroutine + 1);
   7216 
   7217 			fs_subroutine_indices[n_subroutine] =
   7218 				gl.getSubroutineIndex(fs_po_id, GL_FRAGMENT_SHADER, fs_subroutine_name_sstream.str().c_str());
   7219 			gs_subroutine_indices[n_subroutine] =
   7220 				gl.getSubroutineIndex(gs_po_id, GL_GEOMETRY_SHADER, gs_subroutine_name_sstream.str().c_str());
   7221 			tc_subroutine_indices[n_subroutine] =
   7222 				gl.getSubroutineIndex(tc_po_id, GL_TESS_CONTROL_SHADER, tc_subroutine_name_sstream.str().c_str());
   7223 			te_subroutine_indices[n_subroutine] =
   7224 				gl.getSubroutineIndex(te_po_id, GL_TESS_EVALUATION_SHADER, te_subroutine_name_sstream.str().c_str());
   7225 			vs_subroutine_indices[n_subroutine] =
   7226 				gl.getSubroutineIndex(vs_po_id, GL_VERTEX_SHADER, vs_subroutine_name_sstream.str().c_str());
   7227 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() call(s) failed.");
   7228 
   7229 			if (fs_subroutine_indices[n_subroutine] == (GLuint)-1 ||
   7230 				gs_subroutine_indices[n_subroutine] == (GLuint)-1 ||
   7231 				tc_subroutine_indices[n_subroutine] == (GLuint)-1 ||
   7232 				te_subroutine_indices[n_subroutine] == (GLuint)-1 || vs_subroutine_indices[n_subroutine] == (GLuint)-1)
   7233 			{
   7234 				m_testCtx.getLog() << tcu::TestLog::Message
   7235 								   << "At least one subroutine was not recognized by glGetSubroutineIndex() call. "
   7236 									  "(fs:"
   7237 								   << fs_subroutine_indices[n_subroutine]
   7238 								   << ", gs:" << gs_subroutine_indices[n_subroutine]
   7239 								   << ", tc:" << tc_subroutine_indices[n_subroutine]
   7240 								   << ", te:" << te_subroutine_indices[n_subroutine]
   7241 								   << ", vs:" << vs_subroutine_indices[n_subroutine] << ")."
   7242 								   << tcu::TestLog::EndMessage;
   7243 
   7244 				TCU_FAIL("At least one subroutine was not recognized");
   7245 			}
   7246 		} /* for (both subroutines) */
   7247 
   7248 		/* Retrieve subroutine uniform indices */
   7249 		fs_subroutine_uniform_index = gl.getSubroutineUniformLocation(fs_po_id, GL_FRAGMENT_SHADER, "function");
   7250 		gs_subroutine_uniform_index = gl.getSubroutineUniformLocation(gs_po_id, GL_GEOMETRY_SHADER, "function");
   7251 		tc_subroutine_uniform_index = gl.getSubroutineUniformLocation(tc_po_id, GL_TESS_CONTROL_SHADER, "function");
   7252 		te_subroutine_uniform_index = gl.getSubroutineUniformLocation(te_po_id, GL_TESS_EVALUATION_SHADER, "function");
   7253 		vs_subroutine_uniform_index = gl.getSubroutineUniformLocation(vs_po_id, GL_VERTEX_SHADER, "function");
   7254 
   7255 		if (fs_subroutine_uniform_index == -1 || gs_subroutine_uniform_index == -1 ||
   7256 			tc_subroutine_uniform_index == -1 || te_subroutine_uniform_index == -1 || vs_subroutine_uniform_index == -1)
   7257 		{
   7258 			m_testCtx.getLog() << tcu::TestLog::Message << "At least one subroutine uniform is considered inactive by "
   7259 														   "glGetSubroutineUniformLocation ("
   7260 														   "fs:"
   7261 							   << fs_subroutine_uniform_index << ", gs:" << gs_subroutine_uniform_index
   7262 							   << ", tc:" << tc_subroutine_uniform_index << ", te:" << te_subroutine_uniform_index
   7263 							   << ", vs:" << vs_subroutine_uniform_index << ")." << tcu::TestLog::EndMessage;
   7264 
   7265 			TCU_FAIL("At least one subroutine uniform is considered inactive");
   7266 		}
   7267 
   7268 		/* Check if both subroutines work correctly in each stage */
   7269 		for (int n_subroutine_permutation = 0; n_subroutine_permutation < 32; /* 2^5 */
   7270 			 ++n_subroutine_permutation)
   7271 		{
   7272 			unsigned int n_fs_subroutine = ((n_subroutine_permutation & (1 << 0)) != 0) ? 1 : 0;
   7273 			unsigned int n_gs_subroutine = ((n_subroutine_permutation & (1 << 1)) != 0) ? 1 : 0;
   7274 			unsigned int n_tc_subroutine = ((n_subroutine_permutation & (1 << 2)) != 0) ? 1 : 0;
   7275 			unsigned int n_te_subroutine = ((n_subroutine_permutation & (1 << 3)) != 0) ? 1 : 0;
   7276 			unsigned int n_vs_subroutine = ((n_subroutine_permutation & (1 << 4)) != 0) ? 1 : 0;
   7277 
   7278 			/* Configure subroutine uniforms */
   7279 			struct
   7280 			{
   7281 				glw::GLenum  stage;
   7282 				glw::GLuint  po_id;
   7283 				glw::GLuint* indices;
   7284 			} configurations[] = {
   7285 				{ GL_FRAGMENT_SHADER, fs_po_id, fs_subroutine_indices + n_fs_subroutine },
   7286 				{ GL_GEOMETRY_SHADER, gs_po_id, gs_subroutine_indices + n_gs_subroutine },
   7287 				{ GL_TESS_CONTROL_SHADER, tc_po_id, tc_subroutine_indices + n_tc_subroutine },
   7288 				{ GL_TESS_EVALUATION_SHADER, te_po_id, te_subroutine_indices + n_te_subroutine },
   7289 				{ GL_VERTEX_SHADER, vs_po_id, vs_subroutine_indices + n_vs_subroutine },
   7290 			};
   7291 
   7292 			for (int i = 0; i < 5; ++i)
   7293 			{
   7294 				gl.activeShaderProgram(m_pipeline_id, configurations[i].po_id);
   7295 				GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveShaderProgram() call failed.");
   7296 
   7297 				gl.uniformSubroutinesuiv(configurations[i].stage, 1 /* count */, configurations[i].indices);
   7298 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() call failed.");
   7299 			}
   7300 
   7301 			/* Render a full-screen quad with the pipeline */
   7302 			gl.clear(GL_COLOR_BUFFER_BIT);
   7303 			GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");
   7304 
   7305 			gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
   7306 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   7307 
   7308 			/* Read color attachment's contents */
   7309 			gl.readPixels(0, /* x */
   7310 						  0, /* y */
   7311 						  m_to_width, m_to_height, GL_RGBA, GL_FLOAT, m_read_buffer);
   7312 			GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed.");
   7313 
   7314 			/* Verify the contents */
   7315 			verifyReadBuffer(n_fs_idx, n_fs_subroutine, n_gs_idx, n_gs_subroutine, n_tc_idx, n_tc_subroutine, n_te_idx,
   7316 							 n_te_subroutine, n_vs_idx, n_vs_subroutine);
   7317 		} /* for (all subroutine permutations) */
   7318 	}	 /* for (all program shader object permutations) */
   7319 
   7320 	/** All done */
   7321 	if (m_has_test_passed)
   7322 	{
   7323 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   7324 	}
   7325 	else
   7326 	{
   7327 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   7328 	}
   7329 
   7330 	return STOP;
   7331 }
   7332 
   7333 /** Verifies the data that have been rendered using a pipeline object.
   7334  *  Contents of the data depends on indices of the shaders, as well as
   7335  *  on the subroutines that have been activated for particular iteration.
   7336  *
   7337  *  @param n_fs_id         Index of the fragment shader used for the iteration;
   7338  *  @param n_fs_subroutine Index of the subroutine used in the fragment shader
   7339  *                         for the iteration;
   7340  *  @param n_gs_id         Index of the geometry shader used for the iteration;
   7341  *  @param n_gs_subroutine Index of the subroutine used in the geometry shader
   7342  *                         for the iteration;
   7343  *  @param n_tc_id         Index of the tessellation control shader used for the iteration;
   7344  *  @param n_tc_subroutine Index of the subroutine used in the tessellation control
   7345  *                         shader for the iteration;
   7346  *  @param n_te_id         Index of the tessellation evaluation shader used for the iteration;
   7347  *  @param n_te_subroutine Index of the subroutine used in the tessellation evaluation
   7348  *                         shader for the iteration;
   7349  *  @param n_vs_id         Index of the vertex shader used for the iteration;
   7350  *  @param n_vs_subroutine Index of the subroutine used in the vertex shader for
   7351  *                         the iteration.
   7352  */
   7353 void FunctionalTest13::verifyReadBuffer(unsigned int n_fs_id, unsigned int n_fs_subroutine, unsigned int n_gs_id,
   7354 										unsigned int n_gs_subroutine, unsigned int n_tc_id,
   7355 										unsigned int n_tc_subroutine, unsigned int n_te_id,
   7356 										unsigned int n_te_subroutine, unsigned int n_vs_id,
   7357 										unsigned int n_vs_subroutine)
   7358 {
   7359 	float expected_color[4] = { 0 };
   7360 	float fs_modifier[4]	= { 0 };
   7361 	float gs_modifier[4]	= { 0 };
   7362 	float tc_modifier[4]	= { 0 };
   7363 	float te_modifier[4]	= { 0 };
   7364 	float vs_modifier[4]	= { 0 };
   7365 
   7366 	if (n_fs_subroutine == 0)
   7367 	{
   7368 		for (unsigned int n_component = 0; n_component < 4; ++n_component)
   7369 		{
   7370 			fs_modifier[n_component] = float(n_fs_id + n_component + 1) / 10.0f;
   7371 		}
   7372 	}
   7373 	else
   7374 	{
   7375 		for (unsigned int n_component = 0; n_component < 4; ++n_component)
   7376 		{
   7377 			fs_modifier[n_component] = float(n_fs_id + n_component + 1) / 20.0f;
   7378 		}
   7379 	}
   7380 
   7381 	if (n_gs_subroutine == 0)
   7382 	{
   7383 		gs_modifier[3] = float(n_gs_id + 1) * 0.425f;
   7384 	}
   7385 	else
   7386 	{
   7387 		gs_modifier[3] = float(n_gs_id + 1) * 0.0425f;
   7388 	}
   7389 
   7390 	if (n_tc_subroutine == 0)
   7391 	{
   7392 		tc_modifier[1] = float(n_tc_id + 1) * 0.25f;
   7393 	}
   7394 	else
   7395 	{
   7396 		tc_modifier[1] = float(n_tc_id + 1) * 0.025f;
   7397 	}
   7398 
   7399 	if (n_te_subroutine == 0)
   7400 	{
   7401 		te_modifier[2] = float(n_te_id + 1) * 0.325f;
   7402 	}
   7403 	else
   7404 	{
   7405 		te_modifier[2] = float(n_te_id + 1) * 0.0325f;
   7406 	}
   7407 
   7408 	if (n_vs_subroutine == 0)
   7409 	{
   7410 		vs_modifier[0] = float(n_vs_id + 1) * 0.125f;
   7411 	}
   7412 	else
   7413 	{
   7414 		vs_modifier[0] = float(n_vs_id + 1) * 0.0125f;
   7415 	}
   7416 
   7417 	/* Determine the expected color */
   7418 	for (unsigned int n_component = 0; n_component < 4 /* rgba */; ++n_component)
   7419 	{
   7420 		expected_color[n_component] = fs_modifier[n_component] + gs_modifier[n_component] + tc_modifier[n_component] +
   7421 									  te_modifier[n_component] + vs_modifier[n_component];
   7422 	}
   7423 
   7424 	/* Verify all read texels are valid */
   7425 	const float epsilon			= 1e-5f;
   7426 	bool		should_continue = true;
   7427 
   7428 	for (unsigned int y = 0; y < m_to_height && should_continue; ++y)
   7429 	{
   7430 		const float* row_ptr = (const float*)m_read_buffer + y * m_to_width * 4; /* rgba */
   7431 
   7432 		for (unsigned int x = 0; x < m_to_width && should_continue; ++x)
   7433 		{
   7434 			const float* texel_ptr = row_ptr + x * 4; /* rgba */
   7435 
   7436 			if (de::abs(texel_ptr[0] - expected_color[0]) > epsilon ||
   7437 				de::abs(texel_ptr[1] - expected_color[1]) > epsilon ||
   7438 				de::abs(texel_ptr[2] - expected_color[2]) > epsilon ||
   7439 				de::abs(texel_ptr[3] - expected_color[3]) > epsilon)
   7440 			{
   7441 				m_testCtx.getLog() << tcu::TestLog::Message << "Invalid texel rendered at (" << x << ", " << y
   7442 								   << ") for "
   7443 									  "the following configuration: "
   7444 									  "n_fs_id:"
   7445 								   << n_fs_id << " n_fs_subroutine:" << n_fs_subroutine << " n_gs_id:" << n_gs_id
   7446 								   << " n_gs_subroutine:" << n_gs_subroutine << " n_tc_id:" << n_tc_id
   7447 								   << " n_tc_subroutine:" << n_tc_subroutine << " n_te_id:" << n_te_id
   7448 								   << " n_te_subroutine:" << n_te_subroutine << " n_vs_id:" << n_vs_id
   7449 								   << " n_vs_subroutine:" << n_vs_subroutine << "; expected:"
   7450 																				"("
   7451 								   << expected_color[0] << ", " << expected_color[1] << ", " << expected_color[2]
   7452 								   << ", " << expected_color[3] << "), found:"
   7453 																   "("
   7454 								   << texel_ptr[0] << ", " << texel_ptr[1] << ", " << texel_ptr[2] << ", "
   7455 								   << texel_ptr[3] << ")." << tcu::TestLog::EndMessage;
   7456 
   7457 				m_has_test_passed = false;
   7458 				should_continue   = false;
   7459 			}
   7460 		} /* for (all columns) */
   7461 	}	 /* for (all rows) */
   7462 }
   7463 
   7464 /** Constructor
   7465  *
   7466  * @param context CTS context
   7467  **/
   7468 FunctionalTest14_15::FunctionalTest14_15(deqp::Context& context)
   7469 	: TestCase(context, "structure_parameters_program_binary", "Verify structures can be used as parameters")
   7470 	, m_uniform_location(0)
   7471 {
   7472 }
   7473 
   7474 /** Execute test
   7475  *
   7476  * @return tcu::TestNode::STOP
   7477  **/
   7478 tcu::TestNode::IterateResult FunctionalTest14_15::iterate()
   7479 {
   7480 	static const GLchar* vertex_shader_code =
   7481 		"#version 400 core\n"
   7482 		"#extension GL_ARB_shader_subroutine : require\n"
   7483 		"\n"
   7484 		"precision highp float;\n"
   7485 		"\n"
   7486 		"struct data\n"
   7487 		"{\n"
   7488 		"    uint r;\n"
   7489 		"    uint g;\n"
   7490 		"    uint b;\n"
   7491 		"    uint a;\n"
   7492 		"};\n"
   7493 		"\n"
   7494 		"subroutine void routine_type_1(in data iparam, out data oparam);\n"
   7495 		"subroutine void routine_type_2(inout data arg);\n"
   7496 		"\n"
   7497 		"subroutine (routine_type_1) void invert(in data iparam, out data oparam)\n"
   7498 		"{\n"
   7499 		"    oparam.r = iparam.a;\n"
   7500 		"    oparam.g = iparam.b;\n"
   7501 		"    oparam.b = iparam.g;\n"
   7502 		"    oparam.a = iparam.r;\n"
   7503 		"}\n"
   7504 		"\n"
   7505 		"subroutine (routine_type_1) void increment(in data iparam, out data oparam)\n"
   7506 		"{\n"
   7507 		"    oparam.r = 1 + iparam.r;\n"
   7508 		"    oparam.g = 1 + iparam.g;\n"
   7509 		"    oparam.b = 1 + iparam.b;\n"
   7510 		"    oparam.a = 1 + iparam.a;\n"
   7511 		"}\n"
   7512 		"\n"
   7513 		"subroutine (routine_type_2) void div_by_2(inout data arg)\n"
   7514 		"{\n"
   7515 		"    arg.r = arg.r / 2;\n"
   7516 		"    arg.g = arg.g / 2;\n"
   7517 		"    arg.b = arg.b / 2;\n"
   7518 		"    arg.a = arg.a / 2;\n"
   7519 		"}\n"
   7520 		"\n"
   7521 		"subroutine (routine_type_2) void decrement(inout data arg)\n"
   7522 		"{\n"
   7523 		"    arg.r = arg.r - 1;\n"
   7524 		"    arg.g = arg.g - 1;\n"
   7525 		"    arg.b = arg.b - 1;\n"
   7526 		"    arg.a = arg.a - 1;\n"
   7527 		"}\n"
   7528 		"\n"
   7529 		"subroutine uniform routine_type_1 routine_1;\n"
   7530 		"subroutine uniform routine_type_2 routine_2;\n"
   7531 		"\n"
   7532 		"uniform uvec4 uni_input;\n"
   7533 		"\n"
   7534 		"out uvec4 out_routine_1;\n"
   7535 		"out uvec4 out_routine_2;\n"
   7536 		"\n"
   7537 		"\n"
   7538 		"void main()\n"
   7539 		"{\n"
   7540 		"    data routine_1_input;\n"
   7541 		"    data routine_1_output;\n"
   7542 		"    data routine_2_arg;\n"
   7543 		"\n"
   7544 		"    routine_1_input.r = uni_input.r;\n"
   7545 		"    routine_1_input.g = uni_input.g;\n"
   7546 		"    routine_1_input.b = uni_input.b;\n"
   7547 		"    routine_1_input.a = uni_input.a;\n"
   7548 		"\n"
   7549 		"    routine_2_arg.r = uni_input.r;\n"
   7550 		"    routine_2_arg.g = uni_input.g;\n"
   7551 		"    routine_2_arg.b = uni_input.b;\n"
   7552 		"    routine_2_arg.a = uni_input.a;\n"
   7553 		"\n"
   7554 		"    routine_1(routine_1_input, routine_1_output);\n"
   7555 		"    routine_2(routine_2_arg);\n"
   7556 		"\n"
   7557 		"    out_routine_1.r = routine_1_output.r;\n"
   7558 		"    out_routine_1.g = routine_1_output.g;\n"
   7559 		"    out_routine_1.b = routine_1_output.b;\n"
   7560 		"    out_routine_1.a = routine_1_output.a;\n"
   7561 		"\n"
   7562 		"    out_routine_2.r = routine_2_arg.r;\n"
   7563 		"    out_routine_2.g = routine_2_arg.g;\n"
   7564 		"    out_routine_2.b = routine_2_arg.b;\n"
   7565 		"    out_routine_2.a = routine_2_arg.a;\n"
   7566 		"}\n"
   7567 		"\n";
   7568 
   7569 	static const GLchar* subroutine_names[][2] = { { "invert", "increment" }, { "div_by_2", "decrement" } };
   7570 	static const GLuint  n_subroutine_types	= sizeof(subroutine_names) / sizeof(subroutine_names[0]);
   7571 
   7572 	static const GLchar* subroutine_uniform_names[] = { "routine_1", "routine_2" };
   7573 	static const GLuint  n_subroutine_uniform_names =
   7574 		sizeof(subroutine_uniform_names) / sizeof(subroutine_uniform_names[0]);
   7575 
   7576 	static const GLchar* uniform_name	= "uni_input";
   7577 	static const GLchar* varying_names[] = { "out_routine_1", "out_routine_2" };
   7578 
   7579 	static const GLuint n_varying_names				   = sizeof(varying_names) / sizeof(varying_names[0]);
   7580 	static const GLuint transform_feedback_buffer_size = n_varying_names * 4 * sizeof(GLuint);
   7581 
   7582 	/* Test data */
   7583 	static const Utils::vec4<GLuint> uni_input[] = { Utils::vec4<GLuint>(8, 64, 4096, 16777216),
   7584 													 Utils::vec4<GLuint>(8, 64, 4096, 16777216) };
   7585 
   7586 	static const Utils::vec4<GLuint> out_routine_1[] = { Utils::vec4<GLuint>(16777216, 4096, 64, 8),
   7587 														 Utils::vec4<GLuint>(9, 65, 4097, 16777217) };
   7588 
   7589 	static const Utils::vec4<GLuint> out_routine_2[] = { Utils::vec4<GLuint>(4, 32, 2048, 8388608),
   7590 														 Utils::vec4<GLuint>(7, 63, 4095, 16777215) };
   7591 
   7592 	static const GLuint n_test_cases = 2;
   7593 
   7594 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   7595 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   7596 	{
   7597 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   7598 	}
   7599 
   7600 	/* GL objects */
   7601 	Utils::program	 program(m_context);
   7602 	Utils::buffer	  transform_feedback_buffer(m_context);
   7603 	Utils::vertexArray vao(m_context);
   7604 
   7605 	bool is_program_binary_supported = program.isProgramBinarySupported();
   7606 
   7607 	/* Init GL objects */
   7608 	program.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* test */, vertex_shader_code,
   7609 				  varying_names /* varying_names */, n_varying_names /* n_varyings */);
   7610 
   7611 	/* Do not execute the test if GL_ARB_get_program_binary is not supported */
   7612 	if (true == is_program_binary_supported)
   7613 	{
   7614 		/* Get subroutine indices */
   7615 		for (GLuint type = 0; type < n_subroutine_types; ++type)
   7616 		{
   7617 			m_initial_subroutine_indices[type][0] =
   7618 				program.getSubroutineIndex(subroutine_names[type][0], GL_VERTEX_SHADER);
   7619 
   7620 			m_initial_subroutine_indices[type][1] =
   7621 				program.getSubroutineIndex(subroutine_names[type][1], GL_VERTEX_SHADER);
   7622 		}
   7623 
   7624 		/* Get subroutine uniform locations */
   7625 		for (GLuint uniform = 0; uniform < n_subroutine_uniform_names; ++uniform)
   7626 		{
   7627 			m_initial_subroutine_uniform_locations[uniform] =
   7628 				program.getSubroutineUniformLocation(subroutine_uniform_names[uniform], GL_VERTEX_SHADER);
   7629 		}
   7630 
   7631 		/* Delete program and recreate it from binary */
   7632 		std::vector<GLubyte> program_binary;
   7633 		GLenum				 binary_format;
   7634 
   7635 		program.getBinary(program_binary, binary_format);
   7636 		program.remove();
   7637 		program.createFromBinary(program_binary, binary_format);
   7638 	}
   7639 
   7640 	program.use();
   7641 
   7642 	vao.generate();
   7643 	vao.bind();
   7644 
   7645 	transform_feedback_buffer.generate();
   7646 	transform_feedback_buffer.update(GL_TRANSFORM_FEEDBACK_BUFFER, transform_feedback_buffer_size, 0 /* data */,
   7647 									 GL_DYNAMIC_COPY);
   7648 	transform_feedback_buffer.bindRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, transform_feedback_buffer_size);
   7649 
   7650 	/* Get subroutine indices */
   7651 	for (GLuint type = 0; type < n_subroutine_types; ++type)
   7652 	{
   7653 		m_subroutine_indices[type][0] = program.getSubroutineIndex(subroutine_names[type][0], GL_VERTEX_SHADER);
   7654 		m_subroutine_indices[type][1] = program.getSubroutineIndex(subroutine_names[type][1], GL_VERTEX_SHADER);
   7655 	}
   7656 
   7657 	/* Get subroutine uniform locations */
   7658 	for (GLuint uniform = 0; uniform < n_subroutine_uniform_names; ++uniform)
   7659 	{
   7660 		m_subroutine_uniform_locations[uniform] =
   7661 			program.getSubroutineUniformLocation(subroutine_uniform_names[uniform], GL_VERTEX_SHADER);
   7662 	}
   7663 
   7664 	/* Get uniform locations */
   7665 	m_uniform_location = program.getUniformLocation(uniform_name);
   7666 
   7667 	/* Test */
   7668 	bool result = true;
   7669 
   7670 	/* Test program binary */
   7671 	if (true == is_program_binary_supported)
   7672 	{
   7673 		/* Test indices and locations */
   7674 		if (false == testIndicesAndLocations())
   7675 		{
   7676 			static const GLuint n_subroutines_per_type = 2;
   7677 
   7678 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   7679 												<< "Error. Subroutine indices or subroutine uniform location changed."
   7680 												<< tcu::TestLog::EndMessage;
   7681 
   7682 			for (GLuint type = 0; type < n_subroutine_types; ++type)
   7683 			{
   7684 				for (GLuint i = 0; i < n_subroutines_per_type; ++i)
   7685 				{
   7686 					m_context.getTestContext().getLog()
   7687 						<< tcu::TestLog::Message << "Subroutine: " << subroutine_names[type][i]
   7688 						<< " index: " << m_subroutine_indices[type][i]
   7689 						<< " initial index: " << m_initial_subroutine_indices[type][i] << tcu::TestLog::EndMessage;
   7690 				}
   7691 			}
   7692 
   7693 			for (GLuint uniform = 0; uniform < n_subroutine_uniform_names; ++uniform)
   7694 			{
   7695 				m_context.getTestContext().getLog()
   7696 					<< tcu::TestLog::Message << "Subroutine uniform: " << subroutine_uniform_names[uniform]
   7697 					<< " location: " << m_subroutine_uniform_locations[uniform]
   7698 					<< " initial location: " << m_initial_subroutine_uniform_locations[uniform]
   7699 					<< tcu::TestLog::EndMessage;
   7700 			}
   7701 
   7702 			result = false;
   7703 		}
   7704 
   7705 		/* Test draw with deafult set of subroutines */
   7706 		if (false == testDefaultSubroutineSet(uni_input[0], out_routine_1, out_routine_2))
   7707 		{
   7708 			result = false;
   7709 		}
   7710 	}
   7711 
   7712 	for (GLuint i = 0; i < n_test_cases; ++i)
   7713 	{
   7714 		if (false == testDraw(i, uni_input[i], out_routine_1[i], out_routine_2[i]))
   7715 		{
   7716 			result = false;
   7717 		}
   7718 	}
   7719 
   7720 	/* Set result */
   7721 	if (true == result)
   7722 	{
   7723 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   7724 	}
   7725 	else
   7726 	{
   7727 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   7728 	}
   7729 
   7730 	/* Done */
   7731 	return tcu::TestNode::STOP;
   7732 }
   7733 
   7734 /** Execute draw call and verify results
   7735  *
   7736  * @param uni_input                 Input data
   7737  * @param expected_routine_1_result Set of expected results of "routine_1"
   7738  * @param expected_routine_2_result Set of expected results of "routine_2"
   7739  *
   7740  * @return true if test pass, false otherwise
   7741  **/
   7742 bool FunctionalTest14_15::testDefaultSubroutineSet(const Utils::vec4<glw::GLuint>& uni_input,
   7743 												   const Utils::vec4<glw::GLuint>  expected_routine_1_result[2],
   7744 												   const Utils::vec4<glw::GLuint>  expected_routine_2_result[2]) const
   7745 {
   7746 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
   7747 	bool				  result = true;
   7748 
   7749 	/* Set up input data uniforms */
   7750 	gl.uniform4ui(m_uniform_location, uni_input.m_x, uni_input.m_y, uni_input.m_z, uni_input.m_w);
   7751 	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f");
   7752 
   7753 	/* Execute draw call with transform feedback */
   7754 	gl.beginTransformFeedback(GL_POINTS);
   7755 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
   7756 
   7757 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   7758 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
   7759 
   7760 	gl.endTransformFeedback();
   7761 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
   7762 
   7763 	/* Capture results */
   7764 	GLuint* feedback_data = (GLuint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   7765 	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
   7766 
   7767 	Utils::vec4<GLuint> routine_1_result;
   7768 	Utils::vec4<GLuint> routine_2_result;
   7769 
   7770 	routine_1_result.m_x = feedback_data[0 + 0];
   7771 	routine_1_result.m_y = feedback_data[0 + 1];
   7772 	routine_1_result.m_z = feedback_data[0 + 2];
   7773 	routine_1_result.m_w = feedback_data[0 + 3];
   7774 
   7775 	routine_2_result.m_x = feedback_data[4 + 0];
   7776 	routine_2_result.m_y = feedback_data[4 + 1];
   7777 	routine_2_result.m_z = feedback_data[4 + 2];
   7778 	routine_2_result.m_w = feedback_data[4 + 3];
   7779 
   7780 	/* Unmap buffer */
   7781 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   7782 	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
   7783 
   7784 	/* Verifiy */
   7785 	result = result &&
   7786 			 ((routine_1_result == expected_routine_1_result[0]) || (routine_1_result == expected_routine_1_result[1]));
   7787 
   7788 	result = result &&
   7789 			 ((routine_2_result == expected_routine_2_result[0]) || (routine_2_result == expected_routine_2_result[1]));
   7790 
   7791 	/* Log error if any */
   7792 	if (false == result)
   7793 	{
   7794 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result."
   7795 											<< tcu::TestLog::EndMessage;
   7796 
   7797 		tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   7798 
   7799 		message << "Routine_1, result: ";
   7800 
   7801 		routine_1_result.log(message);
   7802 
   7803 		message << "Routine_2, result: ";
   7804 
   7805 		routine_2_result.log(message);
   7806 
   7807 		message << tcu::TestLog::EndMessage;
   7808 	}
   7809 
   7810 	/* Done */
   7811 	return result;
   7812 }
   7813 
   7814 /** Execute draw call and verify results
   7815  *
   7816  * @param routine_configuration     Subroutine "type" ordinal
   7817  * @param uni_input                 Input data
   7818  * @param expected_routine_1_result Expected results of "routine_1"
   7819  * @param expected_routine_2_result Expected results of "routine_2"
   7820  *
   7821  * @return true if test pass, false otherwise
   7822  **/
   7823 bool FunctionalTest14_15::testDraw(glw::GLuint routine_configuration, const Utils::vec4<glw::GLuint>& uni_input,
   7824 								   const Utils::vec4<glw::GLuint>& expected_routine_1_result,
   7825 								   const Utils::vec4<glw::GLuint>& expected_routine_2_result) const
   7826 {
   7827 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
   7828 	bool				  result = true;
   7829 	GLuint				  subroutine_indices[2];
   7830 	static const GLuint   n_subroutine_uniforms = sizeof(subroutine_indices) / sizeof(subroutine_indices[0]);
   7831 
   7832 	/* Set up input data uniforms */
   7833 	gl.uniform4ui(m_uniform_location, uni_input.m_x, uni_input.m_y, uni_input.m_z, uni_input.m_w);
   7834 	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f");
   7835 
   7836 	/* Prepare subroutine uniform data */
   7837 	for (GLuint i = 0; i < n_subroutine_uniforms; ++i)
   7838 	{
   7839 		const GLuint location = m_subroutine_uniform_locations[i];
   7840 
   7841 		subroutine_indices[location] = m_subroutine_indices[i][routine_configuration];
   7842 	}
   7843 
   7844 	/* Set up subroutine uniforms */
   7845 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, n_subroutine_uniforms, &subroutine_indices[0]);
   7846 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   7847 
   7848 	/* Execute draw call with transform feedback */
   7849 	gl.beginTransformFeedback(GL_POINTS);
   7850 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
   7851 
   7852 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   7853 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
   7854 
   7855 	gl.endTransformFeedback();
   7856 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
   7857 
   7858 	/* Capture results */
   7859 	GLuint* feedback_data = (GLuint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   7860 	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
   7861 
   7862 	Utils::vec4<GLuint> routine_1_result;
   7863 	Utils::vec4<GLuint> routine_2_result;
   7864 
   7865 	routine_1_result.m_x = feedback_data[0 + 0];
   7866 	routine_1_result.m_y = feedback_data[0 + 1];
   7867 	routine_1_result.m_z = feedback_data[0 + 2];
   7868 	routine_1_result.m_w = feedback_data[0 + 3];
   7869 
   7870 	routine_2_result.m_x = feedback_data[4 + 0];
   7871 	routine_2_result.m_y = feedback_data[4 + 1];
   7872 	routine_2_result.m_z = feedback_data[4 + 2];
   7873 	routine_2_result.m_w = feedback_data[4 + 3];
   7874 
   7875 	/* Unmap buffer */
   7876 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   7877 	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
   7878 
   7879 	/* Verifiy */
   7880 	result = result && (routine_1_result == expected_routine_1_result);
   7881 	result = result && (routine_2_result == expected_routine_2_result);
   7882 
   7883 	/* Log error if any */
   7884 	if (false == result)
   7885 	{
   7886 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result."
   7887 											<< tcu::TestLog::EndMessage;
   7888 
   7889 		tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
   7890 
   7891 		message << "Routine_1, result: ";
   7892 
   7893 		routine_1_result.log(message);
   7894 
   7895 		message << ", expected: ";
   7896 
   7897 		expected_routine_1_result.log(message);
   7898 
   7899 		message << "Routine_2, result: ";
   7900 
   7901 		routine_2_result.log(message);
   7902 
   7903 		message << ", expected: ";
   7904 
   7905 		expected_routine_2_result.log(message);
   7906 
   7907 		message << tcu::TestLog::EndMessage;
   7908 	}
   7909 
   7910 	/* Done */
   7911 	return result;
   7912 }
   7913 
   7914 /** Verify initial and current values of subroutine indices and subroutines uniform locations
   7915  *
   7916  * @return true if test pass, false otherwise
   7917  **/
   7918 bool FunctionalTest14_15::testIndicesAndLocations() const
   7919 {
   7920 	static const GLuint n_subroutine_types = 2;
   7921 	bool				result			   = true;
   7922 
   7923 	/* Verify subroutine indices */
   7924 	for (GLuint type = 0; type < n_subroutine_types; ++type)
   7925 	{
   7926 		result = result && (m_subroutine_indices[type][0] == m_initial_subroutine_indices[type][0]);
   7927 		result = result && (m_subroutine_indices[type][1] == m_initial_subroutine_indices[type][1]);
   7928 	}
   7929 
   7930 	/* Verify subroutine uniform locations */
   7931 	for (GLuint uniform = 0; uniform < n_subroutine_types; ++uniform)
   7932 	{
   7933 		result = result && (m_subroutine_uniform_locations[uniform] == m_initial_subroutine_uniform_locations[uniform]);
   7934 	}
   7935 
   7936 	return result;
   7937 }
   7938 
   7939 /** Constructor.
   7940  *
   7941  *  @param context Rendering context.
   7942  *
   7943  **/
   7944 FunctionalTest16::FunctionalTest16(deqp::Context& context)
   7945 	: TestCase(context, "subroutine_uniform_reset",
   7946 			   "Checks that when the active program for a shader stage is re-linke or "
   7947 			   "changed by a call to UseProgram, BindProgramPipeline, or UseProgramStages,"
   7948 			   " subroutine uniforms for that stage are reset to arbitrarily chosen default "
   7949 			   "functions with compatible subroutine types.")
   7950 	, m_are_pipeline_objects_supported(false)
   7951 	, m_has_test_passed(true)
   7952 {
   7953 	memset(m_fs_ids, 0, sizeof(m_fs_ids));
   7954 	memset(m_gs_ids, 0, sizeof(m_gs_ids));
   7955 	memset(m_po_ids, 0, sizeof(m_po_ids));
   7956 	memset(m_tc_ids, 0, sizeof(m_tc_ids));
   7957 	memset(m_te_ids, 0, sizeof(m_te_ids));
   7958 	memset(m_vs_ids, 0, sizeof(m_vs_ids));
   7959 
   7960 	memset(m_fs_po_ids, 0, sizeof(m_fs_po_ids));
   7961 	memset(m_gs_po_ids, 0, sizeof(m_gs_po_ids));
   7962 	memset(m_pipeline_object_ids, 0, sizeof(m_pipeline_object_ids));
   7963 	memset(m_tc_po_ids, 0, sizeof(m_tc_po_ids));
   7964 	memset(m_te_po_ids, 0, sizeof(m_te_po_ids));
   7965 	memset(m_vs_po_ids, 0, sizeof(m_vs_po_ids));
   7966 }
   7967 
   7968 /** Deinitializes all GL objects that may have been created during test execution. */
   7969 void FunctionalTest16::deinit()
   7970 {
   7971 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   7972 
   7973 	for (unsigned int n_id = 0; n_id < 2; ++n_id)
   7974 	{
   7975 		if (m_fs_ids[n_id] != 0)
   7976 		{
   7977 			gl.deleteShader(m_fs_ids[n_id]);
   7978 
   7979 			m_fs_ids[n_id] = 0;
   7980 		}
   7981 
   7982 		if (m_fs_po_ids[n_id] != 0)
   7983 		{
   7984 			gl.deleteProgram(m_fs_po_ids[n_id]);
   7985 
   7986 			m_fs_po_ids[n_id] = 0;
   7987 		}
   7988 
   7989 		if (m_gs_ids[n_id] != 0)
   7990 		{
   7991 			gl.deleteShader(m_gs_ids[n_id]);
   7992 
   7993 			m_gs_ids[n_id] = 0;
   7994 		}
   7995 
   7996 		if (m_gs_po_ids[n_id] != 0)
   7997 		{
   7998 			gl.deleteProgram(m_gs_po_ids[n_id]);
   7999 
   8000 			m_gs_po_ids[n_id] = 0;
   8001 		}
   8002 
   8003 		if (m_pipeline_object_ids[n_id] != 0)
   8004 		{
   8005 			gl.deleteProgramPipelines(1 /* n */, m_pipeline_object_ids + n_id);
   8006 		}
   8007 
   8008 		if (m_po_ids[n_id] != 0)
   8009 		{
   8010 			gl.deleteProgram(m_po_ids[n_id]);
   8011 
   8012 			m_po_ids[n_id] = 0;
   8013 		}
   8014 
   8015 		if (m_tc_ids[n_id] != 0)
   8016 		{
   8017 			gl.deleteShader(m_tc_ids[n_id]);
   8018 
   8019 			m_tc_ids[n_id] = 0;
   8020 		}
   8021 
   8022 		if (m_tc_po_ids[n_id] != 0)
   8023 		{
   8024 			gl.deleteProgram(m_tc_po_ids[n_id]);
   8025 
   8026 			m_tc_po_ids[n_id] = 0;
   8027 		}
   8028 
   8029 		if (m_te_ids[n_id] != 0)
   8030 		{
   8031 			gl.deleteShader(m_te_ids[n_id]);
   8032 
   8033 			m_te_ids[n_id] = 0;
   8034 		}
   8035 
   8036 		if (m_te_po_ids[n_id] != 0)
   8037 		{
   8038 			gl.deleteProgram(m_te_po_ids[n_id]);
   8039 
   8040 			m_te_po_ids[n_id] = 0;
   8041 		}
   8042 
   8043 		if (m_vs_ids[n_id] != 0)
   8044 		{
   8045 			gl.deleteShader(m_vs_ids[n_id]);
   8046 
   8047 			m_vs_ids[n_id] = 0;
   8048 		}
   8049 
   8050 		if (m_vs_po_ids[n_id] != 0)
   8051 		{
   8052 			gl.deleteProgram(m_vs_po_ids[n_id]);
   8053 
   8054 			m_vs_po_ids[n_id] = 0;
   8055 		}
   8056 	} /* for (both IDs) */
   8057 }
   8058 
   8059 /** Retrieves body of a shader that should be used for user-specified shader stage.
   8060  *  This function returns slightly different implementations, depending on index of
   8061  *  the program/pipeline object the shader will be used for.
   8062  *
   8063  *  @param shader_stage Stage the shader body is to be returned for.
   8064  *  @param n_id         Index of the shader (as per description).
   8065  *
   8066  *  @return Requested string.
   8067  **/
   8068 std::string FunctionalTest16::getShaderBody(const Utils::_shader_stage& shader_stage, const unsigned int& n_id) const
   8069 {
   8070 	std::stringstream result_sstream;
   8071 
   8072 	result_sstream << "#version 400\n"
   8073 					  "\n"
   8074 					  "#extension GL_ARB_shader_subroutine : require\n"
   8075 					  "\n";
   8076 
   8077 	switch (shader_stage)
   8078 	{
   8079 	case Utils::SHADER_STAGE_VERTEX:
   8080 	{
   8081 		result_sstream << "out gl_PerVertex { vec4 gl_Position; } ;\n";
   8082 		break;
   8083 	}
   8084 	case Utils::SHADER_STAGE_GEOMETRY:
   8085 	{
   8086 		result_sstream << "layout(points)                   in;\n"
   8087 						  "layout(points, max_vertices = 1) out;\n";
   8088 		result_sstream << "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n";
   8089 		result_sstream << "out gl_PerVertex { vec4 gl_Position; } ;\n";
   8090 		break;
   8091 	}
   8092 
   8093 	case Utils::SHADER_STAGE_TESSELLATION_CONTROL:
   8094 	{
   8095 		result_sstream << "layout(vertices = 4) out;\n";
   8096 		result_sstream << "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n";
   8097 		result_sstream << "out gl_PerVertex { vec4 gl_Position; } gl_out[];\n";
   8098 		break;
   8099 	}
   8100 
   8101 	case Utils::SHADER_STAGE_TESSELLATION_EVALUATION:
   8102 	{
   8103 		result_sstream << "layout(quads) in;\n";
   8104 		result_sstream << "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n";
   8105 		result_sstream << "out gl_PerVertex { vec4 gl_Position; };\n";
   8106 		break;
   8107 	}
   8108 
   8109 	default:
   8110 		break;
   8111 	} /* switch (shader_stage) */
   8112 
   8113 	result_sstream << "\n"
   8114 					  "subroutine void subroutineType (inout vec4 result);\n"
   8115 					  "subroutine vec4 subroutineType2(in    vec4 data);\n"
   8116 					  "\n"
   8117 					  "subroutine(subroutineType) void function1(inout vec4 result)\n"
   8118 					  "{\n"
   8119 					  "    result += vec4("
   8120 				   << (n_id + 1) << ", " << (n_id + 2) << ", " << (n_id + 3) << ", " << (n_id + 4)
   8121 				   << ");\n"
   8122 					  "}\n"
   8123 					  "subroutine(subroutineType) void function2(inout vec4 result)\n"
   8124 					  "{\n"
   8125 					  "    result += vec4("
   8126 				   << (n_id + 2) << ", " << (n_id + 3) << ", " << (n_id + 4) << ", " << (n_id + 5)
   8127 				   << ");\n"
   8128 					  "}\n"
   8129 					  "\n"
   8130 					  "subroutine(subroutineType2) vec4 function3(in vec4 data)\n"
   8131 					  "{\n"
   8132 					  "    return data * data;\n"
   8133 					  "}\n"
   8134 					  "subroutine(subroutineType2) vec4 function4(in vec4 data)\n"
   8135 					  "{\n"
   8136 					  "    return data + data;\n"
   8137 					  "}\n"
   8138 					  "\n"
   8139 					  "subroutine uniform subroutineType  subroutine1;\n"
   8140 					  "subroutine uniform subroutineType  subroutine2;\n"
   8141 					  "subroutine uniform subroutineType2 subroutine3;\n"
   8142 					  "subroutine uniform subroutineType2 subroutine4;\n"
   8143 					  "\n";
   8144 
   8145 	if (shader_stage == Utils::SHADER_STAGE_FRAGMENT)
   8146 	{
   8147 		result_sstream << "out vec4 result;\n";
   8148 	}
   8149 
   8150 	result_sstream << "void main()\n"
   8151 					  "{\n";
   8152 
   8153 	switch (shader_stage)
   8154 	{
   8155 	case Utils::SHADER_STAGE_FRAGMENT:
   8156 	{
   8157 		result_sstream << "    result = vec4(0);\n"
   8158 					   << "    subroutine1(result);\n"
   8159 						  "    subroutine2(result);\n"
   8160 						  "    result = subroutine3(result) + subroutine4(result);\n";
   8161 
   8162 		break;
   8163 	}
   8164 
   8165 	case Utils::SHADER_STAGE_GEOMETRY:
   8166 	{
   8167 		result_sstream << "    gl_Position = vec4(0);\n"
   8168 						  "    subroutine1(gl_Position);\n"
   8169 						  "    subroutine2(gl_Position);\n"
   8170 						  "    gl_Position = subroutine3(gl_Position) + subroutine4(gl_Position);\n"
   8171 						  "    EmitVertex();\n";
   8172 
   8173 		break;
   8174 	}
   8175 
   8176 	case Utils::SHADER_STAGE_TESSELLATION_CONTROL:
   8177 	{
   8178 		result_sstream << "    gl_out[gl_InvocationID].gl_Position = vec4(0);\n"
   8179 						  "    subroutine1(gl_out[gl_InvocationID].gl_Position);\n"
   8180 						  "    subroutine2(gl_out[gl_InvocationID].gl_Position);\n"
   8181 						  "    gl_out[gl_InvocationID].gl_Position = subroutine3(gl_in[0].gl_Position) + "
   8182 						  "subroutine4(gl_in[0].gl_Position);\n";
   8183 
   8184 		break;
   8185 	}
   8186 
   8187 	case Utils::SHADER_STAGE_VERTEX:
   8188 	case Utils::SHADER_STAGE_TESSELLATION_EVALUATION:
   8189 	{
   8190 		result_sstream << "    gl_Position = vec4(0);\n"
   8191 						  "    subroutine1(gl_Position);\n"
   8192 						  "    subroutine2(gl_Position);\n"
   8193 						  "    gl_Position = subroutine3(gl_Position) + subroutine4(gl_Position);\n";
   8194 
   8195 		break;
   8196 	}
   8197 
   8198 	default:
   8199 		break;
   8200 	} /* switch (shader_stage) */
   8201 
   8202 	result_sstream << "}\n";
   8203 
   8204 	return result_sstream.str();
   8205 }
   8206 
   8207 /** Initializes all objects required to run the test. */
   8208 void FunctionalTest16::initTest()
   8209 {
   8210 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   8211 
   8212 	for (unsigned int n_id = 0; n_id < 2 /* test program/shader objects */; ++n_id)
   8213 	{
   8214 		const std::string fs_body = getShaderBody(Utils::SHADER_STAGE_FRAGMENT, n_id);
   8215 		const std::string gs_body = getShaderBody(Utils::SHADER_STAGE_GEOMETRY, n_id);
   8216 		const std::string tc_body = getShaderBody(Utils::SHADER_STAGE_TESSELLATION_CONTROL, n_id);
   8217 		const std::string te_body = getShaderBody(Utils::SHADER_STAGE_TESSELLATION_EVALUATION, n_id);
   8218 		const std::string vs_body = getShaderBody(Utils::SHADER_STAGE_VERTEX, n_id);
   8219 
   8220 		if (!Utils::buildProgram(gl, vs_body, tc_body, te_body, gs_body, fs_body, DE_NULL, /* xfb_varyings */
   8221 								 DE_NULL,												   /* n_xfb_varyings */
   8222 								 m_vs_ids + n_id, m_tc_ids + n_id, m_te_ids + n_id, m_gs_ids + n_id, m_fs_ids + n_id,
   8223 								 m_po_ids + n_id))
   8224 		{
   8225 			m_testCtx.getLog() << tcu::TestLog::Message << "Failed to build test program object, index:"
   8226 														   "["
   8227 							   << n_id << "]" << tcu::TestLog::EndMessage;
   8228 
   8229 			TCU_FAIL("Failed to build a test program");
   8230 		}
   8231 
   8232 		if (m_are_pipeline_objects_supported)
   8233 		{
   8234 			/* Initialize shader program objects */
   8235 			const char* fs_body_raw_ptr = fs_body.c_str();
   8236 			const char* gs_body_raw_ptr = gs_body.c_str();
   8237 			glw::GLint  link_status[5]  = { GL_FALSE };
   8238 			const char* tc_body_raw_ptr = tc_body.c_str();
   8239 			const char* te_body_raw_ptr = te_body.c_str();
   8240 			const char* vs_body_raw_ptr = vs_body.c_str();
   8241 
   8242 			m_fs_po_ids[n_id] = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1 /* count */, &fs_body_raw_ptr);
   8243 			m_gs_po_ids[n_id] = gl.createShaderProgramv(GL_GEOMETRY_SHADER, 1 /* count */, &gs_body_raw_ptr);
   8244 			m_tc_po_ids[n_id] = gl.createShaderProgramv(GL_TESS_CONTROL_SHADER, 1 /* count */, &tc_body_raw_ptr);
   8245 			m_te_po_ids[n_id] = gl.createShaderProgramv(GL_TESS_EVALUATION_SHADER, 1 /* count */, &te_body_raw_ptr);
   8246 			m_vs_po_ids[n_id] = gl.createShaderProgramv(GL_VERTEX_SHADER, 1 /* count */, &vs_body_raw_ptr);
   8247 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed.");
   8248 
   8249 			gl.getProgramiv(m_fs_po_ids[n_id], GL_LINK_STATUS, link_status + 0);
   8250 			gl.getProgramiv(m_gs_po_ids[n_id], GL_LINK_STATUS, link_status + 1);
   8251 			gl.getProgramiv(m_tc_po_ids[n_id], GL_LINK_STATUS, link_status + 2);
   8252 			gl.getProgramiv(m_te_po_ids[n_id], GL_LINK_STATUS, link_status + 3);
   8253 			gl.getProgramiv(m_vs_po_ids[n_id], GL_LINK_STATUS, link_status + 4);
   8254 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
   8255 
   8256 			if (link_status[0] == GL_FALSE)
   8257 				TCU_FAIL("Fragment shader program failed to link");
   8258 			if (link_status[1] == GL_FALSE)
   8259 				TCU_FAIL("Geometry shader program failed to link");
   8260 			if (link_status[2] == GL_FALSE)
   8261 				TCU_FAIL("Tessellation control shader program failed to link");
   8262 			if (link_status[3] == GL_FALSE)
   8263 				TCU_FAIL("Tessellation evaluation shader program failed to link");
   8264 			if (link_status[4] == GL_FALSE)
   8265 				TCU_FAIL("Vertex shader program failed to link");
   8266 
   8267 			/* Initialize pipeline program object */
   8268 			gl.genProgramPipelines(1 /* n */, m_pipeline_object_ids + n_id);
   8269 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed.");
   8270 
   8271 			gl.useProgramStages(m_pipeline_object_ids[n_id], GL_FRAGMENT_SHADER_BIT, m_fs_po_ids[n_id]);
   8272 			gl.useProgramStages(m_pipeline_object_ids[n_id], GL_GEOMETRY_SHADER_BIT, m_gs_po_ids[n_id]);
   8273 			gl.useProgramStages(m_pipeline_object_ids[n_id], GL_TESS_CONTROL_SHADER_BIT, m_tc_po_ids[n_id]);
   8274 			gl.useProgramStages(m_pipeline_object_ids[n_id], GL_TESS_EVALUATION_SHADER_BIT, m_te_po_ids[n_id]);
   8275 			gl.useProgramStages(m_pipeline_object_ids[n_id], GL_VERTEX_SHADER_BIT, m_vs_po_ids[n_id]);
   8276 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
   8277 		}
   8278 
   8279 		/* Retrieve subroutine locations */
   8280 		struct _item
   8281 		{
   8282 			glw::GLuint	po_id;
   8283 			_shader_stage& stage;
   8284 			glw::GLuint	so_id;
   8285 			glw::GLenum	so_type;
   8286 		} items[] = {
   8287 			{ m_po_ids[n_id], m_po_descriptors[n_id].fragment, m_fs_ids[n_id], GL_FRAGMENT_SHADER },
   8288 			{ m_po_ids[n_id], m_po_descriptors[n_id].geometry, m_gs_ids[n_id], GL_GEOMETRY_SHADER },
   8289 			{ m_po_ids[n_id], m_po_descriptors[n_id].tess_control, m_tc_ids[n_id], GL_TESS_CONTROL_SHADER },
   8290 			{ m_po_ids[n_id], m_po_descriptors[n_id].tess_evaluation, m_te_ids[n_id], GL_TESS_EVALUATION_SHADER },
   8291 			{ m_po_ids[n_id], m_po_descriptors[n_id].vertex, m_vs_ids[n_id], GL_VERTEX_SHADER },
   8292 
   8293 			{ m_fs_po_ids[n_id], m_fs_po_descriptors[n_id], m_fs_po_ids[n_id], GL_FRAGMENT_SHADER },
   8294 			{ m_gs_po_ids[n_id], m_gs_po_descriptors[n_id], m_gs_po_ids[n_id], GL_GEOMETRY_SHADER },
   8295 			{ m_tc_po_ids[n_id], m_tc_po_descriptors[n_id], m_tc_po_ids[n_id], GL_TESS_CONTROL_SHADER },
   8296 			{ m_te_po_ids[n_id], m_te_po_descriptors[n_id], m_te_po_ids[n_id], GL_TESS_EVALUATION_SHADER },
   8297 			{ m_vs_po_ids[n_id], m_vs_po_descriptors[n_id], m_vs_po_ids[n_id], GL_VERTEX_SHADER },
   8298 		};
   8299 		const unsigned int n_items = sizeof(items) / sizeof(items[0]);
   8300 
   8301 		for (unsigned int n_item = 0; n_item < n_items; ++n_item)
   8302 		{
   8303 			_item& current_item = items[n_item];
   8304 
   8305 			current_item.stage.function1_index =
   8306 				gl.getSubroutineIndex(current_item.po_id, current_item.so_type, "function1");
   8307 			current_item.stage.function2_index =
   8308 				gl.getSubroutineIndex(current_item.po_id, current_item.so_type, "function2");
   8309 			current_item.stage.function3_index =
   8310 				gl.getSubroutineIndex(current_item.po_id, current_item.so_type, "function3");
   8311 			current_item.stage.function4_index =
   8312 				gl.getSubroutineIndex(current_item.po_id, current_item.so_type, "function4");
   8313 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() call(s) failed.");
   8314 
   8315 			if (current_item.stage.function1_index == GL_INVALID_INDEX ||
   8316 				current_item.stage.function2_index == GL_INVALID_INDEX ||
   8317 				current_item.stage.function3_index == GL_INVALID_INDEX ||
   8318 				current_item.stage.function4_index == GL_INVALID_INDEX)
   8319 			{
   8320 				TCU_FAIL("Subroutine name was not recognized.");
   8321 			}
   8322 
   8323 			current_item.stage.subroutine1_uniform_location =
   8324 				gl.getSubroutineUniformLocation(current_item.po_id, current_item.so_type, "subroutine1");
   8325 			current_item.stage.subroutine2_uniform_location =
   8326 				gl.getSubroutineUniformLocation(current_item.po_id, current_item.so_type, "subroutine2");
   8327 			current_item.stage.subroutine3_uniform_location =
   8328 				gl.getSubroutineUniformLocation(current_item.po_id, current_item.so_type, "subroutine3");
   8329 			current_item.stage.subroutine4_uniform_location =
   8330 				gl.getSubroutineUniformLocation(current_item.po_id, current_item.so_type, "subroutine4");
   8331 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() call(s) failed.");
   8332 
   8333 			if (current_item.stage.subroutine1_uniform_location == -1 ||
   8334 				current_item.stage.subroutine2_uniform_location == -1 ||
   8335 				current_item.stage.subroutine3_uniform_location == -1 ||
   8336 				current_item.stage.subroutine4_uniform_location == -1)
   8337 			{
   8338 				TCU_FAIL("Subroutine uniform name was not recognized.");
   8339 			}
   8340 
   8341 			if (m_po_ids[n_id] == current_item.po_id)
   8342 			{
   8343 				gl.useProgram(current_item.po_id);
   8344 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   8345 			}
   8346 			else
   8347 			{
   8348 				/* Temporarily bind the program pipeline. */
   8349 				gl.bindProgramPipeline(m_pipeline_object_ids[n_id]);
   8350 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed.");
   8351 			}
   8352 
   8353 			gl.getUniformSubroutineuiv(current_item.so_type, current_item.stage.subroutine1_uniform_location,
   8354 									   &current_item.stage.default_subroutine1_value);
   8355 			gl.getUniformSubroutineuiv(current_item.so_type, current_item.stage.subroutine2_uniform_location,
   8356 									   &current_item.stage.default_subroutine2_value);
   8357 			gl.getUniformSubroutineuiv(current_item.so_type, current_item.stage.subroutine3_uniform_location,
   8358 									   &current_item.stage.default_subroutine3_value);
   8359 			gl.getUniformSubroutineuiv(current_item.so_type, current_item.stage.subroutine4_uniform_location,
   8360 									   &current_item.stage.default_subroutine4_value);
   8361 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformSubroutineuiv() call(s) failed.");
   8362 
   8363 			current_item.stage.gl_stage = current_item.so_type;
   8364 
   8365 			if (m_po_ids[n_id] != current_item.po_id)
   8366 			{
   8367 				/* Unbind the program pipeline object */
   8368 				gl.bindProgramPipeline(0);
   8369 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed.");
   8370 			}
   8371 		} /* for (all items) */
   8372 
   8373 		/* Make sure the default subroutine choices are valid. */
   8374 		verifySubroutineUniformValues(
   8375 			TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT, /* makes the verification routine use program object descriptor */
   8376 			n_id, SUBROUTINE_UNIFORMS_SET_TO_VALID_VALUES);
   8377 
   8378 		if (m_are_pipeline_objects_supported)
   8379 		{
   8380 			gl.useProgram(0);
   8381 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   8382 
   8383 			gl.bindProgramPipeline(m_pipeline_object_ids[n_id]);
   8384 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed.");
   8385 			{
   8386 				verifySubroutineUniformValues(
   8387 					TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_PIPELINE_OBJECT, /* makes the verification routine use pipeline object descriptor */
   8388 					n_id, SUBROUTINE_UNIFORMS_SET_TO_VALID_VALUES);
   8389 			}
   8390 			gl.bindProgramPipeline(0);
   8391 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed.");
   8392 		}
   8393 	} /* for (both program descriptors) */
   8394 }
   8395 
   8396 /** Retrieves IDs of shaders OR shader program objects, depending on which of the two
   8397  *  the caller requests for.
   8398  *
   8399  *  @param retrieve_program_object_shader_ids true if the caller wishes to retrieve shader object IDs,
   8400  *                                            false to return shader program IDs.
   8401  *  @param n_id                               Index of the program/pipeline object the shaders
   8402  *                                            are a part of.
   8403  *  @param out_shader_stages                  Deref will be used to store exactly five IDs. Must not
   8404  *                                            be NULL.
   8405  **/
   8406 void FunctionalTest16::getShaderStages(bool retrieve_program_object_shader_ids, const unsigned int& n_id,
   8407 									   const _shader_stage** out_shader_stages) const
   8408 {
   8409 	if (retrieve_program_object_shader_ids)
   8410 	{
   8411 		out_shader_stages[0] = &m_po_descriptors[n_id].vertex;
   8412 		out_shader_stages[1] = &m_po_descriptors[n_id].tess_control;
   8413 		out_shader_stages[2] = &m_po_descriptors[n_id].tess_evaluation;
   8414 		out_shader_stages[3] = &m_po_descriptors[n_id].geometry;
   8415 		out_shader_stages[4] = &m_po_descriptors[n_id].fragment;
   8416 	}
   8417 	else
   8418 	{
   8419 		out_shader_stages[0] = m_vs_po_descriptors + n_id;
   8420 		out_shader_stages[1] = m_tc_po_descriptors + n_id;
   8421 		out_shader_stages[2] = m_te_po_descriptors + n_id;
   8422 		out_shader_stages[3] = m_gs_po_descriptors + n_id;
   8423 		out_shader_stages[4] = m_fs_po_descriptors + n_id;
   8424 	}
   8425 }
   8426 
   8427 /** Executes test iteration.
   8428  *
   8429  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   8430  */
   8431 tcu::TestNode::IterateResult FunctionalTest16::iterate()
   8432 {
   8433 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   8434 
   8435 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   8436 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   8437 	{
   8438 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   8439 	}
   8440 
   8441 	m_are_pipeline_objects_supported =
   8442 		m_context.getContextInfo().isExtensionSupported("GL_ARB_separate_shader_objects");
   8443 
   8444 	/* Initialize GL objects required to run the test */
   8445 	initTest();
   8446 
   8447 	/* Iterate over both pipelines/programs and verify that calling glUseProgram() /
   8448 	 * glBindProgramPipeline() / glUseProgramStages() resets subroutine uniform configuration.
   8449 	 */
   8450 	for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT); ++test_case)
   8451 	{
   8452 		if (static_cast<_test_case>(test_case) != TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT &&
   8453 			!m_are_pipeline_objects_supported)
   8454 		{
   8455 			/* Current test case requires GL_ARB_separate_shader_objects support which is
   8456 			 * unavaiable on the platform that we're testing
   8457 			 */
   8458 			continue;
   8459 		}
   8460 
   8461 		for (unsigned int n_object_id = 0; n_object_id < 2; /* pipeline/program objects allocated for the test */
   8462 			 ++n_object_id)
   8463 		{
   8464 			/* Verify that currently reported subroutine uniform values are equal to default values */
   8465 			if (test_case == TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT)
   8466 			{
   8467 				gl.useProgram(m_po_ids[n_object_id]);
   8468 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed");
   8469 			}
   8470 			else
   8471 			{
   8472 				gl.bindProgramPipeline(m_pipeline_object_ids[n_object_id]);
   8473 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed");
   8474 			}
   8475 
   8476 			verifySubroutineUniformValues(static_cast<_test_case>(test_case), n_object_id,
   8477 										  SUBROUTINE_UNIFORMS_SET_TO_DEFAULT_VALUES);
   8478 
   8479 			/* Re-configure subroutine uniforms so that they point to different subroutines than
   8480 			 * the default ones.
   8481 			 */
   8482 			const _shader_stage* stages[5 /* fs+gs+tc+te+vs */] = { DE_NULL };
   8483 
   8484 			getShaderStages(static_cast<_test_case>(test_case) == TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT,
   8485 							n_object_id, stages);
   8486 
   8487 			for (unsigned int n_stage = 0; n_stage < 5 /* fs+gs+tc+te+vs stages */; ++n_stage)
   8488 			{
   8489 				const _shader_stage& current_stage				 = *(stages[n_stage]);
   8490 				glw::GLuint			 subroutine_configuration[4] = { GL_INVALID_INDEX };
   8491 
   8492 				subroutine_configuration[0] =
   8493 					(current_stage.default_subroutine1_value == current_stage.function1_index) ?
   8494 						current_stage.function2_index :
   8495 						current_stage.function1_index;
   8496 				subroutine_configuration[1] =
   8497 					(current_stage.default_subroutine2_value == current_stage.function1_index) ?
   8498 						current_stage.function2_index :
   8499 						current_stage.function1_index;
   8500 				subroutine_configuration[2] =
   8501 					(current_stage.default_subroutine3_value == current_stage.function3_index) ?
   8502 						current_stage.function4_index :
   8503 						current_stage.function3_index;
   8504 				subroutine_configuration[3] =
   8505 					(current_stage.default_subroutine4_value == current_stage.function3_index) ?
   8506 						current_stage.function4_index :
   8507 						current_stage.function3_index;
   8508 
   8509 				gl.uniformSubroutinesuiv(current_stage.gl_stage, 4 /* count */, subroutine_configuration);
   8510 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() call failed.");
   8511 			} /* for (all stages) */
   8512 
   8513 			verifySubroutineUniformValues(static_cast<_test_case>(test_case), n_object_id,
   8514 										  SUBROUTINE_UNIFORMS_SET_TO_NONDEFAULT_VALUES);
   8515 
   8516 			/* Execute test case-specific code */
   8517 			_shader_stage cached_shader_stage_data;
   8518 			bool		  stage_reset_status[Utils::SHADER_STAGE_COUNT] = { false, false, false, false, false };
   8519 			bool		  uses_stage_reset_status						= false;
   8520 
   8521 			switch (test_case)
   8522 			{
   8523 			case TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT:
   8524 			{
   8525 				/* Switch to a different program object and then back to current PO.
   8526 				 * Subroutine uniforms should be back at their default settings, instead of
   8527 				 * the ones we've just set.
   8528 				 */
   8529 				gl.useProgram(m_po_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]);
   8530 				gl.useProgram(m_po_ids[n_object_id]);
   8531 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call(s) failed.");
   8532 
   8533 				break;
   8534 			}
   8535 
   8536 			case TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_PIPELINE_OBJECT:
   8537 			{
   8538 				/* Switch to a different pipeline object and then back to the current one.
   8539 				 * Subroutine uniforms should be back at their default settings, instead of
   8540 				 * the ones we've just set.
   8541 				 */
   8542 				gl.bindProgramPipeline(
   8543 					m_pipeline_object_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]);
   8544 				gl.bindProgramPipeline(m_pipeline_object_ids[n_object_id]);
   8545 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call(s) failed.");
   8546 
   8547 				break;
   8548 			}
   8549 
   8550 			case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_FRAGMENT_STAGE:
   8551 			{
   8552 				/* Change the fragment shader stage to a different one.
   8553 				 *
   8554 				 * Note: We also need to update internal descriptor since the subroutine/uniform
   8555 				 *       locations may be different between the two programs.
   8556 				 */
   8557 				gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_FRAGMENT_SHADER_BIT,
   8558 									m_fs_po_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]);
   8559 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
   8560 
   8561 				cached_shader_stage_data		 = m_fs_po_descriptors[n_object_id];
   8562 				m_fs_po_descriptors[n_object_id] = m_fs_po_descriptors[(n_object_id + 1) % 2];
   8563 
   8564 				stage_reset_status[Utils::SHADER_STAGE_FRAGMENT] = true;
   8565 				uses_stage_reset_status							 = true;
   8566 
   8567 				break;
   8568 			}
   8569 
   8570 			case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_GEOMETRY_STAGE:
   8571 			{
   8572 				/* Change the geometry shader stage to a different one.
   8573 				 *
   8574 				 * Note: We also need to update internal descriptor since the subroutine/uniform
   8575 				 *       locations may be different between the two programs.
   8576 				 */
   8577 				gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_GEOMETRY_SHADER_BIT,
   8578 									m_gs_po_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]);
   8579 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
   8580 
   8581 				cached_shader_stage_data		 = m_gs_po_descriptors[n_object_id];
   8582 				m_gs_po_descriptors[n_object_id] = m_gs_po_descriptors[(n_object_id + 1) % 2];
   8583 
   8584 				stage_reset_status[Utils::SHADER_STAGE_GEOMETRY] = true;
   8585 				uses_stage_reset_status							 = true;
   8586 
   8587 				break;
   8588 			}
   8589 
   8590 			case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_TESS_CONTROL_STAGE:
   8591 			{
   8592 				/* Change the tessellation control shader stage to a different one.
   8593 				 *
   8594 				 * Note: We also need to update internal descriptor since the subroutine/uniform
   8595 				 *       locations may be different between the two programs.
   8596 				 */
   8597 				gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_TESS_CONTROL_SHADER_BIT,
   8598 									m_tc_po_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]);
   8599 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
   8600 
   8601 				cached_shader_stage_data		 = m_tc_po_descriptors[n_object_id];
   8602 				m_tc_po_descriptors[n_object_id] = m_tc_po_descriptors[(n_object_id + 1) % 2];
   8603 
   8604 				stage_reset_status[Utils::SHADER_STAGE_TESSELLATION_CONTROL] = true;
   8605 				uses_stage_reset_status										 = true;
   8606 
   8607 				break;
   8608 			}
   8609 
   8610 			case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_TESS_EVALUATION_STAGE:
   8611 			{
   8612 				/* Change the tessellation evaluation shader stage to a different one.
   8613 				 *
   8614 				 * Note: We also need to update internal descriptor since the subroutine/uniform
   8615 				 *       locations may be different between the two programs.
   8616 				 */
   8617 				gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_TESS_EVALUATION_SHADER_BIT,
   8618 									m_te_po_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]);
   8619 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
   8620 
   8621 				cached_shader_stage_data		 = m_te_po_descriptors[n_object_id];
   8622 				m_te_po_descriptors[n_object_id] = m_te_po_descriptors[(n_object_id + 1) % 2];
   8623 
   8624 				stage_reset_status[Utils::SHADER_STAGE_TESSELLATION_EVALUATION] = true;
   8625 				uses_stage_reset_status											= true;
   8626 
   8627 				break;
   8628 			}
   8629 
   8630 			case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_VERTEX_STAGE:
   8631 			{
   8632 				/* Change the vertex shader stage to a different one.
   8633 				 *
   8634 				 * Note: We also need to update internal descriptor since the subroutine/uniform
   8635 				 *       locations may be different between the two programs.
   8636 				 */
   8637 				gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_VERTEX_SHADER_BIT,
   8638 									m_vs_po_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]);
   8639 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
   8640 
   8641 				cached_shader_stage_data		 = m_vs_po_descriptors[n_object_id];
   8642 				m_vs_po_descriptors[n_object_id] = m_vs_po_descriptors[(n_object_id + 1) % 2];
   8643 
   8644 				stage_reset_status[Utils::SHADER_STAGE_VERTEX] = true;
   8645 				uses_stage_reset_status						   = true;
   8646 
   8647 				break;
   8648 			}
   8649 
   8650 			default:
   8651 			{
   8652 				TCU_FAIL("Unrecognized test case");
   8653 			}
   8654 			} /* switch (test_case) */
   8655 
   8656 			/* Verify the subroutine uniform values are valid */
   8657 			if (!uses_stage_reset_status)
   8658 			{
   8659 				verifySubroutineUniformValues(static_cast<_test_case>(test_case), n_object_id,
   8660 											  SUBROUTINE_UNIFORMS_SET_TO_DEFAULT_VALUES);
   8661 			}
   8662 			else
   8663 			{
   8664 				const _shader_stage* shader_stages[Utils::SHADER_STAGE_COUNT] = { DE_NULL };
   8665 
   8666 				getShaderStages(static_cast<_test_case>(test_case) == TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT,
   8667 								n_object_id, shader_stages);
   8668 
   8669 				for (unsigned int n_shader_stage = 0; n_shader_stage < Utils::SHADER_STAGE_COUNT; ++n_shader_stage)
   8670 				{
   8671 					const _shader_stage& current_shader_stage = *(shader_stages[n_shader_stage]);
   8672 
   8673 					if (stage_reset_status[n_shader_stage])
   8674 					{
   8675 						verifySubroutineUniformValuesForShaderStage(current_shader_stage,
   8676 																	SUBROUTINE_UNIFORMS_SET_TO_DEFAULT_VALUES);
   8677 					}
   8678 					else
   8679 					{
   8680 						verifySubroutineUniformValuesForShaderStage(current_shader_stage,
   8681 																	SUBROUTINE_UNIFORMS_SET_TO_NONDEFAULT_VALUES);
   8682 					}
   8683 				} /* for (all shader stages) */
   8684 			}
   8685 
   8686 			/* Revert the changes some of the test cases appied */
   8687 			switch (test_case)
   8688 			{
   8689 			case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_FRAGMENT_STAGE:
   8690 			{
   8691 				gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_FRAGMENT_SHADER_BIT,
   8692 									m_fs_po_ids[n_object_id]);
   8693 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
   8694 
   8695 				m_fs_po_descriptors[n_object_id] = cached_shader_stage_data;
   8696 
   8697 				break;
   8698 			}
   8699 
   8700 			case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_GEOMETRY_STAGE:
   8701 			{
   8702 				gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_GEOMETRY_SHADER_BIT,
   8703 									m_gs_po_ids[n_object_id]);
   8704 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
   8705 
   8706 				m_gs_po_descriptors[n_object_id] = cached_shader_stage_data;
   8707 
   8708 				break;
   8709 			}
   8710 
   8711 			case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_TESS_CONTROL_STAGE:
   8712 			{
   8713 				gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_TESS_CONTROL_SHADER_BIT,
   8714 									m_tc_po_ids[n_object_id]);
   8715 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
   8716 
   8717 				m_tc_po_descriptors[n_object_id] = cached_shader_stage_data;
   8718 
   8719 				break;
   8720 			}
   8721 
   8722 			case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_TESS_EVALUATION_STAGE:
   8723 			{
   8724 				gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_TESS_EVALUATION_SHADER_BIT,
   8725 									m_te_po_ids[n_object_id]);
   8726 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
   8727 
   8728 				m_te_po_descriptors[n_object_id] = cached_shader_stage_data;
   8729 
   8730 				break;
   8731 			}
   8732 
   8733 			case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_VERTEX_STAGE:
   8734 			{
   8735 				gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_VERTEX_SHADER_BIT, m_vs_po_ids[n_object_id]);
   8736 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
   8737 
   8738 				m_vs_po_descriptors[n_object_id] = cached_shader_stage_data;
   8739 
   8740 				break;
   8741 			}
   8742 
   8743 			default:
   8744 				break;
   8745 			} /* switch (test_case) */
   8746 
   8747 		} /* for (all program object descriptors) */
   8748 
   8749 		/* Unbind the program object */
   8750 		gl.useProgram(0);
   8751 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   8752 	} /* for (all test cases) */
   8753 
   8754 	if (m_has_test_passed)
   8755 	{
   8756 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   8757 	}
   8758 	else
   8759 	{
   8760 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   8761 	}
   8762 
   8763 	return STOP;
   8764 }
   8765 
   8766 /** Verifies the subroutine uniform values reported by GL implementation. Depending on the test case,
   8767  *  it will either query program object stages or separate shader objects.
   8768  *
   8769  *  @param test_case    Test case the verification is to be performed for.
   8770  *  @param n_id         Index of the program/pipeline object to use for the verification
   8771  *  @param verification Verification method.
   8772  */
   8773 void FunctionalTest16::verifySubroutineUniformValues(const _test_case& test_case, const unsigned int& n_id,
   8774 													 const _subroutine_uniform_value_verification& verification)
   8775 {
   8776 	const _shader_stage* stages[] = {
   8777 		DE_NULL, /* fragment shader     stage slot */
   8778 		DE_NULL, /* geometry shader     stage slot */
   8779 		DE_NULL, /* tess control shader stage slot */
   8780 		DE_NULL, /* tess eval shader    stage slot */
   8781 		DE_NULL  /* vertex shader       stage slot */
   8782 	};
   8783 	const unsigned int n_stages = sizeof(stages) / sizeof(stages[0]);
   8784 
   8785 	/* Verify that currently reported subroutine uniform values are equal to default values */
   8786 	getShaderStages(test_case == TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT, n_id, stages);
   8787 
   8788 	for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage)
   8789 	{
   8790 		const _shader_stage& current_stage = *(stages[n_stage]);
   8791 
   8792 		verifySubroutineUniformValuesForShaderStage(current_stage, verification);
   8793 	} /* for (all items) */
   8794 }
   8795 
   8796 /** Verifies the subroutine uniform values reported by GL implementation for user-specified
   8797  *  shader stage. If the verification fails, m_has_test_passed will be set to false.
   8798  *
   8799  *  @param shader_stage Descriptor of a shader stage that should be used for the process.
   8800  *  @param verification Type of verification that should be performed.
   8801  *
   8802  **/
   8803 void FunctionalTest16::verifySubroutineUniformValuesForShaderStage(
   8804 	const _shader_stage& shader_stage, const _subroutine_uniform_value_verification& verification)
   8805 {
   8806 	const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
   8807 	glw::GLuint			  result_values[4] = { 0 };
   8808 
   8809 	gl.getUniformSubroutineuiv(shader_stage.gl_stage, shader_stage.subroutine1_uniform_location, result_values + 0);
   8810 	gl.getUniformSubroutineuiv(shader_stage.gl_stage, shader_stage.subroutine2_uniform_location, result_values + 1);
   8811 	gl.getUniformSubroutineuiv(shader_stage.gl_stage, shader_stage.subroutine3_uniform_location, result_values + 2);
   8812 	gl.getUniformSubroutineuiv(shader_stage.gl_stage, shader_stage.subroutine4_uniform_location, result_values + 3);
   8813 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformSubroutineuiv() call(s) failed.");
   8814 
   8815 	if (verification == SUBROUTINE_UNIFORMS_SET_TO_VALID_VALUES)
   8816 	{
   8817 		if (!((result_values[0] == (GLuint)shader_stage.subroutine1_uniform_location ||
   8818 			   result_values[0] == (GLuint)shader_stage.subroutine2_uniform_location) &&
   8819 			  (result_values[1] == (GLuint)shader_stage.subroutine1_uniform_location ||
   8820 			   result_values[1] == (GLuint)shader_stage.subroutine2_uniform_location) &&
   8821 			  (result_values[2] == (GLuint)shader_stage.subroutine3_uniform_location ||
   8822 			   result_values[2] == (GLuint)shader_stage.subroutine4_uniform_location) &&
   8823 			  (result_values[3] == (GLuint)shader_stage.subroutine3_uniform_location ||
   8824 			   result_values[3] == (GLuint)shader_stage.subroutine4_uniform_location)))
   8825 		{
   8826 			m_testCtx.getLog() << tcu::TestLog::Message << "SUBROUTINE_UNIFORMS_SET_TO_VALID_VALUES validation failed. "
   8827 														   "Shader stage:["
   8828 							   << Utils::getShaderStageStringFromGLEnum(shader_stage.gl_stage) << "], "
   8829 																								  "expected data:["
   8830 							   << shader_stage.subroutine1_uniform_location << " OR "
   8831 							   << shader_stage.subroutine2_uniform_location << " x 2, "
   8832 							   << shader_stage.subroutine3_uniform_location << " OR "
   8833 							   << shader_stage.subroutine4_uniform_location << " x 2], "
   8834 																			   "found data:["
   8835 							   << result_values[0] << ", " << result_values[1] << ", " << result_values[2] << ", "
   8836 							   << result_values[3] << "]." << tcu::TestLog::EndMessage;
   8837 
   8838 			m_has_test_passed = false;
   8839 		}
   8840 	}
   8841 	else if (verification == SUBROUTINE_UNIFORMS_SET_TO_DEFAULT_VALUES)
   8842 	{
   8843 		if (result_values[0] != shader_stage.default_subroutine1_value ||
   8844 			result_values[1] != shader_stage.default_subroutine2_value ||
   8845 			result_values[2] != shader_stage.default_subroutine3_value ||
   8846 			result_values[3] != shader_stage.default_subroutine4_value)
   8847 		{
   8848 			m_testCtx.getLog() << tcu::TestLog::Message
   8849 							   << "SUBROUTINE_UNIFORMS_SET_TO_DEFAULT_VALUES validation failed. "
   8850 								  "Shader stage:["
   8851 							   << Utils::getShaderStageStringFromGLEnum(shader_stage.gl_stage) << "], "
   8852 																								  "expected data:["
   8853 							   << shader_stage.default_subroutine1_value << ", "
   8854 							   << shader_stage.default_subroutine2_value << ", "
   8855 							   << shader_stage.default_subroutine3_value << ", "
   8856 							   << shader_stage.default_subroutine4_value << "], "
   8857 																			"found data:["
   8858 							   << result_values[0] << ", " << result_values[1] << ", " << result_values[2] << ", "
   8859 							   << result_values[3] << "]." << tcu::TestLog::EndMessage;
   8860 
   8861 			m_has_test_passed = false;
   8862 		}
   8863 	}
   8864 	else
   8865 	{
   8866 		DE_ASSERT(verification == SUBROUTINE_UNIFORMS_SET_TO_NONDEFAULT_VALUES);
   8867 
   8868 		if (result_values[0] == shader_stage.default_subroutine1_value ||
   8869 			result_values[1] == shader_stage.default_subroutine2_value ||
   8870 			result_values[2] == shader_stage.default_subroutine3_value ||
   8871 			result_values[3] == shader_stage.default_subroutine4_value)
   8872 		{
   8873 			m_testCtx.getLog() << tcu::TestLog::Message
   8874 							   << "SUBROUTINE_UNIFORMS_SET_TO_NONDEFAULT_VALUES validation failed. "
   8875 								  "Shader stage:["
   8876 							   << Utils::getShaderStageStringFromGLEnum(shader_stage.gl_stage) << "], "
   8877 																								  "expected data:!["
   8878 							   << shader_stage.default_subroutine1_value << ", "
   8879 							   << shader_stage.default_subroutine2_value << ", "
   8880 							   << shader_stage.default_subroutine3_value << ", "
   8881 							   << shader_stage.default_subroutine4_value << "], "
   8882 																			"found data:["
   8883 							   << result_values[0] << ", " << result_values[1] << ", " << result_values[2] << ", "
   8884 							   << result_values[3] << "]." << tcu::TestLog::EndMessage;
   8885 
   8886 			m_has_test_passed = false;
   8887 		}
   8888 	}
   8889 }
   8890 
   8891 /** Constructor.
   8892  *
   8893  *  @param context Rendering context.
   8894  *
   8895  **/
   8896 FunctionalTest17::FunctionalTest17(deqp::Context& context)
   8897 	: TestCase(context, "same_subroutine_and_subroutine_uniform_but_different_type_used_in_all_stages",
   8898 			   "Creates a program which uses the same subroutine and subroutine uniform "
   8899 			   "names for every stage (types of subroutines are different in each stage) "
   8900 			   "and then makes sure that such program compiles and works as expected.")
   8901 	, m_fbo_id(0)
   8902 	, m_fs_id(0)
   8903 	, m_gs_id(0)
   8904 	, m_has_test_passed(true)
   8905 	, m_po_id(0)
   8906 	, m_tc_id(0)
   8907 	, m_te_id(0)
   8908 	, m_to_data(DE_NULL)
   8909 	, m_to_height(4) /* arbitrary value */
   8910 	, m_to_id(0)
   8911 	, m_to_width(4) /* arbitrary value */
   8912 	, m_vao_id(0)
   8913 	, m_vs_id(0)
   8914 {
   8915 	/* Left blank intentionally */
   8916 }
   8917 
   8918 /** Deinitializes all GL objects that may have been created during test execution. */
   8919 void FunctionalTest17::deinit()
   8920 {
   8921 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   8922 
   8923 	if (m_fbo_id != 0)
   8924 	{
   8925 		gl.deleteFramebuffers(1, &m_fbo_id);
   8926 
   8927 		m_fbo_id = 0;
   8928 	}
   8929 
   8930 	if (m_fs_id != 0)
   8931 	{
   8932 		gl.deleteShader(m_fs_id);
   8933 
   8934 		m_fs_id = 0;
   8935 	}
   8936 
   8937 	if (m_gs_id != 0)
   8938 	{
   8939 		gl.deleteShader(m_gs_id);
   8940 
   8941 		m_gs_id = 0;
   8942 	}
   8943 
   8944 	if (m_po_id != 0)
   8945 	{
   8946 		gl.deleteProgram(m_po_id);
   8947 
   8948 		m_po_id = 0;
   8949 	}
   8950 
   8951 	if (m_tc_id != 0)
   8952 	{
   8953 		gl.deleteShader(m_tc_id);
   8954 
   8955 		m_tc_id = 0;
   8956 	}
   8957 
   8958 	if (m_te_id != 0)
   8959 	{
   8960 		gl.deleteShader(m_te_id);
   8961 
   8962 		m_te_id = 0;
   8963 	}
   8964 
   8965 	if (m_to_data != DE_NULL)
   8966 	{
   8967 		delete[] m_to_data;
   8968 
   8969 		m_to_data = DE_NULL;
   8970 	}
   8971 
   8972 	if (m_to_id != 0)
   8973 	{
   8974 		gl.deleteTextures(1, &m_to_id);
   8975 
   8976 		m_to_id = 0;
   8977 	}
   8978 
   8979 	if (m_vao_id != 0)
   8980 	{
   8981 		gl.deleteVertexArrays(1, &m_vao_id);
   8982 
   8983 		m_vao_id = 0;
   8984 	}
   8985 
   8986 	if (m_vs_id != 0)
   8987 	{
   8988 		gl.deleteShader(m_vs_id);
   8989 
   8990 		m_vs_id = 0;
   8991 	}
   8992 
   8993 	/* Restore original GL configuration */
   8994 	gl.patchParameteri(GL_PATCH_VERTICES, 3);
   8995 	GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteri() call failed.");
   8996 
   8997 	gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
   8998 	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call failed.");
   8999 }
   9000 
   9001 /** Retrieves body of a fragment shader that should be used by the test program.
   9002  *
   9003  *  @return Requested string.
   9004  **/
   9005 std::string FunctionalTest17::getFragmentShaderBody() const
   9006 {
   9007 	return "#version 400\n"
   9008 		   "\n"
   9009 		   "#extension GL_ARB_shader_subroutine : require\n"
   9010 		   "\n"
   9011 		   "in GS_DATA\n"
   9012 		   "{\n"
   9013 		   "    vec4 gs_data;\n"
   9014 		   "    vec4 tc_data;\n"
   9015 		   "    vec4 te_data;\n"
   9016 		   "    vec4 vs_data;\n"
   9017 		   "} gs;\n"
   9018 		   "\n"
   9019 		   "out vec4 result;\n"
   9020 		   "\n"
   9021 		   "subroutine void subroutineTypeFS(out vec4 result);\n"
   9022 		   "\n"
   9023 		   "subroutine(subroutineTypeFS) void subroutine1(out vec4 result)\n"
   9024 		   "{\n"
   9025 		   "    result = vec4(5, 6, 7, 8);\n"
   9026 		   "}\n"
   9027 		   "\n"
   9028 		   "subroutine uniform subroutineTypeFS function;\n"
   9029 		   "\n"
   9030 		   "void main()\n"
   9031 		   "{\n"
   9032 		   "    vec4 fs_data;\n"
   9033 		   "\n"
   9034 		   "    function(fs_data);\n"
   9035 		   "    result = gs.gs_data + gs.tc_data + gs.te_data + gs.vs_data + fs_data;\n"
   9036 		   "}\n";
   9037 }
   9038 
   9039 /** Retrieves body of a geometry shader that should be used by the test program.
   9040  *
   9041  *  @return Requested string.
   9042  **/
   9043 std::string FunctionalTest17::getGeometryShaderBody() const
   9044 {
   9045 	return "#version 400\n"
   9046 		   "\n"
   9047 		   "#extension GL_ARB_shader_subroutine : require\n"
   9048 		   "\n"
   9049 		   "layout(points)                           in;\n"
   9050 		   "layout(triangle_strip, max_vertices = 4) out;\n"
   9051 		   "\n"
   9052 		   "subroutine void subroutineTypeGS(out vec4 result);\n"
   9053 		   "\n"
   9054 		   "subroutine(subroutineTypeGS) void subroutine1(out vec4 result)\n"
   9055 		   "{\n"
   9056 		   "    result = vec4(4, 5, 6, 7);\n"
   9057 		   "}\n"
   9058 		   "\n"
   9059 		   "subroutine uniform subroutineTypeGS function;\n"
   9060 		   "\n"
   9061 		   "in TE_DATA\n"
   9062 		   "{\n"
   9063 		   "    vec4 tc_data;\n"
   9064 		   "    vec4 te_data;\n"
   9065 		   "    vec4 vs_data;\n"
   9066 		   "} te[];\n"
   9067 		   "\n"
   9068 		   "out GS_DATA\n"
   9069 		   "{\n"
   9070 		   "    vec4 gs_data;\n"
   9071 		   "    vec4 tc_data;\n"
   9072 		   "    vec4 te_data;\n"
   9073 		   "    vec4 vs_data;\n"
   9074 		   "} result;\n"
   9075 		   "\n"
   9076 		   "void main()\n"
   9077 		   "{\n"
   9078 		   "    function(result.gs_data);\n"
   9079 		   "    gl_Position    = vec4(1, -1, 0, 1);\n"
   9080 		   "    result.tc_data = te[0].tc_data;\n"
   9081 		   "    result.te_data = te[0].te_data;\n"
   9082 		   "    result.vs_data = te[0].vs_data;\n"
   9083 		   "    EmitVertex();\n"
   9084 		   "\n"
   9085 		   "    function(result.gs_data);\n"
   9086 		   "    gl_Position    = vec4(-1, -1, 0, 1);\n"
   9087 		   "    result.tc_data = te[0].tc_data;\n"
   9088 		   "    result.te_data = te[0].te_data;\n"
   9089 		   "    result.vs_data = te[0].vs_data;\n"
   9090 		   "    EmitVertex();\n"
   9091 		   "\n"
   9092 		   "    function(result.gs_data);\n"
   9093 		   "    gl_Position    = vec4(1, 1, 0, 1);\n"
   9094 		   "    result.tc_data = te[0].tc_data;\n"
   9095 		   "    result.te_data = te[0].te_data;\n"
   9096 		   "    result.vs_data = te[0].vs_data;\n"
   9097 		   "    EmitVertex();\n"
   9098 		   "\n"
   9099 		   "    function(result.gs_data);\n"
   9100 		   "    gl_Position    = vec4(-1, 1, 0, 1);\n"
   9101 		   "    result.tc_data = te[0].tc_data;\n"
   9102 		   "    result.te_data = te[0].te_data;\n"
   9103 		   "    result.vs_data = te[0].vs_data;\n"
   9104 		   "    EmitVertex();\n"
   9105 		   "    EndPrimitive();\n"
   9106 		   "}\n";
   9107 }
   9108 
   9109 /** Retrieves body of a tessellation control shader that should be used by the test program.
   9110  *
   9111  *  @return Requested string.
   9112  **/
   9113 std::string FunctionalTest17::getTessellationControlShaderBody() const
   9114 {
   9115 	return "#version 400\n"
   9116 		   "\n"
   9117 		   "#extension GL_ARB_shader_subroutine : require\n"
   9118 		   "\n"
   9119 		   "layout (vertices = 4) out;\n"
   9120 		   "\n"
   9121 		   "subroutine void subroutineTypeTC(out vec4 result);\n"
   9122 		   "\n"
   9123 		   "subroutine(subroutineTypeTC) void subroutine1(out vec4 result)\n"
   9124 		   "{\n"
   9125 		   "    result = vec4(2, 3, 4, 5);\n"
   9126 		   "}\n"
   9127 		   "\n"
   9128 		   "subroutine uniform subroutineTypeTC function;\n"
   9129 		   "\n"
   9130 		   "in VS_DATA\n"
   9131 		   "{\n"
   9132 		   "    vec4 vs_data;\n"
   9133 		   "} vs[];\n"
   9134 		   "\n"
   9135 		   "out TC_DATA\n"
   9136 		   "{\n"
   9137 		   "    vec4 tc_data;\n"
   9138 		   "    vec4 vs_data;\n"
   9139 		   "} result[];\n"
   9140 		   "\n"
   9141 		   "void main()\n"
   9142 		   "{\n"
   9143 		   "    gl_TessLevelInner[0] = 1.0;\n"
   9144 		   "    gl_TessLevelInner[1] = 1.0;\n"
   9145 		   "    gl_TessLevelOuter[0] = 1.0;\n"
   9146 		   "    gl_TessLevelOuter[1] = 1.0;\n"
   9147 		   "    gl_TessLevelOuter[2] = 1.0;\n"
   9148 		   "    gl_TessLevelOuter[3] = 1.0;\n"
   9149 		   "\n"
   9150 		   "    function(result[gl_InvocationID].tc_data);\n"
   9151 		   "    result[gl_InvocationID].vs_data = vs[gl_InvocationID].vs_data;\n"
   9152 		   "}\n";
   9153 }
   9154 
   9155 /** Retrieves body of a tessellation evaluation shader that should be used
   9156  *  by the test program.
   9157  *
   9158  *  @return Requested string.
   9159  **/
   9160 std::string FunctionalTest17::getTessellationEvaluationShaderBody() const
   9161 {
   9162 	return "#version 400\n"
   9163 		   "\n"
   9164 		   "#extension GL_ARB_shader_subroutine : require\n"
   9165 		   "\n"
   9166 		   "layout (quads, point_mode) in;\n"
   9167 		   "\n"
   9168 		   "subroutine void subroutineTypeTE(out vec4 result);\n"
   9169 		   "\n"
   9170 		   "subroutine(subroutineTypeTE) void subroutine1(out vec4 result)\n"
   9171 		   "{\n"
   9172 		   "    result = vec4(3, 4, 5, 6);\n"
   9173 		   "}\n"
   9174 		   "\n"
   9175 		   "subroutine uniform subroutineTypeTE function;\n"
   9176 		   "\n"
   9177 		   "in TC_DATA\n"
   9178 		   "{\n"
   9179 		   "    vec4 tc_data;\n"
   9180 		   "    vec4 vs_data;\n"
   9181 		   "} tc[];\n"
   9182 		   "\n"
   9183 		   "out TE_DATA\n"
   9184 		   "{\n"
   9185 		   "    vec4 tc_data;\n"
   9186 		   "    vec4 te_data;\n"
   9187 		   "    vec4 vs_data;\n"
   9188 		   "} result;\n"
   9189 		   "\n"
   9190 		   "void main()\n"
   9191 		   "{\n"
   9192 		   "    result.vs_data = tc[0].vs_data;\n"
   9193 		   "    result.tc_data = tc[0].tc_data;\n"
   9194 		   "    function(result.te_data);\n"
   9195 		   "}\n";
   9196 }
   9197 
   9198 /** Retrieves body of a vertex shader that should be used by the test program.
   9199  *
   9200  *  @return Requested string.
   9201  **/
   9202 std::string FunctionalTest17::getVertexShaderBody() const
   9203 {
   9204 	return "#version 400\n"
   9205 		   "\n"
   9206 		   "#extension GL_ARB_shader_subroutine : require\n"
   9207 		   "\n"
   9208 		   "out VS_DATA\n"
   9209 		   "{\n"
   9210 		   "    vec4 vs_data;\n"
   9211 		   "} result;\n"
   9212 		   "\n"
   9213 		   "subroutine void subroutineTypeVS(out vec4 result);\n"
   9214 		   "\n"
   9215 		   "subroutine(subroutineTypeVS) void subroutine1(out vec4 result)\n"
   9216 		   "{\n"
   9217 		   "    result = vec4(1, 2, 3, 4);\n"
   9218 		   "}\n"
   9219 		   "\n"
   9220 		   "subroutine uniform subroutineTypeVS function;\n"
   9221 		   "\n"
   9222 		   "void main()\n"
   9223 		   "{\n"
   9224 		   "    function(result.vs_data);\n"
   9225 		   "}\n";
   9226 }
   9227 
   9228 /** Initializes all buffers and GL objects required to run the test. */
   9229 void FunctionalTest17::initTest()
   9230 {
   9231 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9232 
   9233 	/* Configure GL_PATCH_VERTICES so that TC only takes a single patch vertex */
   9234 	gl.patchParameteri(GL_PATCH_VERTICES, 1);
   9235 	GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteri() call failed.");
   9236 
   9237 	/* Generate & bind a VAO */
   9238 	gl.genVertexArrays(1, &m_vao_id);
   9239 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
   9240 
   9241 	gl.bindVertexArray(m_vao_id);
   9242 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
   9243 
   9244 	/* Set up test program object */
   9245 	std::string fs_body = getFragmentShaderBody();
   9246 	std::string gs_body = getGeometryShaderBody();
   9247 	std::string tc_body = getTessellationControlShaderBody();
   9248 	std::string te_body = getTessellationEvaluationShaderBody();
   9249 	std::string vs_body = getVertexShaderBody();
   9250 
   9251 	if (!Utils::buildProgram(gl, vs_body, tc_body, te_body, gs_body, fs_body, DE_NULL, /* xfb_varyings */
   9252 							 DE_NULL,												   /* n_xfb_varyings */
   9253 							 &m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id))
   9254 	{
   9255 		TCU_FAIL("Failed to link test program object");
   9256 	}
   9257 
   9258 	/* Set up a texture object that will be used as a color attachment */
   9259 	gl.genTextures(1, &m_to_id);
   9260 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
   9261 
   9262 	gl.bindTexture(GL_TEXTURE_2D, m_to_id);
   9263 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   9264 
   9265 	gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
   9266 					GL_RGBA32F, m_to_width, m_to_height);
   9267 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
   9268 
   9269 	/* Set up FBO */
   9270 	gl.genFramebuffers(1, &m_fbo_id);
   9271 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
   9272 
   9273 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
   9274 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
   9275 
   9276 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_id, 0 /* level */);
   9277 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
   9278 
   9279 	/* Make sure glReadPixels() does not return misaligned data */
   9280 	gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
   9281 	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call failed.");
   9282 
   9283 	/* Initialize a buffer that will be used to store rendered data */
   9284 	m_to_data = new float[m_to_width * m_to_height * 4 /* rgba */];
   9285 }
   9286 
   9287 /** Executes test iteration.
   9288  *
   9289  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   9290  */
   9291 tcu::TestNode::IterateResult FunctionalTest17::iterate()
   9292 {
   9293 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9294 
   9295 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   9296 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   9297 	{
   9298 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   9299 	}
   9300 
   9301 	initTest();
   9302 
   9303 	/* Use the test program to render a full-screen test quad */
   9304 	gl.useProgram(m_po_id);
   9305 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   9306 
   9307 	gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
   9308 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   9309 
   9310 	/* Read back the data that was rendered */
   9311 	gl.readPixels(0, /* x */
   9312 				  0, /* y */
   9313 				  m_to_width, m_to_height, GL_RGBA, GL_FLOAT, m_to_data);
   9314 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReaDPixels() call failed.");
   9315 
   9316 	/* Verify the data */
   9317 	verifyRenderedData();
   9318 
   9319 	/** All done */
   9320 	if (m_has_test_passed)
   9321 	{
   9322 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   9323 	}
   9324 	else
   9325 	{
   9326 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   9327 	}
   9328 
   9329 	return STOP;
   9330 }
   9331 
   9332 /** Verifies the data that have been rendered by the test program.
   9333  *
   9334  *  It is assumed the rendered data have already been copied to
   9335  *  m_to_data.
   9336  *
   9337  *  If the rendered data is found to be invalid, m_has_test_passed
   9338  *  will be set to false.
   9339  **/
   9340 void FunctionalTest17::verifyRenderedData()
   9341 {
   9342 	const float epsilon			 = 1e-5f;
   9343 	const float expected_data[4] = { 15.0f, 20.0f, 25.0f, 30.0f };
   9344 
   9345 	for (unsigned int y = 0; y < m_to_height && m_has_test_passed; ++y)
   9346 	{
   9347 		const float* row_ptr = m_to_data + y * 4 /* rgba */ * m_to_width;
   9348 
   9349 		for (unsigned int x = 0; x < m_to_width && m_has_test_passed; ++x)
   9350 		{
   9351 			const float* pixel_ptr = row_ptr + 4 /* rgba */ * x;
   9352 
   9353 			if (de::abs(pixel_ptr[0] - expected_data[0]) > epsilon ||
   9354 				de::abs(pixel_ptr[1] - expected_data[1]) > epsilon ||
   9355 				de::abs(pixel_ptr[2] - expected_data[2]) > epsilon ||
   9356 				de::abs(pixel_ptr[3] - expected_data[3]) > epsilon)
   9357 			{
   9358 				m_testCtx.getLog() << tcu::TestLog::Message << "Invalid texel found at (" << x << ", " << y
   9359 								   << "): "
   9360 									  "expected:("
   9361 								   << expected_data[0] << ", " << expected_data[1] << ", " << expected_data[2] << ", "
   9362 								   << expected_data[3] << "), found:(" << pixel_ptr[0] << ", " << pixel_ptr[1] << ", "
   9363 								   << pixel_ptr[2] << ", " << pixel_ptr[3] << ")." << tcu::TestLog::EndMessage;
   9364 
   9365 				m_has_test_passed = false;
   9366 			}
   9367 		} /* for (all columns) */
   9368 	}	 /* for (all rows) */
   9369 }
   9370 
   9371 /** Constructor.
   9372  *
   9373  *  @param context Rendering context.
   9374  *
   9375  **/
   9376 FunctionalTest18_19::FunctionalTest18_19(deqp::Context& context)
   9377 	: TestCase(context, "control_flow_and_returned_subroutine_values_used_as_subroutine_input",
   9378 			   "Makes sure that calling a subroutine with argument value returned by "
   9379 			   "another subroutine works correctly. Also checks that subroutine and "
   9380 			   "subroutine uniforms work as expected when used in connection with control "
   9381 			   "flow functions.")
   9382 	, m_has_test_passed(true)
   9383 	, m_n_points_to_draw(16) /* arbitrary value */
   9384 	, m_po_id(0)
   9385 	, m_po_subroutine_divide_by_two_location(GL_INVALID_INDEX)
   9386 	, m_po_subroutine_multiply_by_four_location(GL_INVALID_INDEX)
   9387 	, m_po_subroutine_returns_false_location(GL_INVALID_INDEX)
   9388 	, m_po_subroutine_returns_true_location(GL_INVALID_INDEX)
   9389 	, m_po_subroutine_uniform_bool_operator1(-1)
   9390 	, m_po_subroutine_uniform_bool_operator2(-1)
   9391 	, m_po_subroutine_uniform_vec4_processor1(-1)
   9392 	, m_po_subroutine_uniform_vec4_processor2(-1)
   9393 	, m_xfb_bo_id(0)
   9394 	, m_vao_id(0)
   9395 	, m_vs_id(0)
   9396 {
   9397 	/* Left blank intentionally */
   9398 }
   9399 
   9400 /** De-initializes all GL objects that may have been created during test execution */
   9401 void FunctionalTest18_19::deinit()
   9402 {
   9403 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9404 
   9405 	if (m_po_id != 0)
   9406 	{
   9407 		gl.deleteProgram(m_po_id);
   9408 
   9409 		m_po_id = 0;
   9410 	}
   9411 
   9412 	if (m_vao_id != 0)
   9413 	{
   9414 		gl.deleteVertexArrays(1, &m_vao_id);
   9415 
   9416 		m_vao_id = 0;
   9417 	}
   9418 
   9419 	if (m_vs_id != 0)
   9420 	{
   9421 		gl.deleteShader(m_vs_id);
   9422 
   9423 		m_vs_id = 0;
   9424 	}
   9425 
   9426 	if (m_xfb_bo_id != 0)
   9427 	{
   9428 		gl.deleteBuffers(1, &m_xfb_bo_id);
   9429 
   9430 		m_xfb_bo_id = 0;
   9431 	}
   9432 }
   9433 
   9434 /** Executes a single test iteration using user-specified properties. If the
   9435  *  iterations fails, m_has_test_passed is set to false.
   9436  *
   9437  *  @param bool_operator1_subroutine_location Location of a subroutine to be assigned to
   9438  *                                            bool_operator1 subroutine uniform.
   9439  *  @param bool_operator2_subroutine_location Location of a subroutine to be assigned to
   9440  *                                            bool_operator2 subroutine uniform.
   9441  *  @param vec4_operator1_subroutine_location Location of a subroutine to be assigned to
   9442  *                                            vec4_operator1 subroutine uniform.
   9443  *  @param vec4_operator2_subroutine_location Location of a subroutine to be assigned to
   9444  *                                            vec4_operator2 subroutine uniform.
   9445  &**/
   9446 void FunctionalTest18_19::executeTest(glw::GLuint bool_operator1_subroutine_location,
   9447 									  glw::GLuint bool_operator2_subroutine_location,
   9448 									  glw::GLuint vec4_operator1_subroutine_location,
   9449 									  glw::GLuint vec4_operator2_subroutine_location)
   9450 {
   9451 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9452 
   9453 	/* Set up subroutines */
   9454 	glw::GLuint subroutine_configuration[4 /* total number of subroutines */] = { 0 };
   9455 
   9456 	subroutine_configuration[m_po_subroutine_uniform_bool_operator1]  = bool_operator1_subroutine_location;
   9457 	subroutine_configuration[m_po_subroutine_uniform_bool_operator2]  = bool_operator2_subroutine_location;
   9458 	subroutine_configuration[m_po_subroutine_uniform_vec4_processor1] = vec4_operator1_subroutine_location;
   9459 	subroutine_configuration[m_po_subroutine_uniform_vec4_processor2] = vec4_operator2_subroutine_location;
   9460 
   9461 	gl.useProgram(m_po_id);
   9462 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed");
   9463 
   9464 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, 4 /* count */, subroutine_configuration);
   9465 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() call failed");
   9466 
   9467 	/* Draw test-specific number of points */
   9468 	gl.beginTransformFeedback(GL_POINTS);
   9469 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed");
   9470 	{
   9471 		gl.drawArrays(GL_POINTS, 0 /* first */, m_n_points_to_draw);
   9472 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed");
   9473 	}
   9474 	gl.endTransformFeedback();
   9475 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed");
   9476 
   9477 	/* Map the BO storage into process space */
   9478 	const glw::GLvoid* xfb_data_ptr = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   9479 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
   9480 
   9481 	verifyXFBData(xfb_data_ptr, bool_operator1_subroutine_location, bool_operator2_subroutine_location,
   9482 				  vec4_operator1_subroutine_location, vec4_operator2_subroutine_location);
   9483 
   9484 	/* Unmap BO storage */
   9485 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   9486 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
   9487 }
   9488 
   9489 /** Retrieves body of a vertex shader to be used by the test. */
   9490 std::string FunctionalTest18_19::getVertexShaderBody() const
   9491 {
   9492 	return "#version 400\n"
   9493 		   "\n"
   9494 		   "subroutine bool bool_processor();\n"
   9495 		   "subroutine vec4 vec4_processor(in vec4 iparam);\n"
   9496 		   "\n"
   9497 		   "subroutine(bool_processor) bool returnsFalse()\n"
   9498 		   "{\n"
   9499 		   "    return false;\n"
   9500 		   "}\n"
   9501 		   "\n"
   9502 		   "subroutine(bool_processor) bool returnsTrue()\n"
   9503 		   "{\n"
   9504 		   "    return true;\n"
   9505 		   "}\n"
   9506 		   "\n"
   9507 		   "subroutine(vec4_processor) vec4 divideByTwo(in vec4 iparam)\n"
   9508 		   "{\n"
   9509 		   "    return iparam * vec4(0.5);\n"
   9510 		   "}\n"
   9511 		   "\n"
   9512 		   "subroutine(vec4_processor) vec4 multiplyByFour(in vec4 iparam)\n"
   9513 		   "{\n"
   9514 		   "    return iparam * vec4(4.0);\n"
   9515 		   "}\n"
   9516 		   "\n"
   9517 		   "subroutine uniform bool_processor bool_operator1;\n"
   9518 		   "subroutine uniform bool_processor bool_operator2;\n"
   9519 		   "subroutine uniform vec4_processor vec4_operator1;\n"
   9520 		   "subroutine uniform vec4_processor vec4_operator2;\n"
   9521 		   "\n"
   9522 		   "out float result;\n"
   9523 		   "\n"
   9524 		   "void main()\n"
   9525 		   "{\n"
   9526 		   "    if (bool_operator1() )\n"
   9527 		   "    {\n"
   9528 		   "        float value = float( (3 * gl_VertexID + 1) * 2);\n"
   9529 		   "\n"
   9530 		   "        while (bool_operator1() )\n"
   9531 		   "        {\n"
   9532 		   "            value /= float(gl_VertexID + 2);\n"
   9533 		   "\n"
   9534 		   "            if (value <= 1.0f) break;\n"
   9535 		   "        }\n"
   9536 		   "\n"
   9537 		   "        result = value;\n"
   9538 		   "    }\n"
   9539 		   "    else\n"
   9540 		   "    {\n"
   9541 		   "        vec4 value = vec4(gl_VertexID,     gl_VertexID + 1,\n"
   9542 		   "                          gl_VertexID + 2, gl_VertexID + 3);\n"
   9543 		   "\n"
   9544 		   "        switch (gl_VertexID % 2)\n"
   9545 		   "        {\n"
   9546 		   "            case 0:\n"
   9547 		   "            {\n"
   9548 		   "                for (int iteration = 0; iteration < gl_VertexID && bool_operator2(); ++iteration)\n"
   9549 		   "                {\n"
   9550 		   "                    value = vec4_operator2(vec4_operator1(value));\n"
   9551 		   "                }\n"
   9552 		   "\n"
   9553 		   "                break;\n"
   9554 		   "            }\n"
   9555 		   "\n"
   9556 		   "            case 1:\n"
   9557 		   "            {\n"
   9558 		   "                for (int iteration = 0; iteration < gl_VertexID * 2; ++iteration)\n"
   9559 		   "                {\n"
   9560 		   "                    value = vec4_operator1(vec4_operator2(value));\n"
   9561 		   "                }\n"
   9562 		   "\n"
   9563 		   "                break;\n"
   9564 		   "            }\n"
   9565 		   "        }\n"
   9566 		   "\n"
   9567 		   "        result = value.x + value.y + value.z + value.w;\n"
   9568 		   "\n"
   9569 		   "    }\n"
   9570 		   "}\n";
   9571 }
   9572 
   9573 /** Initializes all GL objects required to run the test. */
   9574 void FunctionalTest18_19::initTest()
   9575 {
   9576 	const glw::Functions& gl		  = m_context.getRenderContext().getFunctions();
   9577 	const char*			  varyings[1] = { "result" };
   9578 	std::string			  vs_body	 = getVertexShaderBody();
   9579 	const unsigned int	n_varyings  = sizeof(varyings) / sizeof(varyings[0]);
   9580 
   9581 	if (!Utils::buildProgram(gl, vs_body, "",						  /* tc_body */
   9582 							 "",									  /* te_body */
   9583 							 "",									  /* gs_body */
   9584 							 "",									  /* fs_body */
   9585 							 varyings, n_varyings, &m_vs_id, DE_NULL, /* out_tc_id */
   9586 							 DE_NULL,								  /* out_te_id */
   9587 							 DE_NULL,								  /* out_gs_id */
   9588 							 DE_NULL,								  /* out_fs_id */
   9589 							 &m_po_id))
   9590 	{
   9591 		TCU_FAIL("Failed to build test program object");
   9592 	}
   9593 
   9594 	/* Retrieve subroutine & subroutine uniform locations */
   9595 	m_po_subroutine_divide_by_two_location	= gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "divideByTwo");
   9596 	m_po_subroutine_multiply_by_four_location = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "multiplyByFour");
   9597 	m_po_subroutine_returns_false_location	= gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "returnsFalse");
   9598 	m_po_subroutine_returns_true_location	 = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "returnsTrue");
   9599 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() call(s) failed");
   9600 
   9601 	if (m_po_subroutine_divide_by_two_location == GL_INVALID_INDEX ||
   9602 		m_po_subroutine_multiply_by_four_location == GL_INVALID_INDEX ||
   9603 		m_po_subroutine_returns_false_location == GL_INVALID_INDEX ||
   9604 		m_po_subroutine_returns_true_location == GL_INVALID_INDEX)
   9605 	{
   9606 		TCU_FAIL("glGetSubroutineIndex() returned GL_INVALID_INDEX for a valid subroutine");
   9607 	}
   9608 
   9609 	m_po_subroutine_uniform_bool_operator1 =
   9610 		gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "bool_operator1");
   9611 	m_po_subroutine_uniform_bool_operator2 =
   9612 		gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "bool_operator2");
   9613 	m_po_subroutine_uniform_vec4_processor1 =
   9614 		gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "vec4_operator1");
   9615 	m_po_subroutine_uniform_vec4_processor2 =
   9616 		gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "vec4_operator2");
   9617 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() call(s) failed");
   9618 
   9619 	if (m_po_subroutine_uniform_bool_operator1 == -1 || m_po_subroutine_uniform_bool_operator2 == -1 ||
   9620 		m_po_subroutine_uniform_vec4_processor1 == -1 || m_po_subroutine_uniform_vec4_processor2 == -1)
   9621 	{
   9622 		TCU_FAIL("glGetSubroutineUniformLocation() returned -1 for an active subroutine uniform");
   9623 	}
   9624 
   9625 	/* Set up XFB BO */
   9626 	const unsigned int bo_size = static_cast<unsigned int>(sizeof(float) * m_n_points_to_draw);
   9627 
   9628 	gl.genBuffers(1, &m_xfb_bo_id);
   9629 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
   9630 
   9631 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id);
   9632 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
   9633 
   9634 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id);
   9635 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
   9636 
   9637 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bo_size, DE_NULL /* data */, GL_STATIC_COPY);
   9638 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
   9639 
   9640 	/* Set up a VAO */
   9641 	gl.genVertexArrays(1, &m_vao_id);
   9642 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
   9643 
   9644 	gl.bindVertexArray(m_vao_id);
   9645 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
   9646 }
   9647 
   9648 /** Executes test iteration.
   9649  *
   9650  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   9651  */
   9652 tcu::TestNode::IterateResult FunctionalTest18_19::iterate()
   9653 {
   9654 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   9655 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   9656 	{
   9657 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   9658 	}
   9659 
   9660 	/* Initialize all GL objects required to run the test */
   9661 	initTest();
   9662 
   9663 	/* Iterate over all subroutine permutations */
   9664 	const glw::GLuint subroutine_bool_operators[] = { m_po_subroutine_returns_false_location,
   9665 													  m_po_subroutine_returns_true_location };
   9666 	const unsigned int n_subroutine_bool_operators =
   9667 		sizeof(subroutine_bool_operators) / sizeof(subroutine_bool_operators[0]);
   9668 
   9669 	const glw::GLuint subroutine_vec4_operators[] = { m_po_subroutine_divide_by_two_location,
   9670 													  m_po_subroutine_multiply_by_four_location };
   9671 	const unsigned int n_subroutine_vec4_operators =
   9672 		sizeof(subroutine_vec4_operators) / sizeof(subroutine_vec4_operators[0]);
   9673 
   9674 	for (unsigned int n_subroutine_uniform_bool_operator1 = 0;
   9675 		 n_subroutine_uniform_bool_operator1 < n_subroutine_bool_operators; ++n_subroutine_uniform_bool_operator1)
   9676 	{
   9677 		for (unsigned int n_subroutine_uniform_bool_operator2 = 0;
   9678 			 n_subroutine_uniform_bool_operator2 < n_subroutine_bool_operators; ++n_subroutine_uniform_bool_operator2)
   9679 		{
   9680 			for (unsigned int n_subroutine_uniform_vec4_operator1 = 0;
   9681 				 n_subroutine_uniform_vec4_operator1 < n_subroutine_vec4_operators;
   9682 				 ++n_subroutine_uniform_vec4_operator1)
   9683 			{
   9684 				for (unsigned int n_subroutine_uniform_vec4_operator2 = 0;
   9685 					 n_subroutine_uniform_vec4_operator2 < n_subroutine_vec4_operators;
   9686 					 ++n_subroutine_uniform_vec4_operator2)
   9687 				{
   9688 					executeTest(subroutine_bool_operators[n_subroutine_uniform_bool_operator1],
   9689 								subroutine_bool_operators[n_subroutine_uniform_bool_operator2],
   9690 								subroutine_vec4_operators[n_subroutine_uniform_vec4_operator1],
   9691 								subroutine_vec4_operators[n_subroutine_uniform_vec4_operator2]);
   9692 				} /* for (all subroutine vec4 operator subroutines used for processor2) */
   9693 			}	 /* for (all subroutine vec4 operator subroutines used for processor1) */
   9694 		}		  /* for (all subroutine bool operator subroutines used for operator2) */
   9695 	}			  /* for (all subroutine bool operator subroutines used for operator1) */
   9696 
   9697 	/* All done */
   9698 	if (m_has_test_passed)
   9699 	{
   9700 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   9701 	}
   9702 	else
   9703 	{
   9704 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   9705 	}
   9706 
   9707 	return STOP;
   9708 }
   9709 
   9710 /** Divides input argument by two. The result value is returned to the
   9711  *  caller.
   9712  *
   9713  *  @param data Input value.
   9714  *
   9715  *  @return As per description.
   9716  **/
   9717 tcu::Vec4 FunctionalTest18_19::vec4operator_div2(tcu::Vec4 data)
   9718 {
   9719 	return data * 0.5f;
   9720 }
   9721 
   9722 /** Multiplies input argument by four. The result value is returned to the
   9723  *  caller.
   9724  *
   9725  *  @param data Input value.
   9726  *
   9727  *  @return As per description.
   9728  **/
   9729 tcu::Vec4 FunctionalTest18_19::vec4operator_mul4(tcu::Vec4 data)
   9730 {
   9731 	return data * 4.0f;
   9732 }
   9733 
   9734 /** Verifies data XFBed out by the vertex shader. It is assumed the subroutines were configured
   9735  *  as per passed arguments, prior to the draw call.
   9736  *
   9737  *  If the result data is found to be invalid, m_has_test_passed is set to false.
   9738  *
   9739  *  @param data                               XFBed data.
   9740  *  @param bool_operator1_subroutine_location Location of a subroutine to be assigned to
   9741  *                                            bool_operator1 subroutine uniform.
   9742  *  @param bool_operator2_subroutine_location Location of a subroutine to be assigned to
   9743  *                                            bool_operator2 subroutine uniform.
   9744  *  @param vec4_operator1_subroutine_location Location of a subroutine to be assigned to
   9745  *                                            vec4_operator1 subroutine uniform.
   9746  *  @param vec4_operator2_subroutine_location Location of a subroutine to be assigned to
   9747  *                                            vec4_operator2 subroutine uniform.
   9748  */
   9749 void FunctionalTest18_19::verifyXFBData(const glw::GLvoid* data, glw::GLuint bool_operator1_subroutine_location,
   9750 										glw::GLuint bool_operator2_subroutine_location,
   9751 										glw::GLuint vec4_operator1_subroutine_location,
   9752 										glw::GLuint vec4_operator2_subroutine_location)
   9753 {
   9754 	bool				bool_operator1_result = false;
   9755 	bool				bool_operator2_result = false;
   9756 	const float			epsilon				  = 1e-5f;
   9757 	PFNVEC4OPERATORPROC pVec4Operator1		  = NULL;
   9758 	PFNVEC4OPERATORPROC pVec4Operator2		  = NULL;
   9759 	const glw::GLfloat* traveller_ptr		  = (const glw::GLfloat*)data;
   9760 
   9761 	bool_operator1_result = (bool_operator1_subroutine_location == m_po_subroutine_returns_true_location);
   9762 	bool_operator2_result = (bool_operator2_subroutine_location == m_po_subroutine_returns_true_location);
   9763 	pVec4Operator1		  = (vec4_operator1_subroutine_location == m_po_subroutine_divide_by_two_location) ?
   9764 						 vec4operator_div2 :
   9765 						 vec4operator_mul4;
   9766 	pVec4Operator2 = (vec4_operator2_subroutine_location == m_po_subroutine_divide_by_two_location) ?
   9767 						 vec4operator_div2 :
   9768 						 vec4operator_mul4;
   9769 
   9770 	for (unsigned int n_vertex = 0; n_vertex < m_n_points_to_draw; ++n_vertex)
   9771 	{
   9772 		float expected_value = 0.0f;
   9773 
   9774 		if (bool_operator1_result)
   9775 		{
   9776 			float value = float((3 * n_vertex + 1) * 2);
   9777 
   9778 			while (bool_operator1_result)
   9779 			{
   9780 				value /= float(n_vertex + 2);
   9781 
   9782 				if (value <= 1.0f)
   9783 					break;
   9784 			}
   9785 
   9786 			expected_value = value;
   9787 		}
   9788 		else
   9789 		{
   9790 			tcu::Vec4 value((float)n_vertex, (float)n_vertex + 1, (float)n_vertex + 2, (float)n_vertex + 3);
   9791 
   9792 			switch (n_vertex % 2)
   9793 			{
   9794 			case 0:
   9795 			{
   9796 				for (unsigned int iteration = 0; iteration < n_vertex && bool_operator2_result; ++iteration)
   9797 				{
   9798 					value = pVec4Operator2(pVec4Operator1(value));
   9799 				}
   9800 
   9801 				break;
   9802 			}
   9803 
   9804 			case 1:
   9805 			{
   9806 				for (unsigned int iteration = 0; iteration < n_vertex * 2; ++iteration)
   9807 				{
   9808 					value = pVec4Operator1(pVec4Operator2(value));
   9809 				}
   9810 
   9811 				break;
   9812 			}
   9813 			} /* switch (n_vertex % 2) */
   9814 
   9815 			expected_value = value.x() + value.y() + value.z() + value.w();
   9816 		}
   9817 
   9818 		if (de::abs(expected_value - *traveller_ptr) > epsilon)
   9819 		{
   9820 			m_testCtx.getLog() << tcu::TestLog::Message << "XFBed data was found to be invalid at index [" << n_vertex
   9821 							   << "]"
   9822 								  "for the following subroutine location configuration:"
   9823 								  " bool_operator1_subroutine_location:["
   9824 							   << bool_operator1_subroutine_location << "]"
   9825 																		" bool_operator2_subroutine_location:["
   9826 							   << bool_operator2_subroutine_location << "]"
   9827 																		" vec4_operator1_subroutine_location:["
   9828 							   << vec4_operator1_subroutine_location << "]"
   9829 																		" vec4_operator2_subroutine_location:["
   9830 							   << vec4_operator2_subroutine_location << "];"
   9831 																		" expected data:"
   9832 							   << expected_value << ", found:" << *traveller_ptr << tcu::TestLog::EndMessage;
   9833 
   9834 			m_has_test_passed = false;
   9835 		}
   9836 
   9837 		++traveller_ptr;
   9838 	} /* for (all drawn points) */
   9839 }
   9840 
   9841 /** Constructor.
   9842  *
   9843  *  @param context Rendering context.
   9844  *
   9845  **/
   9846 NegativeTest1::NegativeTest1(deqp::Context& context)
   9847 	: TestCase(context, "subroutine_errors", "Verifies all GL_INVALID_OPERATION, GL_INVALID_VALUE, GL_INVALID ENUM "
   9848 											 "errors related to subroutine usage are properly generated.")
   9849 	, m_has_test_passed(true)
   9850 	, m_po_active_subroutine_uniform_locations(0)
   9851 	, m_po_active_subroutine_uniforms(0)
   9852 	, m_po_active_subroutines(0)
   9853 	, m_po_subroutine_uniform_function_index(-1)
   9854 	, m_po_subroutine_uniform_function2_index(-1)
   9855 	, m_po_subroutine_test1_index(GL_INVALID_INDEX)
   9856 	, m_po_subroutine_test2_index(GL_INVALID_INDEX)
   9857 	, m_po_subroutine_test3_index(GL_INVALID_INDEX)
   9858 	, m_po_not_linked_id(0)
   9859 	, m_po_id(0)
   9860 	, m_vs_id(0)
   9861 {
   9862 	/* Left blank intentionally */
   9863 }
   9864 
   9865 /** Deinitializes all GL objects that may have been created during
   9866  *  test execution.
   9867  **/
   9868 void NegativeTest1::deinit()
   9869 {
   9870 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9871 
   9872 	if (m_po_id != 0)
   9873 	{
   9874 		gl.deleteProgram(m_po_id);
   9875 
   9876 		m_po_id = 0;
   9877 	}
   9878 
   9879 	if (m_po_not_linked_id != 0)
   9880 	{
   9881 		gl.deleteProgram(m_po_not_linked_id);
   9882 
   9883 		m_po_not_linked_id = 0;
   9884 	}
   9885 
   9886 	if (m_vs_id != 0)
   9887 	{
   9888 		gl.deleteShader(m_vs_id);
   9889 
   9890 		m_vs_id = 0;
   9891 	}
   9892 }
   9893 
   9894 /** Initializes all GL objects required to run the test.  */
   9895 void NegativeTest1::initTest()
   9896 {
   9897 	glw::GLint			  compile_status = GL_FALSE;
   9898 	const glw::Functions& gl			 = m_context.getRenderContext().getFunctions();
   9899 
   9900 	/* Create program objects */
   9901 	m_po_not_linked_id = gl.createProgram();
   9902 	m_po_id			   = gl.createProgram();
   9903 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed.");
   9904 
   9905 	/* Create vertex shader object */
   9906 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
   9907 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
   9908 
   9909 	/* Set up vertex shader */
   9910 	const char* vs_body = "#version 400\n"
   9911 						  "\n"
   9912 						  "#extension GL_ARB_shader_subroutine : require\n"
   9913 						  "\n"
   9914 						  "subroutine void subroutineType (out ivec2 arg);\n"
   9915 						  "subroutine void subroutineType2(out ivec4 arg);\n"
   9916 						  "\n"
   9917 						  "subroutine(subroutineType) void test1(out ivec2 arg)\n"
   9918 						  "{\n"
   9919 						  "    arg = ivec2(1, 2);\n"
   9920 						  "}\n"
   9921 						  "subroutine(subroutineType) void test2(out ivec2 arg)\n"
   9922 						  "{\n"
   9923 						  "    arg = ivec2(3,4);\n"
   9924 						  "}\n"
   9925 						  "subroutine(subroutineType2) void test3(out ivec4 arg)\n"
   9926 						  "{\n"
   9927 						  "    arg = ivec4(1, 2, 3, 4);\n"
   9928 						  "}\n"
   9929 						  "\n"
   9930 						  "subroutine uniform subroutineType  function;\n"
   9931 						  "subroutine uniform subroutineType2 function2;\n"
   9932 						  "\n"
   9933 						  "void main()\n"
   9934 						  "{\n"
   9935 						  "    ivec2 test;\n"
   9936 						  "    ivec4 test2;\n"
   9937 						  "\n"
   9938 						  "    function(test);\n"
   9939 						  "\n"
   9940 						  "    if (test.x > 2)\n"
   9941 						  "    {\n"
   9942 						  "        gl_Position = vec4(1);\n"
   9943 						  "    }\n"
   9944 						  "    else\n"
   9945 						  "    {\n"
   9946 						  "        function2(test2);\n"
   9947 						  "\n"
   9948 						  "        gl_Position = vec4(float(test2.x) );\n"
   9949 						  "    }\n"
   9950 						  "}\n";
   9951 
   9952 	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */);
   9953 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
   9954 
   9955 	gl.compileShader(m_vs_id);
   9956 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed");
   9957 
   9958 	gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
   9959 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed");
   9960 
   9961 	if (compile_status == GL_FALSE)
   9962 	{
   9963 		TCU_FAIL("Shader compilation failed");
   9964 	}
   9965 
   9966 	/* Set up & link the test program object */
   9967 	glw::GLint link_status = GL_FALSE;
   9968 
   9969 	gl.attachShader(m_po_id, m_vs_id);
   9970 	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
   9971 
   9972 	gl.linkProgram(m_po_id);
   9973 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
   9974 
   9975 	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
   9976 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
   9977 
   9978 	if (link_status == GL_FALSE)
   9979 	{
   9980 		TCU_FAIL("Program linking failed");
   9981 	}
   9982 
   9983 	/* Query test program object's properties */
   9984 	gl.getProgramStageiv(m_po_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS,
   9985 						 &m_po_active_subroutine_uniform_locations);
   9986 	gl.getProgramStageiv(m_po_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &m_po_active_subroutine_uniforms);
   9987 	gl.getProgramStageiv(m_po_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINES, &m_po_active_subroutines);
   9988 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramStageiv() call(s) failed.");
   9989 
   9990 	if (m_po_active_subroutine_uniform_locations != 2)
   9991 	{
   9992 		TCU_FAIL("Invalid GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS value returned");
   9993 	}
   9994 
   9995 	m_po_subroutine_test1_index = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "test1");
   9996 	m_po_subroutine_test2_index = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "test2");
   9997 	m_po_subroutine_test3_index = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "test3");
   9998 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() call(s) failed.");
   9999 
   10000 	if (m_po_subroutine_test1_index == GL_INVALID_INDEX || m_po_subroutine_test2_index == GL_INVALID_INDEX ||
   10001 		m_po_subroutine_test3_index == GL_INVALID_INDEX)
   10002 	{
   10003 		TCU_FAIL("Invalid subroutine index returned");
   10004 	}
   10005 
   10006 	m_po_subroutine_uniform_function_index  = gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "function");
   10007 	m_po_subroutine_uniform_function2_index = gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "function2");
   10008 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() call(s) failed.");
   10009 
   10010 	if (m_po_subroutine_uniform_function_index == -1 || m_po_subroutine_uniform_function2_index == -1)
   10011 	{
   10012 		TCU_FAIL("Invalid subroutine uniform index returned");
   10013 	}
   10014 }
   10015 
   10016 /** Executes test iteration.
   10017  *
   10018  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   10019  */
   10020 tcu::TestNode::IterateResult NegativeTest1::iterate()
   10021 {
   10022 	glw::GLenum			  error_code = GL_NO_ERROR;
   10023 	const glw::Functions& gl		 = m_context.getRenderContext().getFunctions();
   10024 
   10025 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   10026 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   10027 	{
   10028 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   10029 	}
   10030 
   10031 	/* Initialize GL objects required to run the test */
   10032 	initTest();
   10033 
   10034 	/* The error INVALID_OPERATION is generated by GetSubroutineUniformLocation
   10035 	 * if the program object identified by <program> has not been successfully
   10036 	 * linked.
   10037 	 */
   10038 	gl.getSubroutineUniformLocation(m_po_not_linked_id, GL_FRAGMENT_SHADER, "subroutine_uniform_name");
   10039 
   10040 	error_code = gl.getError();
   10041 
   10042 	if (error_code != GL_INVALID_OPERATION)
   10043 	{
   10044 		m_testCtx.getLog() << tcu::TestLog::Message
   10045 						   << "glGetSubroutineUniformLocation() does not generate GL_INVALID_OPERATION "
   10046 							  "error code when called for a non-linked program object."
   10047 						   << tcu::TestLog::EndMessage;
   10048 
   10049 		m_has_test_passed = false;
   10050 	}
   10051 
   10052 	/* The error INVALID_VALUE is generated by GetActiveSubroutineUniformiv or
   10053 	 * GetActiveSubroutineUniformName if <index> is greater than or equal to the
   10054 	 * value of ACTIVE_SUBROUTINE_UNIFORMS for the shader stage.
   10055 	 */
   10056 	glw::GLint temp_length = 0;
   10057 	glw::GLint temp_values = 0;
   10058 
   10059 	gl.getActiveSubroutineUniformiv(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutine_uniforms,
   10060 									GL_NUM_COMPATIBLE_SUBROUTINES, &temp_values);
   10061 	error_code = gl.getError();
   10062 
   10063 	if (error_code == GL_INVALID_VALUE)
   10064 	{
   10065 		gl.getActiveSubroutineUniformiv(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutine_uniforms + 1,
   10066 										GL_NUM_COMPATIBLE_SUBROUTINES, &temp_values);
   10067 
   10068 		error_code = gl.getError();
   10069 	}
   10070 
   10071 	if (error_code != GL_INVALID_VALUE)
   10072 	{
   10073 		m_testCtx.getLog() << tcu::TestLog::Message
   10074 						   << "glGetActiveSubroutineUniformiv() does not generate GL_INVALID_VALUE "
   10075 							  "when passed <index> argument that is greater than or equal to "
   10076 							  "the value of GL_ACTIVE_SUBROUTINE_UNIFORMS."
   10077 						   << tcu::TestLog::EndMessage;
   10078 
   10079 		m_has_test_passed = false;
   10080 	}
   10081 
   10082 	gl.getActiveSubroutineUniformName(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutine_uniforms, 0, /* bufsize */
   10083 									  &temp_length, DE_NULL);										 /* name */
   10084 	error_code = gl.getError();
   10085 
   10086 	if (error_code == GL_INVALID_VALUE)
   10087 	{
   10088 		gl.getActiveSubroutineUniformName(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutine_uniforms + 1,
   10089 										  0,					  /* bufsize */
   10090 										  &temp_length, DE_NULL); /* name */
   10091 
   10092 		error_code = gl.getError();
   10093 	}
   10094 
   10095 	if (error_code != GL_INVALID_VALUE)
   10096 	{
   10097 		m_testCtx.getLog() << tcu::TestLog::Message
   10098 						   << "glGetActiveSubroutineUniformName() does not generate GL_INVALID_VALUE "
   10099 							  "when passed <index> argument that is greater than or equal to "
   10100 							  "the value of GL_ACTIVE_SUBROUTINE_UNIFORMS."
   10101 						   << tcu::TestLog::EndMessage;
   10102 
   10103 		m_has_test_passed = false;
   10104 	}
   10105 
   10106 	/* The error INVALID_VALUE is generated by GetActiveSubroutineName if <index>
   10107 	 * is greater than or equal to the value of ACTIVE_SUBROUTINES for the shader
   10108 	 * stage.
   10109 	 */
   10110 	gl.getActiveSubroutineName(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutines, 0, /* bufsize */
   10111 							   &temp_length, DE_NULL);								  /* name */
   10112 	error_code = gl.getError();
   10113 
   10114 	if (error_code == GL_INVALID_VALUE)
   10115 	{
   10116 		gl.getActiveSubroutineName(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutines + 1, 0, /* bufsize */
   10117 								   &temp_length, DE_NULL);									  /* name */
   10118 
   10119 		error_code = gl.getError();
   10120 	}
   10121 
   10122 	if (error_code != GL_INVALID_VALUE)
   10123 	{
   10124 		m_testCtx.getLog() << tcu::TestLog::Message << "glGetActiveSubroutineName() does not generate GL_INVALID_VALUE "
   10125 													   "when passed <index> argument that is greater than or equal to "
   10126 													   "the value of GL_ACTIVE_SUBROUTINES."
   10127 						   << tcu::TestLog::EndMessage;
   10128 
   10129 		m_has_test_passed = false;
   10130 	}
   10131 
   10132 	/* The error INVALID_VALUE is generated by UniformSubroutinesuiv if <count>
   10133 	 * is not equal to the value of ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS for the
   10134 	 * shader stage <shadertype>.
   10135 	 */
   10136 	glw::GLuint index = 0;
   10137 
   10138 	gl.useProgram(m_po_id);
   10139 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   10140 
   10141 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations - 1, &index);
   10142 	error_code = gl.getError();
   10143 
   10144 	if (error_code == GL_INVALID_VALUE)
   10145 	{
   10146 		gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations + 1, &index);
   10147 
   10148 		error_code = gl.getError();
   10149 	}
   10150 
   10151 	if (error_code != GL_INVALID_VALUE)
   10152 	{
   10153 		m_testCtx.getLog() << tcu::TestLog::Message << "glUniformSubroutinesiv() does not generate GL_INVALID_VALUE "
   10154 													   "when passed <count> argument that is not equal to the value of "
   10155 													   "GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS."
   10156 						   << tcu::TestLog::EndMessage;
   10157 
   10158 		m_has_test_passed = false;
   10159 	}
   10160 
   10161 	/* The error INVALID_VALUE is generated by UniformSubroutinesuiv if any value
   10162 	 * in <indices> is greater than or equal to the value of ACTIVE_SUBROUTINES
   10163 	 * for the shader stage.
   10164 	 */
   10165 	glw::GLuint invalid_subroutine_indices[4] = { (GLuint)m_po_active_subroutines, (GLuint)m_po_active_subroutines,
   10166 												  (GLuint)m_po_active_subroutines + 1,
   10167 												  (GLuint)m_po_active_subroutines + 1 };
   10168 
   10169 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations, /* count */
   10170 							 invalid_subroutine_indices + 0);
   10171 	error_code = gl.getError();
   10172 
   10173 	if (error_code == GL_INVALID_VALUE)
   10174 	{
   10175 		gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations,
   10176 								 invalid_subroutine_indices + 2);
   10177 
   10178 		error_code = gl.getError();
   10179 	}
   10180 
   10181 	if (error_code != GL_INVALID_VALUE)
   10182 	{
   10183 		m_testCtx.getLog() << tcu::TestLog::Message << "glUniformSubroutinesuiv() does not generate GL_INVALID_VALUE "
   10184 													   "when the value passed via <indices> argument is greater than "
   10185 													   "or equal to the value of GL_ACTIVE_SUBROUTINES."
   10186 						   << tcu::TestLog::EndMessage;
   10187 
   10188 		m_has_test_passed = false;
   10189 	}
   10190 
   10191 	/* The error INVALID_OPERATION is generated by UniformSubroutinesuiv() if any
   10192 	 * subroutine index in <indices> identifies a subroutine not associated with
   10193 	 * the type of the subroutine uniform variable assigned to the corresponding
   10194 	 * location.
   10195 	 */
   10196 	glw::GLuint invalid_subroutine_indices2[2] = { m_po_subroutine_test1_index, m_po_subroutine_test1_index };
   10197 
   10198 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations, invalid_subroutine_indices2);
   10199 	error_code = gl.getError();
   10200 
   10201 	if (error_code != GL_INVALID_OPERATION)
   10202 	{
   10203 		m_testCtx.getLog() << tcu::TestLog::Message
   10204 						   << "glUniformSubroutinesuiv() does not generate GL_INVALID_OPERATION "
   10205 							  "when the subroutine index passed via <indices> argument identifies"
   10206 							  "a subroutine not associated with the type of the subroutine uniform "
   10207 							  "assigned to the corresponding location."
   10208 						   << tcu::TestLog::EndMessage;
   10209 
   10210 		m_has_test_passed = false;
   10211 	}
   10212 
   10213 	/* The error INVALID_OPERATION is generated by UniformSubroutinesuiv if no
   10214 	 * program is active.
   10215 	 */
   10216 	glw::GLuint valid_subroutine_locations[2] = { 0 };
   10217 
   10218 	valid_subroutine_locations[m_po_subroutine_uniform_function_index]  = m_po_subroutine_test1_index;
   10219 	valid_subroutine_locations[m_po_subroutine_uniform_function2_index] = m_po_subroutine_test3_index;
   10220 
   10221 	gl.useProgram(0);
   10222 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   10223 
   10224 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations, valid_subroutine_locations);
   10225 	error_code = gl.getError();
   10226 
   10227 	if (error_code != GL_INVALID_OPERATION)
   10228 	{
   10229 		m_testCtx.getLog() << tcu::TestLog::Message
   10230 						   << "glUniformSubroutinesuiv() does not generate GL_INVALID_OPERATION "
   10231 							  "when called without an active program object."
   10232 						   << tcu::TestLog::EndMessage;
   10233 
   10234 		m_has_test_passed = false;
   10235 	}
   10236 
   10237 	/* The error INVALID_VALUE is generated by GetUniformSubroutineuiv if
   10238 	 * <location> is greater than or equal to the value of
   10239 	 * ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS for the shader stage.
   10240 	 */
   10241 	glw::GLuint temp_value = 0;
   10242 
   10243 	gl.useProgram(m_po_id);
   10244 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   10245 
   10246 	gl.getUniformSubroutineuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations, &temp_value);
   10247 	error_code = gl.getError();
   10248 
   10249 	if (error_code == GL_INVALID_VALUE)
   10250 	{
   10251 		gl.getUniformSubroutineuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations + 1, &temp_value);
   10252 		error_code = gl.getError();
   10253 	}
   10254 
   10255 	if (error_code != GL_INVALID_VALUE)
   10256 	{
   10257 		m_testCtx.getLog() << tcu::TestLog::Message
   10258 						   << "glGetUniformSubroutineuiv() does not generate GL_INVALID_VALUE "
   10259 							  "when called for location that is greater than or equal to the value "
   10260 							  "of GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS."
   10261 						   << tcu::TestLog::EndMessage;
   10262 
   10263 		m_has_test_passed = false;
   10264 	}
   10265 
   10266 	/* The error INVALID_OPERATION is generated by GetUniformSubroutineuiv if no
   10267 	 * program is active for the shader stage identified by <shadertype>.
   10268 	 */
   10269 	const glw::GLenum undefined_shader_stages[] = { GL_FRAGMENT_SHADER, GL_GEOMETRY_SHADER, GL_TESS_CONTROL_SHADER,
   10270 													GL_TESS_EVALUATION_SHADER };
   10271 	const unsigned int n_undefined_shader_stages = sizeof(undefined_shader_stages) / sizeof(undefined_shader_stages[0]);
   10272 
   10273 	for (unsigned int n_undefined_shader_stage = 0; n_undefined_shader_stage < n_undefined_shader_stages;
   10274 		 ++n_undefined_shader_stage)
   10275 	{
   10276 		glw::GLenum shader_stage = undefined_shader_stages[n_undefined_shader_stage];
   10277 
   10278 		gl.getUniformSubroutineuiv(shader_stage, 0, /* location */
   10279 								   &temp_value);
   10280 		error_code = gl.getError();
   10281 
   10282 		if (error_code != GL_INVALID_OPERATION)
   10283 		{
   10284 			m_testCtx.getLog() << tcu::TestLog::Message
   10285 							   << "glGetUniformSubroutineuiv() does not generate GL_INVALID_OPERATION "
   10286 								  "when called for a shader stage that is not defined for active "
   10287 								  "program object."
   10288 							   << tcu::TestLog::EndMessage;
   10289 
   10290 			m_has_test_passed = false;
   10291 		}
   10292 	} /* for (all undefined shader stages) */
   10293 
   10294 	/* All done */
   10295 	if (m_has_test_passed)
   10296 	{
   10297 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   10298 	}
   10299 	else
   10300 	{
   10301 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   10302 	}
   10303 
   10304 	return STOP;
   10305 }
   10306 
   10307 /** Constructor
   10308  *
   10309  *  @param context Rendering context.
   10310  *
   10311  **/
   10312 NegativeTest2::NegativeTest2(deqp::Context& context)
   10313 	: TestCase(context, "subroutine_uniform_scope", "Verifies subroutine uniforms declared in shader stage A"
   10314 													"cannot be accessed from a different stage.")
   10315 	, m_fs_id(0)
   10316 	, m_gs_id(0)
   10317 	, m_has_test_passed(true)
   10318 	, m_po_id(0)
   10319 	, m_tc_id(0)
   10320 	, m_te_id(0)
   10321 	, m_vs_id(0)
   10322 {
   10323 	/* Left blank intentionally */
   10324 }
   10325 
   10326 /** Deinitializes all GL objects that may have been created during test execution */
   10327 void NegativeTest2::deinit()
   10328 {
   10329 	deinitGLObjects();
   10330 }
   10331 
   10332 /** Deinitializes all GL objects that may have been created during test execution */
   10333 void NegativeTest2::deinitGLObjects()
   10334 {
   10335 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   10336 
   10337 	if (m_fs_id != 0)
   10338 	{
   10339 		gl.deleteShader(m_fs_id);
   10340 
   10341 		m_fs_id = 0;
   10342 	}
   10343 
   10344 	if (m_gs_id != 0)
   10345 	{
   10346 		gl.deleteShader(m_gs_id);
   10347 
   10348 		m_gs_id = 0;
   10349 	}
   10350 
   10351 	if (m_tc_id != 0)
   10352 	{
   10353 		gl.deleteShader(m_tc_id);
   10354 
   10355 		m_tc_id = 0;
   10356 	}
   10357 
   10358 	if (m_te_id != 0)
   10359 	{
   10360 		gl.deleteShader(m_te_id);
   10361 
   10362 		m_te_id = 0;
   10363 	}
   10364 
   10365 	if (m_vs_id != 0)
   10366 	{
   10367 		gl.deleteShader(m_vs_id);
   10368 
   10369 		m_vs_id = 0;
   10370 	}
   10371 
   10372 	if (m_po_id != 0)
   10373 	{
   10374 		gl.deleteProgram(m_po_id);
   10375 
   10376 		m_po_id = 0;
   10377 	}
   10378 }
   10379 
   10380 /** Builds an offending program object and tries to link it. We're either expecting
   10381  *  a compile-time or link-time error here.
   10382  *
   10383  *  If the program object builds successfully, the test has failed.
   10384  *
   10385  *  @param referencing_stage Shader stage which defines a subroutine uniform that
   10386  *                           should be called from fragment/geometry/tess control/
   10387  *                           tess evaluation/vertex shader stages.
   10388  *
   10389  **/
   10390 void NegativeTest2::executeTestCase(const Utils::_shader_stage& referencing_stage)
   10391 {
   10392 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   10393 
   10394 	const std::string fs_body = getFragmentShaderBody(referencing_stage);
   10395 	const std::string gs_body = getGeometryShaderBody(referencing_stage);
   10396 	const std::string tc_body = getTessellationControlShaderBody(referencing_stage);
   10397 	const std::string te_body = getTessellationEvaluationShaderBody(referencing_stage);
   10398 	const std::string vs_body = getVertexShaderBody(referencing_stage);
   10399 
   10400 	if (Utils::buildProgram(gl, vs_body, tc_body, te_body, gs_body, fs_body, NULL, /* xfb_varyings */
   10401 							0,													   /* n_xfb_varyings */
   10402 							&m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id))
   10403 	{
   10404 		/* Test program should not have built correctly ! */
   10405 		m_testCtx.getLog() << tcu::TestLog::Message << "In the following program, one of the stages references "
   10406 													   "a subroutine that is defined in another stage. This "
   10407 													   "is forbidden by the specification.\n"
   10408 													   "\n"
   10409 													   "Vertex shader:\n\n"
   10410 						   << vs_body.c_str() << "\n\nTessellation control shader:\n\n"
   10411 						   << tc_body.c_str() << "\n\nTessellation evaluation shader:\n\n"
   10412 						   << te_body.c_str() << "\n\nGeometry shader:\n\n"
   10413 						   << gs_body.c_str() << "\n\nFragment shader:\n\n"
   10414 						   << fs_body.c_str() << tcu::TestLog::EndMessage;
   10415 
   10416 		m_has_test_passed = false;
   10417 	} /* if (test program was built successfully) */
   10418 
   10419 	/* Release the shaders & the program object that buildProgram() created */
   10420 	deinitGLObjects();
   10421 }
   10422 
   10423 /** Retrieves an offending fragment shader body.
   10424  *
   10425  *  @param referencing_stage Shader stage which defines the subroutine uniform that
   10426  *                           will be called from fragment shader.
   10427  *
   10428  *  @return Requested string.
   10429  **/
   10430 std::string NegativeTest2::getFragmentShaderBody(const Utils::_shader_stage& referencing_stage) const
   10431 {
   10432 	std::stringstream result;
   10433 
   10434 	/* Form the pre-amble */
   10435 	result << "#version 400\n"
   10436 			  "\n"
   10437 			  "#extension GL_ARB_shader_subroutine : require\n"
   10438 			  "\n"
   10439 			  "subroutine void testSubroutineType(out vec4 test_argument);\n"
   10440 			  "\n"
   10441 			  /* Define a subroutine */
   10442 			  "subroutine(testSubroutineType) void fs_subroutine(out vec4 test_argument)\n"
   10443 			  "{\n"
   10444 			  "    test_argument = vec4(1, 0, 0, 0);\n"
   10445 			  "}\n"
   10446 			  "\n"
   10447 			  /* Define output variables */
   10448 			  "out vec4 result;\n"
   10449 			  "\n"
   10450 			  /* Define uniforms */
   10451 			  "subroutine uniform testSubroutineType test_fs_subroutine;\n"
   10452 			  "\n"
   10453 			  /* Define main() */
   10454 			  "void main()\n"
   10455 			  "{\n"
   10456 			  "    "
   10457 		   << getSubroutineUniformName(referencing_stage) << "(result);\n"
   10458 															 "}\n";
   10459 
   10460 	return result.str();
   10461 }
   10462 
   10463 /** Retrieves an offending geometry shader body.
   10464  *
   10465  *  @param referencing_stage Shader stage which defines the subroutine uniform that
   10466  *                           will be called from geometry shader.
   10467  *
   10468  *  @return Requested string.
   10469  **/
   10470 std::string NegativeTest2::getGeometryShaderBody(const Utils::_shader_stage& referencing_stage) const
   10471 {
   10472 	std::stringstream result;
   10473 
   10474 	/* Form the pre-amble */
   10475 	result << "#version 400\n"
   10476 			  "\n"
   10477 			  "#extension GL_ARB_shader_subroutine : require\n"
   10478 			  "\n"
   10479 			  "subroutine void testSubroutineType(out vec4 test_argument);\n"
   10480 			  "\n"
   10481 			  "layout(points)                   in;\n"
   10482 			  "layout(points, max_vertices = 1) out;\n"
   10483 			  "\n"
   10484 			  /* Define a subroutine */
   10485 			  "subroutine(testSubroutineType) void gs_subroutine(out vec4 test_argument)\n"
   10486 			  "{\n"
   10487 			  "    test_argument = vec4(0, 1, 1, 1);\n"
   10488 			  "}\n"
   10489 			  "\n"
   10490 			  /* Define output variables */
   10491 			  "out vec4 result;\n"
   10492 			  "\n"
   10493 			  /* Define uniforms */
   10494 			  "subroutine uniform testSubroutineType test_gs_subroutine;\n"
   10495 			  "\n"
   10496 			  /* Define main() */
   10497 			  "void main()\n"
   10498 			  "{\n"
   10499 			  "    "
   10500 		   << getSubroutineUniformName(referencing_stage) << "(result);\n"
   10501 															 "}\n";
   10502 
   10503 	return result.str();
   10504 }
   10505 
   10506 /** Retrieves name of the subroutine uniform that is defined in user-specified
   10507  *  shader stage.
   10508  *
   10509  *  @param stage Shader stage to retrieve the subroutine uniform name for.
   10510  *
   10511  *  @return As per description.
   10512  **/
   10513 std::string NegativeTest2::getSubroutineUniformName(const Utils::_shader_stage& stage) const
   10514 {
   10515 	std::string result = "?";
   10516 
   10517 	switch (stage)
   10518 	{
   10519 	case Utils::SHADER_STAGE_FRAGMENT:
   10520 	{
   10521 		result = "test_fs_subroutine";
   10522 
   10523 		break;
   10524 	}
   10525 
   10526 	case Utils::SHADER_STAGE_GEOMETRY:
   10527 	{
   10528 		result = "test_gs_subroutine";
   10529 
   10530 		break;
   10531 	}
   10532 
   10533 	case Utils::SHADER_STAGE_TESSELLATION_CONTROL:
   10534 	{
   10535 		result = "test_tc_subroutine";
   10536 
   10537 		break;
   10538 	}
   10539 
   10540 	case Utils::SHADER_STAGE_TESSELLATION_EVALUATION:
   10541 	{
   10542 		result = "test_te_subroutine";
   10543 
   10544 		break;
   10545 	}
   10546 
   10547 	case Utils::SHADER_STAGE_VERTEX:
   10548 	{
   10549 		result = "test_vs_subroutine";
   10550 
   10551 		break;
   10552 	}
   10553 
   10554 	default:
   10555 	{
   10556 		TCU_FAIL("Unrecognized shader stage requested");
   10557 	}
   10558 	} /* switch (stage) */
   10559 
   10560 	return result;
   10561 }
   10562 
   10563 /** Retrieves an offending tessellation control shader body.
   10564  *
   10565  *  @param referencing_stage Shader stage which defines the subroutine uniform that
   10566  *                           will be called from tessellation control shader.
   10567  *
   10568  *  @return Requested string.
   10569  **/
   10570 std::string NegativeTest2::getTessellationControlShaderBody(const Utils::_shader_stage& referencing_stage) const
   10571 {
   10572 	std::stringstream result;
   10573 
   10574 	/* Form the pre-amble */
   10575 	result << "#version 400\n"
   10576 			  "\n"
   10577 			  "#extension GL_ARB_shader_subroutine : require\n"
   10578 			  "\n"
   10579 			  "layout(vertices = 4) out;\n"
   10580 			  "\n"
   10581 			  "subroutine void testSubroutineType(out vec4 test_argument);\n"
   10582 			  "\n"
   10583 			  /* Define a subroutine */
   10584 			  "subroutine(testSubroutineType) void tc_subroutine(out vec4 test_argument)\n"
   10585 			  "{\n"
   10586 			  "    test_argument = vec4(0, 0, 1, 0);\n"
   10587 			  "}\n"
   10588 			  "\n"
   10589 			  /* Define uniforms */
   10590 			  "subroutine uniform testSubroutineType test_tc_subroutine;\n"
   10591 			  "\n"
   10592 			  /* Define main() */
   10593 			  "void main()\n"
   10594 			  "{\n"
   10595 			  "    "
   10596 		   << getSubroutineUniformName(referencing_stage) << "(gl_out[gl_InvocationID].gl_Position);\n"
   10597 															 "}\n";
   10598 
   10599 	return result.str();
   10600 }
   10601 
   10602 /** Retrieves an offending tessellation evaluation shader body.
   10603  *
   10604  *  @param referencing_stage Shader stage which defines the subroutine uniform that
   10605  *                           will be called from tessellation evaluation shader.
   10606  *
   10607  *  @return Requested string.
   10608  **/
   10609 std::string NegativeTest2::getTessellationEvaluationShaderBody(const Utils::_shader_stage& referencing_stage) const
   10610 {
   10611 	std::stringstream result;
   10612 
   10613 	/* Form the pre-amble */
   10614 	result << "#version 400\n"
   10615 			  "\n"
   10616 			  "#extension GL_ARB_shader_subroutine : require\n"
   10617 			  "\n"
   10618 			  "layout(quads) in;\n"
   10619 			  "\n"
   10620 			  "subroutine void testSubroutineType(out vec4 test_argument);\n"
   10621 			  "\n"
   10622 			  /* Define a subroutine */
   10623 			  "subroutine(testSubroutineType) void te_subroutine(out vec4 test_argument)\n"
   10624 			  "{\n"
   10625 			  "    test_argument = vec4(1, 1, 1, 1);\n"
   10626 			  "}\n"
   10627 			  "\n"
   10628 			  /* Define uniforms */
   10629 			  "subroutine uniform testSubroutineType test_te_subroutine;\n"
   10630 			  "\n"
   10631 			  /* Define main() */
   10632 			  "void main()\n"
   10633 			  "{\n"
   10634 			  "    "
   10635 		   << getSubroutineUniformName(referencing_stage) << "(gl_Position);\n"
   10636 															 "}\n";
   10637 
   10638 	return result.str();
   10639 }
   10640 
   10641 /** Retrieves an offending vertex shader body.
   10642  *
   10643  *  @param referencing_stage Shader stage which defines the subroutine uniform that
   10644  *                           will be called from vertex shader.
   10645  *
   10646  *  @return Requested string.
   10647  **/
   10648 std::string NegativeTest2::getVertexShaderBody(const Utils::_shader_stage& referencing_stage) const
   10649 {
   10650 	std::stringstream result;
   10651 
   10652 	/* Form the pre-amble */
   10653 	result << "#version 400\n"
   10654 			  "\n"
   10655 			  "#extension GL_ARB_shader_subroutine : require\n"
   10656 			  "\n"
   10657 			  "subroutine void testSubroutineType(out vec4 test_argument);\n"
   10658 			  "\n"
   10659 			  /* Define a subroutine */
   10660 			  "subroutine(testSubroutineType) void vs_subroutine(out vec4 test_argument)\n"
   10661 			  "{\n"
   10662 			  "    test_argument = vec4(0, 1, 0, 0);\n"
   10663 			  "}\n"
   10664 			  "\n"
   10665 			  /* Define uniforms */
   10666 			  "subroutine uniform testSubroutineType test_vs_subroutine;\n"
   10667 			  "\n"
   10668 			  /* Define main() */
   10669 			  "void main()\n"
   10670 			  "{\n"
   10671 			  "    "
   10672 		   << getSubroutineUniformName(referencing_stage) << "(gl_Position);\n"
   10673 															 "}\n";
   10674 
   10675 	return result.str();
   10676 }
   10677 
   10678 /** Executes test iteration.
   10679  *
   10680  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   10681  */
   10682 tcu::TestNode::IterateResult NegativeTest2::iterate()
   10683 {
   10684 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   10685 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   10686 	{
   10687 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   10688 	}
   10689 
   10690 	/* Iterate over all shader stages and execute the checks */
   10691 	for (int referencing_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   10692 		 referencing_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++referencing_stage)
   10693 	{
   10694 		executeTestCase(static_cast<Utils::_shader_stage>(referencing_stage));
   10695 	} /* for (all test cases) */
   10696 
   10697 	/* All done */
   10698 	if (m_has_test_passed)
   10699 	{
   10700 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   10701 	}
   10702 	else
   10703 	{
   10704 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   10705 	}
   10706 
   10707 	return STOP;
   10708 }
   10709 
   10710 /** Constructor.
   10711  *
   10712  *  @param context Rendering context.
   10713  *
   10714  **/
   10715 NegativeTest3::NegativeTest3(deqp::Context& context)
   10716 	: TestCase(context, "missing_subroutine_keyword", "Verifies that subroutine keyword is necessary when declaring a "
   10717 													  "subroutine uniforn and a compilation error occurs without it.")
   10718 	, m_has_test_passed(true)
   10719 	, m_so_id(0)
   10720 {
   10721 	/* Left blank intentionally */
   10722 }
   10723 
   10724 /** Deinitializes all GL objects that may have been created during test execution */
   10725 void NegativeTest3::deinit()
   10726 {
   10727 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   10728 
   10729 	if (m_so_id != 0)
   10730 	{
   10731 		gl.deleteShader(m_so_id);
   10732 
   10733 		m_so_id = 0;
   10734 	}
   10735 }
   10736 
   10737 /** Verifies that broken shader (for user-specified shader stage) does not compile.
   10738  *
   10739  *  @param shader_stage Shader stage to use for the test.
   10740  **/
   10741 void NegativeTest3::executeTest(const Utils::_shader_stage& shader_stage)
   10742 {
   10743 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   10744 
   10745 	/* Generate a new shader object */
   10746 	m_so_id = gl.createShader(Utils::getGLenumForShaderStage(shader_stage));
   10747 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
   10748 
   10749 	/* Assign body to the shader */
   10750 	std::string body;
   10751 	const char* body_raw_ptr = DE_NULL;
   10752 
   10753 	switch (shader_stage)
   10754 	{
   10755 	case Utils::SHADER_STAGE_VERTEX:
   10756 		body = getVertexShaderBody();
   10757 		break;
   10758 	case Utils::SHADER_STAGE_TESSELLATION_CONTROL:
   10759 		body = getTessellationControlShaderBody();
   10760 		break;
   10761 	case Utils::SHADER_STAGE_TESSELLATION_EVALUATION:
   10762 		body = getTessellationEvaluationShaderBody();
   10763 		break;
   10764 	case Utils::SHADER_STAGE_GEOMETRY:
   10765 		body = getGeometryShaderBody();
   10766 		break;
   10767 	case Utils::SHADER_STAGE_FRAGMENT:
   10768 		body = getFragmentShaderBody();
   10769 		break;
   10770 
   10771 	default:
   10772 	{
   10773 		TCU_FAIL("Unrecognized shader stage requested");
   10774 	}
   10775 	} /* switch (shader_stage) */
   10776 
   10777 	body_raw_ptr = body.c_str();
   10778 
   10779 	gl.shaderSource(m_so_id, 1 /* count */, &body_raw_ptr, DE_NULL /* length */);
   10780 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   10781 
   10782 	/* Try to compile the shader */
   10783 	glw::GLint compile_status = 0;
   10784 
   10785 	gl.compileShader(m_so_id);
   10786 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
   10787 
   10788 	gl.getShaderiv(m_so_id, GL_COMPILE_STATUS, &compile_status);
   10789 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
   10790 
   10791 	if (compile_status == GL_TRUE)
   10792 	{
   10793 		m_testCtx.getLog() << tcu::TestLog::Message << "The following shader was expected to fail to compile but was "
   10794 													   "accepted by the compiler:\n"
   10795 													   "\n"
   10796 						   << body.c_str() << tcu::TestLog::EndMessage;
   10797 
   10798 		m_has_test_passed = false;
   10799 	}
   10800 
   10801 	/* Good to release the shader at this point */
   10802 	gl.deleteShader(m_so_id);
   10803 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader() call failed.");
   10804 }
   10805 
   10806 /** Retrieves body of a broken fragment shader.
   10807  *
   10808  *  @return Requested string.
   10809  **/
   10810 std::string NegativeTest3::getFragmentShaderBody() const
   10811 {
   10812 	return "#version 400\n"
   10813 		   "\n"
   10814 		   "#extension GL_ARB_shader_subroutine : require\n"
   10815 		   "\n"
   10816 		   "subroutine void testSubroutineType(inout vec4 test);\n"
   10817 		   "\n"
   10818 		   "void testSubroutine1(inout vec4 test)\n"
   10819 		   "{\n"
   10820 		   "    test += vec4(3, 4, 5, 6);\n"
   10821 		   "}\n"
   10822 		   "\n"
   10823 		   "uniform testSubroutineType subroutineFunction;\n"
   10824 		   "out     vec4               result;\n"
   10825 		   "\n"
   10826 		   "void main()\n"
   10827 		   "{\n"
   10828 		   "    vec4 test = vec4(2, 3, 4, 5);\n"
   10829 		   "\n"
   10830 		   "    subroutineFunction(test);\n"
   10831 		   "\n"
   10832 		   "    result = test;\n"
   10833 		   "}\n";
   10834 }
   10835 
   10836 /** Retrieves body of a broken geometry shader.
   10837  *
   10838  *  @return Requested string.
   10839  **/
   10840 std::string NegativeTest3::getGeometryShaderBody() const
   10841 {
   10842 	return "#version 400\n"
   10843 		   "\n"
   10844 		   "#extension GL_ARB_shader_subroutine : require\n"
   10845 		   "\n"
   10846 		   "layout(points)                   in;\n"
   10847 		   "layout(points, max_vertices = 1) out;\n"
   10848 		   "\n"
   10849 		   "subroutine void testSubroutineType(inout vec4 test);\n"
   10850 		   "\n"
   10851 		   "void testSubroutine1(inout vec4 test)\n"
   10852 		   "{\n"
   10853 		   "    test += vec4(3, 4, 5, 6);\n"
   10854 		   "}\n"
   10855 		   "\n"
   10856 		   "uniform testSubroutineType subroutineFunction;\n"
   10857 		   "\n"
   10858 		   "void main()\n"
   10859 		   "{\n"
   10860 		   "    vec4 test = vec4(2, 3, 4, 5);\n"
   10861 		   "\n"
   10862 		   "    subroutineFunction(test);\n"
   10863 		   "\n"
   10864 		   "    gl_Position = test;\n"
   10865 		   "    EmitVertex();\n"
   10866 		   "}\n";
   10867 }
   10868 
   10869 /** Retrieves body of a broken tessellation control shader.
   10870  *
   10871  *  @return Requested string.
   10872  **/
   10873 std::string NegativeTest3::getTessellationControlShaderBody() const
   10874 {
   10875 	return "#version 400\n"
   10876 		   "\n"
   10877 		   "#extension GL_ARB_shader_subroutine : require\n"
   10878 		   "\n"
   10879 		   "layout(vertices=4) out;\n"
   10880 		   "\n"
   10881 		   "subroutine void testSubroutineType(inout vec4 test);\n"
   10882 		   "\n"
   10883 		   "void testSubroutine1(inout vec4 test)\n"
   10884 		   "{\n"
   10885 		   "    test += vec4(1, 2, 3, 4);\n"
   10886 		   "}\n"
   10887 		   "\n"
   10888 		   "uniform testSubroutineType subroutineFunction;\n"
   10889 		   "\n"
   10890 		   "void main()\n"
   10891 		   "{\n"
   10892 		   "    vec4 test = vec4(0, 1, 2, 3);\n"
   10893 		   "\n"
   10894 		   "    subroutineFunction(test);\n"
   10895 		   "\n"
   10896 		   "    gl_out[gl_InvocationID].gl_Position = test;\n"
   10897 		   "}\n";
   10898 }
   10899 
   10900 /** Retrieves body of a broken tessellation evaluation shader.
   10901  *
   10902  *  @return Requested string.
   10903  **/
   10904 std::string NegativeTest3::getTessellationEvaluationShaderBody() const
   10905 {
   10906 	return "#version 400\n"
   10907 		   "\n"
   10908 		   "#extension GL_ARB_shader_subroutine : require\n"
   10909 		   "\n"
   10910 		   "layout(quads) in;\n"
   10911 		   "\n"
   10912 		   "subroutine void testSubroutineType(inout vec4 test);\n"
   10913 		   "\n"
   10914 		   "void testSubroutine1(inout vec4 test)\n"
   10915 		   "{\n"
   10916 		   "    test += vec4(2, 3, 4, 5);\n"
   10917 		   "}\n"
   10918 		   "\n"
   10919 		   "uniform testSubroutineType subroutineFunction;\n"
   10920 		   "\n"
   10921 		   "void main()\n"
   10922 		   "{\n"
   10923 		   "    vec4 test = vec4(1, 2, 3, 4);\n"
   10924 		   "\n"
   10925 		   "    subroutineFunction(test);\n"
   10926 		   "\n"
   10927 		   "    gl_Position = test;\n"
   10928 		   "}\n";
   10929 }
   10930 
   10931 /** Retrieves body of a broken vertex shader.
   10932  *
   10933  *  @return Requested string.
   10934  **/
   10935 std::string NegativeTest3::getVertexShaderBody() const
   10936 {
   10937 	return "#version 400\n"
   10938 		   "\n"
   10939 		   "#extension GL_ARB_shader_subroutine : require\n"
   10940 		   "\n"
   10941 		   "subroutine void testSubroutineType(inout vec4 test);\n"
   10942 		   "\n"
   10943 		   "void testSubroutine1(inout vec4 test)\n"
   10944 		   "{\n"
   10945 		   "    test += vec4(0, 1, 2, 3);\n"
   10946 		   "}\n"
   10947 		   "\n"
   10948 		   "uniform testSubroutineType subroutineFunction;\n"
   10949 		   "\n"
   10950 		   "void main()\n"
   10951 		   "{\n"
   10952 		   "    subroutineFunction(gl_Position);\n"
   10953 		   "}\n";
   10954 }
   10955 
   10956 /** Executes test iteration.
   10957  *
   10958  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   10959  */
   10960 tcu::TestNode::IterateResult NegativeTest3::iterate()
   10961 {
   10962 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   10963 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   10964 	{
   10965 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   10966 	}
   10967 
   10968 	/* Iterate over all shader stages */
   10969 	for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   10970 		 shader_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage)
   10971 	{
   10972 		executeTest(static_cast<Utils::_shader_stage>(shader_stage));
   10973 	} /* for (all shader stages) */
   10974 
   10975 	/* Done */
   10976 	if (m_has_test_passed)
   10977 	{
   10978 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   10979 	}
   10980 	else
   10981 	{
   10982 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   10983 	}
   10984 
   10985 	return STOP;
   10986 }
   10987 
   10988 /** Constructor.
   10989  *
   10990  *  @param context Rendering context.
   10991  *
   10992  **/
   10993 NegativeTest4::NegativeTest4(deqp::Context& context)
   10994 	: TestCase(context, "subroutines_incompatible_with_subroutine_type",
   10995 			   "Verifies that a compile-time error is generated when arguments and "
   10996 			   "return type do not match beween the function and each associated "
   10997 			   "subroutine type.")
   10998 	, m_has_test_passed(true)
   10999 	, m_so_id(0)
   11000 {
   11001 	/* Left blank intentionally */
   11002 }
   11003 
   11004 /** Deinitializes GL objects that may have been created during test
   11005  *  execution.
   11006  **/
   11007 void NegativeTest4::deinit()
   11008 {
   11009 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   11010 
   11011 	if (m_so_id != 0)
   11012 	{
   11013 		gl.deleteShader(m_so_id);
   11014 
   11015 		m_so_id = 0;
   11016 	}
   11017 }
   11018 
   11019 /** Retrieves body of a shader of user-specified type that should be used
   11020  *  for a single test iteration. The shader will define user-specified number
   11021  *  of subroutine types, with the last type either defining an additional argument
   11022  *  or using a different return type.
   11023  *  A subroutine (claimed compatible with *all* subroutine types) will also be
   11024  *  defined in the shader.
   11025  *
   11026  *  @param shader_stage       Shader stage to use for the query.
   11027  *  @param n_subroutine_types Overall number of subroutine types that will be
   11028  *                            declared & used in the shader. Please see description
   11029  *                            for more details.
   11030  *
   11031  *  @return Requested string.
   11032  **/
   11033 std::string NegativeTest4::getShaderBody(const Utils::_shader_stage& shader_stage,
   11034 										 const unsigned int& n_subroutine_types, const _test_case& test_case) const
   11035 {
   11036 	std::stringstream result_sstream;
   11037 
   11038 	/* Form the pre-amble */
   11039 	result_sstream << "#version 400\n"
   11040 					  "\n"
   11041 					  "#extension GL_ARB_shader_subroutine : require\n"
   11042 					  "\n";
   11043 
   11044 	/* Inject stage-specific code */
   11045 	switch (shader_stage)
   11046 	{
   11047 	case Utils::SHADER_STAGE_GEOMETRY:
   11048 	{
   11049 		result_sstream << "layout (points) in;\n"
   11050 						  "layout (points, max_vertices = 1) out;\n"
   11051 						  "\n";
   11052 
   11053 		break;
   11054 	}
   11055 
   11056 	case Utils::SHADER_STAGE_TESSELLATION_CONTROL:
   11057 	{
   11058 		result_sstream << "layout (vertices = 4) out;\n"
   11059 						  "\n";
   11060 
   11061 		break;
   11062 	}
   11063 
   11064 	case Utils::SHADER_STAGE_TESSELLATION_EVALUATION:
   11065 	{
   11066 		result_sstream << "layout (quads) in;\n"
   11067 						  "\n";
   11068 
   11069 		break;
   11070 	}
   11071 
   11072 	default:
   11073 		break;
   11074 	} /* switch (shader_stage) */
   11075 
   11076 	/* Insert subroutine type declarations */
   11077 	for (unsigned int n_subroutine_type = 0; n_subroutine_type < n_subroutine_types - 1; ++n_subroutine_type)
   11078 	{
   11079 		result_sstream << "subroutine void subroutineType" << n_subroutine_type << "(inout vec3 argument);\n";
   11080 	} /* for (all subroutine types) */
   11081 
   11082 	switch (test_case)
   11083 	{
   11084 	case TEST_CASE_INCOMPATIBLE_ARGUMENT_LIST:
   11085 	{
   11086 		result_sstream << "subroutine void subroutineType" << (n_subroutine_types - 1)
   11087 					   << "(inout vec3 argument, out vec4 argument2);\n";
   11088 
   11089 		break;
   11090 	}
   11091 
   11092 	case TEST_CASE_INCOMPATIBLE_RETURN_TYPE:
   11093 	{
   11094 		result_sstream << "subroutine int subroutineType" << (n_subroutine_types - 1) << "(inout vec3 argument);\n";
   11095 
   11096 		break;
   11097 	}
   11098 
   11099 	default:
   11100 	{
   11101 		TCU_FAIL("Unrecognized test case");
   11102 	}
   11103 	} /* switch (test_case) */
   11104 
   11105 	/* Insert subroutine declarations */
   11106 	result_sstream << "subroutine(";
   11107 
   11108 	for (unsigned int n_subroutine_type = 0; n_subroutine_type < n_subroutine_types; ++n_subroutine_type)
   11109 	{
   11110 		result_sstream << "subroutineType" << n_subroutine_type;
   11111 
   11112 		if (n_subroutine_type != (n_subroutine_types - 1))
   11113 		{
   11114 			result_sstream << ", ";
   11115 		}
   11116 	} /* for (all subroutine types) */
   11117 
   11118 	result_sstream << ") void function(inout vec3 argument)\n"
   11119 					  "{\n"
   11120 					  "    argument = vec3(1, 2, 3);\n"
   11121 					  "}\n"
   11122 					  "\n";
   11123 
   11124 	/* Insert remaining required stage-specific bits */
   11125 	switch (shader_stage)
   11126 	{
   11127 	case Utils::SHADER_STAGE_FRAGMENT:
   11128 	{
   11129 		result_sstream << "out vec4 result;\n"
   11130 						  "\n"
   11131 						  "void main()\n"
   11132 						  "{\n"
   11133 						  "    result = vec4(1, 2, 3, 4);\n"
   11134 						  "}\n";
   11135 
   11136 		break;
   11137 	}
   11138 
   11139 	case Utils::SHADER_STAGE_GEOMETRY:
   11140 	{
   11141 		result_sstream << "void main()\n"
   11142 						  "{\n"
   11143 						  "    gl_Position = vec4(1, 2, 3, 4);\n"
   11144 						  "    EmitVertex();\n"
   11145 						  "}\n";
   11146 
   11147 		break;
   11148 	}
   11149 
   11150 	case Utils::SHADER_STAGE_TESSELLATION_CONTROL:
   11151 	{
   11152 		result_sstream << "void main()\n"
   11153 						  "{\n"
   11154 						  "    gl_TessLevelInner[0]                = 1;\n"
   11155 						  "    gl_TessLevelInner[1]                = 1;\n"
   11156 						  "    gl_TessLevelOuter[0]                = 1;\n"
   11157 						  "    gl_TessLevelOuter[1]                = 1;\n"
   11158 						  "    gl_TessLevelOuter[2]                = 1;\n"
   11159 						  "    gl_TessLevelOuter[3]                = 1;\n"
   11160 						  "    gl_out[gl_InvocationID].gl_Position = vec4(2, 3, 4, 5);\n"
   11161 						  "}\n";
   11162 
   11163 		break;
   11164 	}
   11165 
   11166 	case Utils::SHADER_STAGE_TESSELLATION_EVALUATION:
   11167 	case Utils::SHADER_STAGE_VERTEX:
   11168 	{
   11169 		result_sstream << "void main()\n"
   11170 						  "{\n"
   11171 						  "    gl_Position = vec4(1, 2, 3, 4);\n"
   11172 						  "}\n";
   11173 
   11174 		break;
   11175 	}
   11176 
   11177 	default:
   11178 	{
   11179 		TCU_FAIL("Unrecognized shader stage");
   11180 	}
   11181 	} /* switch (shader_stage) */
   11182 
   11183 	return result_sstream.str();
   11184 }
   11185 
   11186 /** Executes test iteration.
   11187  *
   11188  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   11189  */
   11190 tcu::TestNode::IterateResult NegativeTest4::iterate()
   11191 {
   11192 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   11193 
   11194 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   11195 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   11196 	{
   11197 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   11198 	}
   11199 
   11200 	/* Iterate over all shader stages.. */
   11201 	for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   11202 		 shader_stage != static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage)
   11203 	{
   11204 		/* For each shader stage, we will be trying to compile a number of invalid shaders.
   11205 		 * Each shader defines N different subroutine types. (N-1) of them are compatible
   11206 		 * with a subroutine, but exactly 1 will be mismatched. The test passes if GLSL
   11207 		 * compiler correctly detects that all shaders we will be trying to compile are
   11208 		 * broken.
   11209 		 */
   11210 		const glw::GLenum shader_type = Utils::getGLenumForShaderStage(static_cast<Utils::_shader_stage>(shader_stage));
   11211 
   11212 		for (unsigned int n_subroutine_types = 1; n_subroutine_types < 6; /* arbitrary number */
   11213 			 ++n_subroutine_types)
   11214 		{
   11215 			for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT);
   11216 				 ++test_case)
   11217 			{
   11218 				std::string body;
   11219 				const char* body_raw_ptr   = NULL;
   11220 				glw::GLint  compile_status = GL_FALSE;
   11221 
   11222 				body = getShaderBody(static_cast<Utils::_shader_stage>(shader_stage), n_subroutine_types,
   11223 									 static_cast<_test_case>(test_case));
   11224 				body_raw_ptr = body.c_str();
   11225 
   11226 				/* Try to compile the shader */
   11227 				m_so_id = gl.createShader(shader_type);
   11228 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed");
   11229 
   11230 				gl.shaderSource(m_so_id, 1 /* count */, &body_raw_ptr, DE_NULL);
   11231 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
   11232 
   11233 				gl.compileShader(m_so_id);
   11234 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed");
   11235 
   11236 				gl.getShaderiv(m_so_id, GL_COMPILE_STATUS, &compile_status);
   11237 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
   11238 
   11239 				if (compile_status == GL_TRUE)
   11240 				{
   11241 					m_testCtx.getLog() << tcu::TestLog::Message << "A malformed "
   11242 									   << Utils::getShaderStageString(static_cast<Utils::_shader_stage>(shader_stage))
   11243 									   << " compiled successfully "
   11244 										  "("
   11245 									   << n_subroutine_types << " subroutine types "
   11246 																"were defined)."
   11247 									   << tcu::TestLog::EndMessage;
   11248 
   11249 					m_has_test_passed = false;
   11250 				}
   11251 
   11252 				/* Release the object */
   11253 				gl.deleteShader(m_so_id);
   11254 				GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader() call failed.");
   11255 			} /* for (all test cases) */
   11256 		}	 /* for (a number of different subroutine type declarations) */
   11257 	}		  /* for (all shader stages) */
   11258 
   11259 	/* Done */
   11260 	if (m_has_test_passed)
   11261 	{
   11262 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   11263 	}
   11264 	else
   11265 	{
   11266 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   11267 	}
   11268 
   11269 	return STOP;
   11270 }
   11271 
   11272 /** Constructor.
   11273  *
   11274  *  @param context Rendering context.
   11275  *
   11276  **/
   11277 NegativeTest5::NegativeTest5(deqp::Context& context)
   11278 	: TestCase(context, "subroutine_uniform_wo_matching_subroutines",
   11279 			   "Verifies that a link- or compile-time error occurs when "
   11280 			   "trying to link a program with no subroutine for subroutine "
   11281 			   "uniform variable.")
   11282 	, m_fs_id(0)
   11283 	, m_gs_id(0)
   11284 	, m_has_test_passed(true)
   11285 	, m_po_id(0)
   11286 	, m_tc_id(0)
   11287 	, m_te_id(0)
   11288 	, m_vs_id(0)
   11289 {
   11290 	/* Left blank intentionally */
   11291 }
   11292 
   11293 /** Deinitializes all GL objects that may have been created during test execution */
   11294 void NegativeTest5::deinit()
   11295 {
   11296 	deinitIteration();
   11297 }
   11298 
   11299 /** Deinitializes all GL objects that may have been created during a single test
   11300  *  iteration.
   11301  ***/
   11302 void NegativeTest5::deinitIteration()
   11303 {
   11304 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   11305 
   11306 	if (m_fs_id != 0)
   11307 	{
   11308 		gl.deleteShader(m_fs_id);
   11309 
   11310 		m_fs_id = 0;
   11311 	}
   11312 
   11313 	if (m_gs_id != 0)
   11314 	{
   11315 		gl.deleteShader(m_gs_id);
   11316 
   11317 		m_gs_id = 0;
   11318 	}
   11319 
   11320 	if (m_po_id != 0)
   11321 	{
   11322 		gl.deleteProgram(m_po_id);
   11323 
   11324 		m_po_id = 0;
   11325 	}
   11326 
   11327 	if (m_tc_id != 0)
   11328 	{
   11329 		gl.deleteShader(m_tc_id);
   11330 
   11331 		m_tc_id = 0;
   11332 	}
   11333 
   11334 	if (m_te_id != 0)
   11335 	{
   11336 		gl.deleteShader(m_te_id);
   11337 
   11338 		m_te_id = 0;
   11339 	}
   11340 
   11341 	if (m_vs_id != 0)
   11342 	{
   11343 		gl.deleteShader(m_vs_id);
   11344 
   11345 		m_vs_id = 0;
   11346 	}
   11347 }
   11348 
   11349 /** Executes a single test iteration.
   11350  *
   11351  *  If the iteration fails, m_has_test_passed will be set to false.
   11352  *
   11353  *  @param shader_stage Shader stage, for which a subroutine uniform should be
   11354  *                      declared in the shader without a matching subroutine.
   11355  **/
   11356 void NegativeTest5::executeIteration(const Utils::_shader_stage& shader_stage)
   11357 {
   11358 	std::string fs_body = getFragmentShaderBody(shader_stage == Utils::SHADER_STAGE_FRAGMENT);
   11359 	std::string gs_body = getGeometryShaderBody(shader_stage == Utils::SHADER_STAGE_GEOMETRY);
   11360 	std::string tc_body = getTessellationControlShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_CONTROL);
   11361 	std::string te_body =
   11362 		getTessellationEvaluationShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_EVALUATION);
   11363 	std::string vs_body = getVertexShaderBody(shader_stage == Utils::SHADER_STAGE_VERTEX);
   11364 
   11365 	if (Utils::buildProgram(m_context.getRenderContext().getFunctions(), vs_body, tc_body, te_body, gs_body, fs_body,
   11366 							DE_NULL, /* xfb_varyings */
   11367 							DE_NULL, /* n_xfb_varyings */
   11368 							&m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id))
   11369 	{
   11370 		/* None of the test programs should ever build successfully */
   11371 		m_testCtx.getLog() << tcu::TestLog::Message
   11372 						   << "A program object, consisting of the following shaders, has linked"
   11373 							  " correctly. One of the shaders defines a subroutine uniform but does "
   11374 							  "not implement any function that matches subroutine type of the uniform."
   11375 							  " This should have resulted in a compilation/link-time error.\n"
   11376 							  "\n"
   11377 							  "Vertex shader:\n"
   11378 							  "\n"
   11379 						   << vs_body << "\n"
   11380 										 "Tessellation control shader:\n"
   11381 										 "\n"
   11382 						   << tc_body << "\n"
   11383 										 "Tessellation evaluation shader:\n"
   11384 										 "\n"
   11385 						   << te_body << "\n"
   11386 										 "Geometry shader:\n"
   11387 										 "\n"
   11388 						   << gs_body << "\n"
   11389 										 "Fragment shader:\n"
   11390 										 "\n"
   11391 						   << fs_body << tcu::TestLog::EndMessage;
   11392 
   11393 		m_has_test_passed = false;
   11394 	}
   11395 }
   11396 
   11397 /** Retrieves fragment shader body.
   11398  *
   11399  *  @param include_invalid_subroutine_uniform_declaration true if the shader should declare
   11400  *                                                        a subroutine uniform without
   11401  *                                                        a matching subroutine, false otherwise.
   11402  *
   11403  *  @return Requested string.
   11404  **/
   11405 std::string NegativeTest5::getFragmentShaderBody(bool include_invalid_subroutine_uniform_declaration) const
   11406 {
   11407 	std::stringstream result_sstream;
   11408 
   11409 	result_sstream << "#version 400\n"
   11410 					  "\n"
   11411 					  "#extension GL_ARB_shader_subroutine : require\n"
   11412 					  "\n";
   11413 
   11414 	if (include_invalid_subroutine_uniform_declaration)
   11415 	{
   11416 		result_sstream << "subroutine void subroutineTestTypeFS(out vec4 test);\n"
   11417 						  "\n"
   11418 						  "subroutine uniform subroutineTestTypeFS test_subroutineFS;\n";
   11419 	};
   11420 
   11421 	result_sstream << "\n"
   11422 					  "out vec4 result;\n"
   11423 					  "\n"
   11424 					  "void main()\n"
   11425 					  "{\n";
   11426 
   11427 	if (include_invalid_subroutine_uniform_declaration)
   11428 	{
   11429 		result_sstream << "    test_subroutineFS(result);\n";
   11430 	}
   11431 	else
   11432 	{
   11433 		result_sstream << "    result = vec4(0, 1, 2, 3);\n";
   11434 	}
   11435 
   11436 	result_sstream << "}\n";
   11437 
   11438 	return result_sstream.str();
   11439 }
   11440 
   11441 /** Retrieves geometry shader body.
   11442  *
   11443  *  @param include_invalid_subroutine_uniform_declaration true if the shader should declare
   11444  *                                                        a subroutine uniform without
   11445  *                                                        a matching subroutine, false otherwise.
   11446  *
   11447  *  @return Requested string.
   11448  **/
   11449 std::string NegativeTest5::getGeometryShaderBody(bool include_invalid_subroutine_uniform_declaration) const
   11450 {
   11451 	std::stringstream result_sstream;
   11452 
   11453 	result_sstream << "#version 400\n"
   11454 					  "\n"
   11455 					  "#extension GL_ARB_shader_subroutine : require\n"
   11456 					  "\n"
   11457 					  "layout (points)                   in;\n"
   11458 					  "layout (points, max_vertices = 1) out;\n"
   11459 					  "\n";
   11460 
   11461 	if (include_invalid_subroutine_uniform_declaration)
   11462 	{
   11463 		result_sstream << "subroutine void subroutineTestTypeGS(out vec4 test);\n"
   11464 						  "\n"
   11465 						  "subroutine uniform subroutineTestTypeGS test_subroutineGS;\n";
   11466 	};
   11467 
   11468 	result_sstream << "\n"
   11469 					  "void main()\n"
   11470 					  "{\n";
   11471 
   11472 	if (include_invalid_subroutine_uniform_declaration)
   11473 	{
   11474 		result_sstream << "    test_subroutineGS(gl_Position);\n";
   11475 	}
   11476 	else
   11477 	{
   11478 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   11479 	}
   11480 
   11481 	result_sstream << "EmitVertex();\n"
   11482 					  "}\n";
   11483 
   11484 	return result_sstream.str();
   11485 }
   11486 
   11487 /** Retrieves tessellation control shader body.
   11488  *
   11489  *  @param include_invalid_subroutine_uniform_declaration true if the shader should declare
   11490  *                                                        a subroutine uniform without
   11491  *                                                        a matching subroutine, false otherwise.
   11492  *
   11493  *  @return Requested string.
   11494  **/
   11495 std::string NegativeTest5::getTessellationControlShaderBody(bool include_invalid_subroutine_uniform_declaration) const
   11496 {
   11497 	std::stringstream result_sstream;
   11498 
   11499 	result_sstream << "#version 400\n"
   11500 					  "\n"
   11501 					  "#extension GL_ARB_shader_subroutine : require\n"
   11502 					  "\n"
   11503 					  "layout (vertices = 4) out;\n"
   11504 					  "\n";
   11505 
   11506 	if (include_invalid_subroutine_uniform_declaration)
   11507 	{
   11508 		result_sstream << "subroutine void subroutineTestTypeTC(out vec4 test);\n"
   11509 						  "\n"
   11510 						  "subroutine uniform subroutineTestTypeTC test_subroutineTC;\n";
   11511 	};
   11512 
   11513 	result_sstream << "\n"
   11514 					  "void main()\n"
   11515 					  "{\n";
   11516 
   11517 	if (include_invalid_subroutine_uniform_declaration)
   11518 	{
   11519 		result_sstream << "    test_subroutineTC(gl_out[gl_InvocationID].gl_Position);\n";
   11520 	}
   11521 	else
   11522 	{
   11523 		result_sstream << "    gl_out[gl_InvocationID].gl_Position = vec4(0, 1, 2, 3);\n";
   11524 	}
   11525 
   11526 	result_sstream << "}\n";
   11527 
   11528 	return result_sstream.str();
   11529 }
   11530 
   11531 /** Retrieves tessellation evaluation body.
   11532  *
   11533  *  @param include_invalid_subroutine_uniform_declaration true if the shader should declare
   11534  *                                                        a subroutine uniform without
   11535  *                                                        a matching subroutine, false otherwise.
   11536  *
   11537  *  @return Requested string.
   11538  **/
   11539 std::string NegativeTest5::getTessellationEvaluationShaderBody(
   11540 	bool include_invalid_subroutine_uniform_declaration) const
   11541 {
   11542 	std::stringstream result_sstream;
   11543 
   11544 	result_sstream << "#version 400\n"
   11545 					  "\n"
   11546 					  "#extension GL_ARB_shader_subroutine : require\n"
   11547 					  "\n"
   11548 					  "layout (quads) in;\n"
   11549 					  "\n";
   11550 
   11551 	if (include_invalid_subroutine_uniform_declaration)
   11552 	{
   11553 		result_sstream << "subroutine void subroutineTestTypeTE(out vec4 test);\n"
   11554 						  "\n"
   11555 						  "subroutine uniform subroutineTestTypeTE test_subroutineTE;\n";
   11556 	};
   11557 
   11558 	result_sstream << "\n"
   11559 					  "void main()\n"
   11560 					  "{\n";
   11561 
   11562 	if (include_invalid_subroutine_uniform_declaration)
   11563 	{
   11564 		result_sstream << "    test_subroutineTE(gl_Position);\n";
   11565 	}
   11566 	else
   11567 	{
   11568 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   11569 	}
   11570 
   11571 	result_sstream << "}\n";
   11572 
   11573 	return result_sstream.str();
   11574 }
   11575 
   11576 /** Retrieves vertex shader body.
   11577  *
   11578  *  @param include_invalid_subroutine_uniform_declaration true if the shader should declare
   11579  *                                                        a subroutine uniform without
   11580  *                                                        a matching subroutine, false otherwise.
   11581  *
   11582  *  @return Requested string.
   11583  **/
   11584 std::string NegativeTest5::getVertexShaderBody(bool include_invalid_subroutine_uniform_declaration) const
   11585 {
   11586 	std::stringstream result_sstream;
   11587 
   11588 	result_sstream << "#version 400\n"
   11589 					  "\n"
   11590 					  "#extension GL_ARB_shader_subroutine : require\n"
   11591 					  "\n";
   11592 
   11593 	if (include_invalid_subroutine_uniform_declaration)
   11594 	{
   11595 		result_sstream << "subroutine void subroutineTestTypeVS(out vec4 test);\n"
   11596 						  "\n"
   11597 						  "subroutine uniform subroutineTestTypeVS test_subroutineVS;\n";
   11598 	};
   11599 
   11600 	result_sstream << "\n"
   11601 					  "void main()\n"
   11602 					  "{\n";
   11603 
   11604 	if (include_invalid_subroutine_uniform_declaration)
   11605 	{
   11606 		result_sstream << "    test_subroutineVS(gl_Position);\n";
   11607 	}
   11608 	else
   11609 	{
   11610 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   11611 	}
   11612 
   11613 	result_sstream << "}\n";
   11614 
   11615 	return result_sstream.str();
   11616 }
   11617 
   11618 /** Executes test iteration.
   11619  *
   11620  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   11621  */
   11622 tcu::TestNode::IterateResult NegativeTest5::iterate()
   11623 {
   11624 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   11625 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   11626 	{
   11627 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   11628 	}
   11629 
   11630 	/* Iterate over all shader stages. Iteration-specific shader stage defines a subroutine type &
   11631 	 * a corresponding subroutine uniform, for which no compatible subroutines are available. All
   11632 	 * other shader stages are defined correctly.
   11633 	 */
   11634 	for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   11635 		 shader_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage)
   11636 	{
   11637 		executeIteration(static_cast<Utils::_shader_stage>(shader_stage));
   11638 		deinitIteration();
   11639 	} /* for (all shader stages) */
   11640 
   11641 	/* All done */
   11642 	if (m_has_test_passed)
   11643 	{
   11644 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   11645 	}
   11646 	else
   11647 	{
   11648 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   11649 	}
   11650 
   11651 	return STOP;
   11652 }
   11653 
   11654 /** Constructor.
   11655  *
   11656  *  @param context Rendering context.
   11657  *
   11658  **/
   11659 NegativeTest6::NegativeTest6(deqp::Context& context)
   11660 	: TestCase(context, "two_duplicate_functions_one_being_a_subroutine",
   11661 			   "Verifies that a link- or compile-time error occurs if any shader in "
   11662 			   "a program object includes two functions with the same name and one "
   11663 			   "of which is associated with a subroutine type.")
   11664 	, m_fs_id(0)
   11665 	, m_gs_id(0)
   11666 	, m_has_test_passed(true)
   11667 	, m_po_id(0)
   11668 	, m_tc_id(0)
   11669 	, m_te_id(0)
   11670 	, m_vs_id(0)
   11671 {
   11672 	/* Left blank intentionally */
   11673 }
   11674 
   11675 /** Deinitializes all GL objects that may have been created during test execution */
   11676 void NegativeTest6::deinit()
   11677 {
   11678 	deinitIteration();
   11679 }
   11680 
   11681 /** Deinitializes all GL objects that may have been created during a single test
   11682  *  iteration.
   11683  ***/
   11684 void NegativeTest6::deinitIteration()
   11685 {
   11686 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   11687 
   11688 	if (m_fs_id != 0)
   11689 	{
   11690 		gl.deleteShader(m_fs_id);
   11691 
   11692 		m_fs_id = 0;
   11693 	}
   11694 
   11695 	if (m_gs_id != 0)
   11696 	{
   11697 		gl.deleteShader(m_gs_id);
   11698 
   11699 		m_gs_id = 0;
   11700 	}
   11701 
   11702 	if (m_po_id != 0)
   11703 	{
   11704 		gl.deleteProgram(m_po_id);
   11705 
   11706 		m_po_id = 0;
   11707 	}
   11708 
   11709 	if (m_tc_id != 0)
   11710 	{
   11711 		gl.deleteShader(m_tc_id);
   11712 
   11713 		m_tc_id = 0;
   11714 	}
   11715 
   11716 	if (m_te_id != 0)
   11717 	{
   11718 		gl.deleteShader(m_te_id);
   11719 
   11720 		m_te_id = 0;
   11721 	}
   11722 
   11723 	if (m_vs_id != 0)
   11724 	{
   11725 		gl.deleteShader(m_vs_id);
   11726 
   11727 		m_vs_id = 0;
   11728 	}
   11729 }
   11730 
   11731 /** Executes a single test iteration.
   11732  *
   11733  *  If the iteration fails, m_has_test_passed will be set to false.
   11734  *
   11735  *  @param shader_stage Shader stage, for which two duplicate functions
   11736  *                      (one additionally marked as subroutine) should
   11737  *                      be defined.
   11738  **/
   11739 void NegativeTest6::executeIteration(const Utils::_shader_stage& shader_stage)
   11740 {
   11741 	std::string fs_body = getFragmentShaderBody(shader_stage == Utils::SHADER_STAGE_FRAGMENT);
   11742 	std::string gs_body = getGeometryShaderBody(shader_stage == Utils::SHADER_STAGE_GEOMETRY);
   11743 	std::string tc_body = getTessellationControlShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_CONTROL);
   11744 	std::string te_body =
   11745 		getTessellationEvaluationShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_EVALUATION);
   11746 	std::string vs_body = getVertexShaderBody(shader_stage == Utils::SHADER_STAGE_VERTEX);
   11747 
   11748 	if (Utils::buildProgram(m_context.getRenderContext().getFunctions(), vs_body, tc_body, te_body, gs_body, fs_body,
   11749 							DE_NULL, /* xfb_varyings */
   11750 							DE_NULL, /* n_xfb_varyings */
   11751 							&m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id))
   11752 	{
   11753 		/* None of the test programs should ever build successfully */
   11754 		m_testCtx.getLog() << tcu::TestLog::Message
   11755 						   << "A program object, consisting of the following shaders, has linked"
   11756 							  " correctly. This is invalid, because one of the shaders defines two"
   11757 							  " functions with the same name, with an exception that one of the"
   11758 							  " functions is marked as a subroutine.\n"
   11759 							  "\n"
   11760 							  "Vertex shader:\n"
   11761 							  "\n"
   11762 						   << vs_body << "\n"
   11763 										 "Tessellation control shader:\n"
   11764 										 "\n"
   11765 						   << tc_body << "\n"
   11766 										 "Tessellation evaluation shader:\n"
   11767 										 "\n"
   11768 						   << te_body << "\n"
   11769 										 "Geometry shader:\n"
   11770 										 "\n"
   11771 						   << gs_body << "\n"
   11772 										 "Fragment shader:\n"
   11773 										 "\n"
   11774 						   << fs_body << tcu::TestLog::EndMessage;
   11775 
   11776 		m_has_test_passed = false;
   11777 	}
   11778 }
   11779 
   11780 /** Retrieves fragment shader body.
   11781  *
   11782  *  @param include_invalid_declaration true if the shader should include duplicate function
   11783  *                                     declaration.
   11784  *
   11785  *  @return Requested string.
   11786  **/
   11787 std::string NegativeTest6::getFragmentShaderBody(bool include_invalid_declaration) const
   11788 {
   11789 	std::stringstream result_sstream;
   11790 
   11791 	result_sstream << "#version 400\n"
   11792 					  "\n"
   11793 					  "#extension GL_ARB_shader_subroutine : require\n"
   11794 					  "\n";
   11795 
   11796 	if (include_invalid_declaration)
   11797 	{
   11798 		result_sstream << "subroutine void subroutineTestTypeFS(out vec4 test);\n"
   11799 						  "\n"
   11800 						  "subroutine(subroutineTestTypeFS) void test_impl1(out vec4 test)\n"
   11801 						  "{\n"
   11802 						  "    test = vec4(1, 2, 3, 4);\n"
   11803 						  "}\n"
   11804 						  "\n"
   11805 						  "void test_impl1(out vec4 test)\n"
   11806 						  "{\n"
   11807 						  "    test = vec4(2, 3, 4, 5);\n"
   11808 						  "}\n"
   11809 						  "\n"
   11810 						  "subroutine uniform subroutineTestTypeFS test_subroutineFS;\n";
   11811 	};
   11812 
   11813 	result_sstream << "\n"
   11814 					  "out vec4 result;\n"
   11815 					  "\n"
   11816 					  "void main()\n"
   11817 					  "{\n";
   11818 
   11819 	if (include_invalid_declaration)
   11820 	{
   11821 		result_sstream << "    test_subroutineFS(result);\n";
   11822 	}
   11823 	else
   11824 	{
   11825 		result_sstream << "    result = vec4(0, 1, 2, 3);\n";
   11826 	}
   11827 
   11828 	result_sstream << "}\n";
   11829 
   11830 	return result_sstream.str();
   11831 }
   11832 
   11833 /** Retrieves geometry shader body.
   11834  *
   11835  *  @param include_invalid_declaration true if the shader should include duplicate function
   11836  *                                     declaration.
   11837  *
   11838  *  @return Requested string.
   11839  **/
   11840 std::string NegativeTest6::getGeometryShaderBody(bool include_invalid_declaration) const
   11841 {
   11842 	std::stringstream result_sstream;
   11843 
   11844 	result_sstream << "#version 400\n"
   11845 					  "\n"
   11846 					  "#extension GL_ARB_shader_subroutine : require\n"
   11847 					  "\n"
   11848 					  "layout (points)                   in;\n"
   11849 					  "layout (points, max_vertices = 1) out;\n"
   11850 					  "\n";
   11851 
   11852 	if (include_invalid_declaration)
   11853 	{
   11854 		result_sstream << "subroutine void subroutineTestTypeGS(out vec4 test);\n"
   11855 						  "\n"
   11856 						  "subroutine(subroutineTestTypeGS) void test_impl1(out vec4 test)\n"
   11857 						  "{\n"
   11858 						  "    test = vec4(1, 2, 3, 4);\n"
   11859 						  "}\n"
   11860 						  "\n"
   11861 						  "void test_impl1(out vec4 test)\n"
   11862 						  "{\n"
   11863 						  "    test = vec4(2, 3, 4, 5);\n"
   11864 						  "}\n"
   11865 						  "\n"
   11866 						  "subroutine uniform subroutineTestTypeGS test_subroutineGS;\n";
   11867 	};
   11868 
   11869 	result_sstream << "\n"
   11870 					  "void main()\n"
   11871 					  "{\n";
   11872 
   11873 	if (include_invalid_declaration)
   11874 	{
   11875 		result_sstream << "    test_subroutineGS(gl_Position);\n";
   11876 	}
   11877 	else
   11878 	{
   11879 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   11880 	}
   11881 
   11882 	result_sstream << "EmitVertex();\n"
   11883 					  "}\n";
   11884 
   11885 	return result_sstream.str();
   11886 }
   11887 
   11888 /** Retrieves tessellation control shader body.
   11889  *
   11890  *  @param include_invalid_declaration true if the shader should include duplicate function
   11891  *                                     declaration.
   11892  *
   11893  *  @return Requested string.
   11894  **/
   11895 std::string NegativeTest6::getTessellationControlShaderBody(bool include_invalid_declaration) const
   11896 {
   11897 	std::stringstream result_sstream;
   11898 
   11899 	result_sstream << "#version 400\n"
   11900 					  "\n"
   11901 					  "#extension GL_ARB_shader_subroutine : require\n"
   11902 					  "\n"
   11903 					  "layout (vertices = 4) out;\n"
   11904 					  "\n";
   11905 
   11906 	if (include_invalid_declaration)
   11907 	{
   11908 		result_sstream << "subroutine void subroutineTestTypeTC(out vec4 test);\n"
   11909 						  "\n"
   11910 						  "subroutine(subroutineTestTypeTC) void test_impl1(out vec4 test)\n"
   11911 						  "{\n"
   11912 						  "    test = vec4(1, 2, 3, 4);\n"
   11913 						  "}\n"
   11914 						  "\n"
   11915 						  "void test_impl1(out vec4 test)\n"
   11916 						  "{\n"
   11917 						  "    test = vec4(2, 3, 4, 5);\n"
   11918 						  "}\n"
   11919 						  "\n"
   11920 						  "subroutine uniform subroutineTestTypeTC test_subroutineTC;\n";
   11921 	};
   11922 
   11923 	result_sstream << "\n"
   11924 					  "void main()\n"
   11925 					  "{\n";
   11926 
   11927 	if (include_invalid_declaration)
   11928 	{
   11929 		result_sstream << "    test_subroutineTC(gl_out[gl_InvocationID].gl_Position);\n";
   11930 	}
   11931 	else
   11932 	{
   11933 		result_sstream << "    gl_out[gl_InvocationID].gl_Position = vec4(0, 1, 2, 3);\n";
   11934 	}
   11935 
   11936 	result_sstream << "}\n";
   11937 
   11938 	return result_sstream.str();
   11939 }
   11940 
   11941 /** Retrieves tessellation evaluation body.
   11942  *
   11943  *  @param include_invalid_declaration true if the shader should include duplicate function
   11944  *                                     declaration.
   11945  *
   11946  *  @return Requested string.
   11947  **/
   11948 std::string NegativeTest6::getTessellationEvaluationShaderBody(bool include_invalid_declaration) const
   11949 {
   11950 	std::stringstream result_sstream;
   11951 
   11952 	result_sstream << "#version 400\n"
   11953 					  "\n"
   11954 					  "#extension GL_ARB_shader_subroutine : require\n"
   11955 					  "\n"
   11956 					  "layout (quads) in;\n"
   11957 					  "\n";
   11958 
   11959 	if (include_invalid_declaration)
   11960 	{
   11961 		result_sstream << "subroutine void subroutineTestTypeTE(out vec4 test);\n"
   11962 						  "\n"
   11963 						  "subroutine(subroutineTestTypeTE) void test_impl1(out vec4 test)\n"
   11964 						  "{\n"
   11965 						  "    test = vec4(1, 2, 3, 4);\n"
   11966 						  "}\n"
   11967 						  "\n"
   11968 						  "void test_impl1(out vec4 test)\n"
   11969 						  "{\n"
   11970 						  "    test = vec4(2, 3, 4, 5);\n"
   11971 						  "}\n"
   11972 						  "\n"
   11973 						  "subroutine uniform subroutineTestTypeTE test_subroutineTE;\n";
   11974 	};
   11975 
   11976 	result_sstream << "\n"
   11977 					  "void main()\n"
   11978 					  "{\n";
   11979 
   11980 	if (include_invalid_declaration)
   11981 	{
   11982 		result_sstream << "    test_subroutineTE(gl_Position);\n";
   11983 	}
   11984 	else
   11985 	{
   11986 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   11987 	}
   11988 
   11989 	result_sstream << "}\n";
   11990 
   11991 	return result_sstream.str();
   11992 }
   11993 
   11994 /** Retrieves vertex shader body.
   11995  *
   11996  *  @param include_invalid_declaration true if the shader should include duplicate function
   11997  *                                     declaration.
   11998  *
   11999  *  @return Requested string.
   12000  **/
   12001 std::string NegativeTest6::getVertexShaderBody(bool include_invalid_declaration) const
   12002 {
   12003 	std::stringstream result_sstream;
   12004 
   12005 	result_sstream << "#version 400\n"
   12006 					  "\n"
   12007 					  "#extension GL_ARB_shader_subroutine : require\n"
   12008 					  "\n";
   12009 
   12010 	if (include_invalid_declaration)
   12011 	{
   12012 		result_sstream << "subroutine void subroutineTestTypeVS(out vec4 test);\n"
   12013 						  "\n"
   12014 						  "subroutine(subroutineTestTypeVS) void test_impl1(out vec4 test)\n"
   12015 						  "{\n"
   12016 						  "    test = vec4(1, 2, 3, 4);\n"
   12017 						  "}\n"
   12018 						  "\n"
   12019 						  "void test_impl1(out vec4 test)\n"
   12020 						  "{\n"
   12021 						  "    test = vec4(2, 3, 4, 5);\n"
   12022 						  "}\n"
   12023 						  "\n"
   12024 						  "subroutine uniform subroutineTestTypeVS test_subroutineVS;\n";
   12025 	};
   12026 
   12027 	result_sstream << "\n"
   12028 					  "void main()\n"
   12029 					  "{\n";
   12030 
   12031 	if (include_invalid_declaration)
   12032 	{
   12033 		result_sstream << "    test_subroutineVS(gl_Position);\n";
   12034 	}
   12035 	else
   12036 	{
   12037 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   12038 	}
   12039 
   12040 	result_sstream << "}\n";
   12041 
   12042 	return result_sstream.str();
   12043 }
   12044 
   12045 /** Executes test iteration.
   12046  *
   12047  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   12048  */
   12049 tcu::TestNode::IterateResult NegativeTest6::iterate()
   12050 {
   12051 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   12052 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   12053 	{
   12054 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   12055 	}
   12056 
   12057 	/* Iterate over all shader stages. In each iteration, we will inject invalid
   12058 	 * duplicate function declarations to iteration-specific shader stage. All other
   12059 	 * shader stages will be assigned valid bodies. Test should fail if the program
   12060 	 * links successfully.
   12061 	 */
   12062 	for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   12063 		 shader_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage)
   12064 	{
   12065 		executeIteration(static_cast<Utils::_shader_stage>(shader_stage));
   12066 		deinitIteration();
   12067 	} /* for (all shader stages) */
   12068 
   12069 	/* All done */
   12070 	if (m_has_test_passed)
   12071 	{
   12072 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   12073 	}
   12074 	else
   12075 	{
   12076 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   12077 	}
   12078 
   12079 	return STOP;
   12080 }
   12081 
   12082 /** Constructor
   12083  *
   12084  * @param context CTS context
   12085  **/
   12086 NegativeTest7::NegativeTest7(deqp::Context& context)
   12087 	: TestCase(context, "recursion", "Verify that it is not possible to build program with recursing subroutines")
   12088 	, m_program_id(0)
   12089 	, m_vertex_shader_id(0)
   12090 {
   12091 	/* Nothing to be done here */
   12092 }
   12093 
   12094 /** Deinitializes all GL objects that may have been created during test execution
   12095  *
   12096  **/
   12097 void NegativeTest7::deinit()
   12098 {
   12099 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   12100 
   12101 	if (m_program_id != 0)
   12102 	{
   12103 		gl.deleteProgram(m_program_id);
   12104 
   12105 		m_program_id = 0;
   12106 	}
   12107 
   12108 	if (m_vertex_shader_id != 0)
   12109 	{
   12110 		gl.deleteShader(m_vertex_shader_id);
   12111 
   12112 		m_vertex_shader_id = 0;
   12113 	}
   12114 }
   12115 
   12116 /** Executes test iteration.
   12117  *
   12118  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   12119  **/
   12120 tcu::TestNode::IterateResult NegativeTest7::iterate()
   12121 {
   12122 	static const GLchar* vertex_shader_with_static_recursion =
   12123 		"#version 400\n"
   12124 		"\n"
   12125 		"#extension GL_ARB_shader_subroutine : require\n"
   12126 		"\n"
   12127 		"precision highp float;\n"
   12128 		"\n"
   12129 		"subroutine vec4 routine_type(in vec4 data, in uint control);\n"
   12130 		"\n"
   12131 		"subroutine (routine_type) vec4 power_routine(in vec4 data, in uint control)\n"
   12132 		"{\n"
   12133 		"    if (0 != control)\n"
   12134 		"    {\n"
   12135 		"        return data * power_routine(data, control - 1);\n"
   12136 		"    }\n"
   12137 		"    else\n"
   12138 		"    {\n"
   12139 		"        return vec4(1, 1, 1, 1);\n"
   12140 		"    }\n"
   12141 		"}\n"
   12142 		"\n"
   12143 		"subroutine (routine_type) vec4 select_routine(in vec4 data, in uint control)\n"
   12144 		"{\n"
   12145 		"    if (0 == control)\n"
   12146 		"    {\n"
   12147 		"        return data.rrrr;\n"
   12148 		"    }\n"
   12149 		"    else if (1 == control)\n"
   12150 		"    {\n"
   12151 		"        return data.gggg;\n"
   12152 		"    }\n"
   12153 		"    else if (2 == control)\n"
   12154 		"    {\n"
   12155 		"        return data.bbbb;\n"
   12156 		"    }\n"
   12157 		"    else\n"
   12158 		"    {\n"
   12159 		"        return data.aaaa;\n"
   12160 		"    }\n"
   12161 		"}\n"
   12162 		"\n"
   12163 		"subroutine uniform routine_type routine;\n"
   12164 		"\n"
   12165 		"uniform vec4 uni_value;\n"
   12166 		"uniform uint uni_control;\n"
   12167 		"\n"
   12168 		"out vec4 out_result;\n"
   12169 		"\n"
   12170 		"void main()\n"
   12171 		"{\n"
   12172 		"    out_result = routine(uni_value, uni_control);\n"
   12173 		"}\n"
   12174 		"\n";
   12175 
   12176 	static const GLchar* vertex_shader_with_dynamic_recursion =
   12177 		"#version 400\n"
   12178 		"\n"
   12179 		"#extension GL_ARB_shader_subroutine : require\n"
   12180 		"\n"
   12181 		"precision highp float;\n"
   12182 		"\n"
   12183 		"subroutine vec4 routine_type(in vec4 data);\n"
   12184 		"\n"
   12185 		"subroutine uniform routine_type routine;\n"
   12186 		"\n"
   12187 		"subroutine (routine_type) vec4 div_by_2(in vec4 data)\n"
   12188 		"{\n"
   12189 		"    return data / 2;\n"
   12190 		"}\n"
   12191 		"\n"
   12192 		"subroutine (routine_type) vec4 div_routine_result_by_2(in vec4 data)\n"
   12193 		"{\n"
   12194 		"    return routine(data) / 2;\n"
   12195 		"}\n"
   12196 		"\n"
   12197 		"uniform vec4 uni_value;\n"
   12198 		"\n"
   12199 		"out vec4 out_result;\n"
   12200 		"\n"
   12201 		"void main()\n"
   12202 		"{\n"
   12203 		"    out_result = routine(uni_value);\n"
   12204 		"}\n"
   12205 		"\n";
   12206 
   12207 	static const GLchar* vertex_shader_with_subroutine_function_recursion =
   12208 		"#version 400\n"
   12209 		"\n"
   12210 		"#extension GL_ARB_shader_subroutine : require\n"
   12211 		"\n"
   12212 		"precision highp float;\n"
   12213 		"\n"
   12214 		"subroutine vec4 routine_type(in vec4 data);\n"
   12215 		"\n"
   12216 		"subroutine uniform routine_type routine;\n"
   12217 		"\n"
   12218 		"vec4 function(in vec4 data)\n"
   12219 		"{\n"
   12220 		"    return routine(data) + vec4(0.5, 0.5, 0.5, 0.5);\n"
   12221 		"}\n"
   12222 		"\n"
   12223 		"subroutine (routine_type) vec4 routine_a(in vec4 data)\n"
   12224 		"{\n"
   12225 		"    return function(data) / 2;\n"
   12226 		"}\n"
   12227 		"\n"
   12228 		"subroutine (routine_type) vec4 routine_b(in vec4 data)\n"
   12229 		"{\n"
   12230 		"    return routine_a(data) * 2;\n"
   12231 		"}\n"
   12232 		"\n"
   12233 		"uniform vec4 uni_value;\n"
   12234 		"\n"
   12235 		"out vec4 out_result;\n"
   12236 		"\n"
   12237 		"void main()\n"
   12238 		"{\n"
   12239 		"    out_result = routine(uni_value);\n"
   12240 		"}\n"
   12241 		"\n";
   12242 
   12243 	bool result = true;
   12244 
   12245 	if (false == test(vertex_shader_with_subroutine_function_recursion, "routine_a"))
   12246 	{
   12247 		result = false;
   12248 	}
   12249 
   12250 	if (false == test(vertex_shader_with_dynamic_recursion, "div_routine_result_by_2"))
   12251 	{
   12252 		result = false;
   12253 	}
   12254 
   12255 	if (false == test(vertex_shader_with_static_recursion, "power_routine"))
   12256 	{
   12257 		result = false;
   12258 	}
   12259 
   12260 	/* Set result */
   12261 	if (true == result)
   12262 	{
   12263 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   12264 	}
   12265 	else
   12266 	{
   12267 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   12268 	}
   12269 
   12270 	/* Done */
   12271 	return tcu::TestNode::STOP;
   12272 }
   12273 
   12274 /** Try to build program from vertex shader code.
   12275  *
   12276  * @param vertex_shader_code        Source code of vertex shader
   12277  * @param name_of_recursive_routine Name of subroutine that should cause link failure due to recursion
   12278  *
   12279  * @return true build process failed, false otherwise
   12280  **/
   12281 bool NegativeTest7::test(const GLchar* vertex_shader_code, const GLchar* name_of_recursive_routine)
   12282 {
   12283 	const glw::Functions& gl		   = m_context.getRenderContext().getFunctions();
   12284 	bool				  result	   = true;
   12285 	static const GLchar*  varying_name = "out_result";
   12286 
   12287 	/* Try to build program */
   12288 	if (true == Utils::buildProgram(gl, vertex_shader_code, "", "", "", "", &varying_name /* varying_names */,
   12289 									1 /* n_varyings */, &m_vertex_shader_id, 0, 0, 0, 0, &m_program_id))
   12290 	{
   12291 		/* Success is considered an error */
   12292 
   12293 		Utils::program program(m_context);
   12294 		GLuint		   index = 0;
   12295 
   12296 		program.build(0, 0, 0, 0, 0, vertex_shader_code, 0, 0);
   12297 
   12298 		/* Verify that recursive subroutine is active */
   12299 		try
   12300 		{
   12301 			index = program.getSubroutineIndex(name_of_recursive_routine, GL_VERTEX_SHADER);
   12302 		}
   12303 		catch (const std::exception& exc)
   12304 		{
   12305 			/* Something wrong with shader or compilation */
   12306 			m_context.getTestContext().getLog()
   12307 				<< tcu::TestLog::Message << "It is expected that subroutine: \n"
   12308 				<< name_of_recursive_routine
   12309 				<< " is considered active. This subroutine is potentially recursive and should cause link failure."
   12310 				<< tcu::TestLog::EndMessage;
   12311 
   12312 			throw exc;
   12313 		}
   12314 
   12315 		/* Subsoutine is active, however linking should fail */
   12316 		m_context.getTestContext().getLog()
   12317 			<< tcu::TestLog::Message << "Error. Program with potentially recursive subroutine, "
   12318 			<< name_of_recursive_routine << ", which is active, index: " << index << ", has been built successfully.\n"
   12319 			<< vertex_shader_code << tcu::TestLog::EndMessage;
   12320 
   12321 		result = false;
   12322 	}
   12323 
   12324 	/* Delete program and shader */
   12325 	deinit();
   12326 
   12327 	/* Done */
   12328 	return result;
   12329 }
   12330 
   12331 /** Constructor.
   12332  *
   12333  *  @param context Rendering context.
   12334  *
   12335  **/
   12336 NegativeTest8::NegativeTest8(deqp::Context& context)
   12337 	: TestCase(context, "subroutine_wo_body", "Verifies that a compile- or link-time error occurs if a function "
   12338 											  "declared as a subroutine does not include a body.")
   12339 	, m_fs_id(0)
   12340 	, m_gs_id(0)
   12341 	, m_has_test_passed(true)
   12342 	, m_po_id(0)
   12343 	, m_tc_id(0)
   12344 	, m_te_id(0)
   12345 	, m_vs_id(0)
   12346 {
   12347 	/* Left blank intentionally */
   12348 }
   12349 
   12350 /** Deinitializes all GL objects that may have been created during test execution */
   12351 void NegativeTest8::deinit()
   12352 {
   12353 	deinitIteration();
   12354 }
   12355 
   12356 /** Deinitializes all GL objects that may have been created during a single test
   12357  *  iteration.
   12358  ***/
   12359 void NegativeTest8::deinitIteration()
   12360 {
   12361 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   12362 
   12363 	if (m_fs_id != 0)
   12364 	{
   12365 		gl.deleteShader(m_fs_id);
   12366 
   12367 		m_fs_id = 0;
   12368 	}
   12369 
   12370 	if (m_gs_id != 0)
   12371 	{
   12372 		gl.deleteShader(m_gs_id);
   12373 
   12374 		m_gs_id = 0;
   12375 	}
   12376 
   12377 	if (m_po_id != 0)
   12378 	{
   12379 		gl.deleteProgram(m_po_id);
   12380 
   12381 		m_po_id = 0;
   12382 	}
   12383 
   12384 	if (m_tc_id != 0)
   12385 	{
   12386 		gl.deleteShader(m_tc_id);
   12387 
   12388 		m_tc_id = 0;
   12389 	}
   12390 
   12391 	if (m_te_id != 0)
   12392 	{
   12393 		gl.deleteShader(m_te_id);
   12394 
   12395 		m_te_id = 0;
   12396 	}
   12397 
   12398 	if (m_vs_id != 0)
   12399 	{
   12400 		gl.deleteShader(m_vs_id);
   12401 
   12402 		m_vs_id = 0;
   12403 	}
   12404 }
   12405 
   12406 /** Executes a single test iteration.
   12407  *
   12408  *  If the iteration fails, m_has_test_passed will be set to false.
   12409  *
   12410  *  @param shader_stage Shader stage, for which two duplicate functions
   12411  *                      (one additionally marked as subroutine) should
   12412  *                      be defined.
   12413  **/
   12414 void NegativeTest8::executeIteration(const Utils::_shader_stage& shader_stage)
   12415 {
   12416 	std::string fs_body = getFragmentShaderBody(shader_stage == Utils::SHADER_STAGE_FRAGMENT);
   12417 	std::string gs_body = getGeometryShaderBody(shader_stage == Utils::SHADER_STAGE_GEOMETRY);
   12418 	std::string tc_body = getTessellationControlShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_CONTROL);
   12419 	std::string te_body =
   12420 		getTessellationEvaluationShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_EVALUATION);
   12421 	std::string vs_body = getVertexShaderBody(shader_stage == Utils::SHADER_STAGE_VERTEX);
   12422 
   12423 	if (Utils::buildProgram(m_context.getRenderContext().getFunctions(), vs_body, tc_body, te_body, gs_body, fs_body,
   12424 							DE_NULL, /* xfb_varyings */
   12425 							DE_NULL, /* n_xfb_varyings */
   12426 							&m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id))
   12427 	{
   12428 		/* None of the test programs should ever build successfully */
   12429 		m_testCtx.getLog() << tcu::TestLog::Message
   12430 						   << "A program object consisting of FS+GS+TC+TE+VS stages has linked successfully, "
   12431 							  "even though one of the shaders only defines a subroutine that lacks any body."
   12432 							  "\n"
   12433 							  "Vertex shader:\n"
   12434 							  "\n"
   12435 						   << vs_body << "\n"
   12436 										 "Tessellation control shader:\n"
   12437 										 "\n"
   12438 						   << tc_body << "\n"
   12439 										 "Tessellation evaluation shader:\n"
   12440 										 "\n"
   12441 						   << te_body << "\n"
   12442 										 "Geometry shader:\n"
   12443 										 "\n"
   12444 						   << gs_body << "\n"
   12445 										 "Fragment shader:\n"
   12446 										 "\n"
   12447 						   << fs_body << tcu::TestLog::EndMessage;
   12448 
   12449 		m_has_test_passed = false;
   12450 	}
   12451 }
   12452 
   12453 /** Retrieves fragment shader body.
   12454  *
   12455  *  @param include_invalid_declaration true if a subroutine prototype should be included in
   12456  *                                     the shader, false to skip it.
   12457  *
   12458  *  @return Requested string.
   12459  **/
   12460 std::string NegativeTest8::getFragmentShaderBody(bool include_invalid_declaration) const
   12461 {
   12462 	std::stringstream result_sstream;
   12463 
   12464 	result_sstream << "#version 400\n"
   12465 					  "\n"
   12466 					  "#extension GL_ARB_shader_subroutine : require\n"
   12467 					  "\n";
   12468 
   12469 	if (include_invalid_declaration)
   12470 	{
   12471 		result_sstream << "subroutine void subroutineTestTypeFS(out vec4 test);\n"
   12472 						  "\n"
   12473 						  "subroutine(subroutineTestTypeFS) void test_impl1(out vec4 test);\n"
   12474 						  "\n"
   12475 						  "subroutine uniform subroutineTestTypeFS test_subroutineFS;\n";
   12476 	};
   12477 
   12478 	result_sstream << "\n"
   12479 					  "out vec4 result;\n"
   12480 					  "\n"
   12481 					  "void main()\n"
   12482 					  "{\n";
   12483 
   12484 	if (include_invalid_declaration)
   12485 	{
   12486 		result_sstream << "    test_subroutineFS(result);\n";
   12487 	}
   12488 	else
   12489 	{
   12490 		result_sstream << "    result = vec4(0, 1, 2, 3);\n";
   12491 	}
   12492 
   12493 	result_sstream << "}\n";
   12494 
   12495 	return result_sstream.str();
   12496 }
   12497 
   12498 /** Retrieves geometry shader body.
   12499  *
   12500  *  @param include_invalid_declaration true if a subroutine prototype should be included in
   12501  *                                     the shader, false to skip it.
   12502  *
   12503  *  @return Requested string.
   12504  **/
   12505 std::string NegativeTest8::getGeometryShaderBody(bool include_invalid_declaration) const
   12506 {
   12507 	std::stringstream result_sstream;
   12508 
   12509 	result_sstream << "#version 400\n"
   12510 					  "\n"
   12511 					  "#extension GL_ARB_shader_subroutine : require\n"
   12512 					  "\n"
   12513 					  "layout (points)                   in;\n"
   12514 					  "layout (points, max_vertices = 1) out;\n"
   12515 					  "\n";
   12516 
   12517 	if (include_invalid_declaration)
   12518 	{
   12519 		result_sstream << "subroutine void subroutineTestTypeGS(out vec4 test);\n"
   12520 						  "\n"
   12521 						  "subroutine(subroutineTestTypeGS) void test_impl1(out vec4 test);\n"
   12522 						  "\n"
   12523 						  "subroutine uniform subroutineTestTypeGS test_subroutineGS;\n";
   12524 	};
   12525 
   12526 	result_sstream << "\n"
   12527 					  "void main()\n"
   12528 					  "{\n";
   12529 
   12530 	if (include_invalid_declaration)
   12531 	{
   12532 		result_sstream << "    test_subroutineGS(gl_Position);\n";
   12533 	}
   12534 	else
   12535 	{
   12536 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   12537 	}
   12538 
   12539 	result_sstream << "EmitVertex();\n"
   12540 					  "}\n";
   12541 
   12542 	return result_sstream.str();
   12543 }
   12544 
   12545 /** Retrieves tessellation control shader body.
   12546  *
   12547  *  @param include_invalid_declaration true if a subroutine prototype should be included in
   12548  *                                     the shader, false to skip it.
   12549  *
   12550  *  @return Requested string.
   12551  **/
   12552 std::string NegativeTest8::getTessellationControlShaderBody(bool include_invalid_declaration) const
   12553 {
   12554 	std::stringstream result_sstream;
   12555 
   12556 	result_sstream << "#version 400\n"
   12557 					  "\n"
   12558 					  "#extension GL_ARB_shader_subroutine : require\n"
   12559 					  "\n"
   12560 					  "layout (vertices = 4) out;\n"
   12561 					  "\n";
   12562 
   12563 	if (include_invalid_declaration)
   12564 	{
   12565 		result_sstream << "subroutine void subroutineTestTypeTC(out vec4 test);\n"
   12566 						  "\n"
   12567 						  "subroutine(subroutineTestTypeTC) void test_impl1(out vec4 test);\n"
   12568 						  "\n"
   12569 						  "subroutine uniform subroutineTestTypeTC test_subroutineTC;\n";
   12570 	};
   12571 
   12572 	result_sstream << "\n"
   12573 					  "void main()\n"
   12574 					  "{\n";
   12575 
   12576 	if (include_invalid_declaration)
   12577 	{
   12578 		result_sstream << "    test_subroutineTC(gl_out[gl_InvocationID].gl_Position);\n";
   12579 	}
   12580 	else
   12581 	{
   12582 		result_sstream << "    gl_out[gl_InvocationID].gl_Position = vec4(0, 1, 2, 3);\n";
   12583 	}
   12584 
   12585 	result_sstream << "}\n";
   12586 
   12587 	return result_sstream.str();
   12588 }
   12589 
   12590 /** Retrieves tessellation evaluation body.
   12591  *
   12592  *  @param include_invalid_declaration true if a subroutine prototype should be included in
   12593  *                                     the shader, false to skip it.
   12594  *
   12595  *  @return Requested string.
   12596  **/
   12597 std::string NegativeTest8::getTessellationEvaluationShaderBody(bool include_invalid_declaration) const
   12598 {
   12599 	std::stringstream result_sstream;
   12600 
   12601 	result_sstream << "#version 400\n"
   12602 					  "\n"
   12603 					  "#extension GL_ARB_shader_subroutine : require\n"
   12604 					  "\n"
   12605 					  "layout (quads) in;\n"
   12606 					  "\n";
   12607 
   12608 	if (include_invalid_declaration)
   12609 	{
   12610 		result_sstream << "subroutine void subroutineTestTypeTE(out vec4 test);\n"
   12611 						  "\n"
   12612 						  "subroutine(subroutineTestTypeTE) void test_impl1(out vec4 test);\n"
   12613 						  "\n"
   12614 						  "subroutine uniform subroutineTestTypeTE test_subroutineTE;\n";
   12615 	};
   12616 
   12617 	result_sstream << "\n"
   12618 					  "void main()\n"
   12619 					  "{\n";
   12620 
   12621 	if (include_invalid_declaration)
   12622 	{
   12623 		result_sstream << "    test_subroutineTE(gl_Position);\n";
   12624 	}
   12625 	else
   12626 	{
   12627 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   12628 	}
   12629 
   12630 	result_sstream << "}\n";
   12631 
   12632 	return result_sstream.str();
   12633 }
   12634 
   12635 /** Retrieves vertex shader body.
   12636  *
   12637  *  @param include_invalid_declaration true if a subroutine prototype should be included in
   12638  *                                     the shader, false to skip it.
   12639  *
   12640  *  @return Requested string.
   12641  **/
   12642 std::string NegativeTest8::getVertexShaderBody(bool include_invalid_declaration) const
   12643 {
   12644 	std::stringstream result_sstream;
   12645 
   12646 	result_sstream << "#version 400\n"
   12647 					  "\n"
   12648 					  "#extension GL_ARB_shader_subroutine : require\n"
   12649 					  "\n";
   12650 
   12651 	if (include_invalid_declaration)
   12652 	{
   12653 		result_sstream << "subroutine void subroutineTestTypeVS(out vec4 test);\n"
   12654 						  "\n"
   12655 						  "subroutine(subroutineTestTypeVS) void test_impl1(out vec4 test);\n"
   12656 						  "\n"
   12657 						  "subroutine uniform subroutineTestTypeVS test_subroutineVS;\n";
   12658 	};
   12659 
   12660 	result_sstream << "\n"
   12661 					  "void main()\n"
   12662 					  "{\n";
   12663 
   12664 	if (include_invalid_declaration)
   12665 	{
   12666 		result_sstream << "    test_subroutineVS(gl_Position);\n";
   12667 	}
   12668 	else
   12669 	{
   12670 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   12671 	}
   12672 
   12673 	result_sstream << "}\n";
   12674 
   12675 	return result_sstream.str();
   12676 }
   12677 
   12678 /** Executes test iteration.
   12679  *
   12680  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   12681  */
   12682 tcu::TestNode::IterateResult NegativeTest8::iterate()
   12683 {
   12684 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   12685 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   12686 	{
   12687 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   12688 	}
   12689 
   12690 	/* Iterate over all shader stages. For each iteration, iteration-specific shader stage
   12691 	 * will feature an invalid subroutine definition. Other shader stages will be assigned
   12692 	 * valid bodies. The test fails if a program built of such shaders links successfully.
   12693 	 */
   12694 	for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   12695 		 shader_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage)
   12696 	{
   12697 		executeIteration(static_cast<Utils::_shader_stage>(shader_stage));
   12698 		deinitIteration();
   12699 	} /* for (all shader stages) */
   12700 
   12701 	/* All done */
   12702 	if (m_has_test_passed)
   12703 	{
   12704 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   12705 	}
   12706 	else
   12707 	{
   12708 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   12709 	}
   12710 
   12711 	return STOP;
   12712 }
   12713 
   12714 /** Constructor.
   12715  *
   12716  *  @param context Rendering context.
   12717  **/
   12718 NegativeTest9::NegativeTest9(deqp::Context& context)
   12719 	: TestCase(context, "subroutines_cannot_be_assigned_float_int_values_or_be_compared",
   12720 			   "Make sure it is not possible to assign float/int to subroutine "
   12721 			   "uniform and that subroutine uniform values cannot be compared.")
   12722 	, m_has_test_passed(true)
   12723 	, m_po_id(0)
   12724 	, m_vs_id(0)
   12725 {
   12726 	/* Left blank intentionally */
   12727 }
   12728 
   12729 /** Deinitializes any GL objects that may have been created during
   12730  *  test execution.
   12731  **/
   12732 void NegativeTest9::deinit()
   12733 {
   12734 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   12735 
   12736 	if (m_po_id != 0)
   12737 	{
   12738 		gl.deleteProgram(m_po_id);
   12739 
   12740 		m_po_id = 0;
   12741 	}
   12742 
   12743 	if (m_vs_id != 0)
   12744 	{
   12745 		gl.deleteShader(m_vs_id);
   12746 
   12747 		m_vs_id = 0;
   12748 	}
   12749 }
   12750 
   12751 /** Returns a literal corresponding to user-specified test case enum.
   12752  *
   12753  *  @param test_case As per description.
   12754  *
   12755  *  @return Requested string.
   12756  **/
   12757 std::string NegativeTest9::getTestCaseString(const _test_case& test_case)
   12758 {
   12759 	std::string result = "?";
   12760 
   12761 	switch (test_case)
   12762 	{
   12763 	case TEST_CASE_INVALID_FLOAT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT:
   12764 		result = "TEST_CASE_INVALID_FLOAT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT";
   12765 		break;
   12766 	case TEST_CASE_INVALID_INT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT:
   12767 		result = "TEST_CASE_INVALID_INT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT";
   12768 		break;
   12769 	case TEST_CASE_INVALID_SUBROUTINE_UNIFORM_VALUE_COMPARISON:
   12770 		result = "TEST_CASE_INVALID_SUBROUTINE_UNIFORM_VALUE_COMPARISON";
   12771 		break;
   12772 	default:
   12773 		break;
   12774 	}
   12775 
   12776 	return result;
   12777 }
   12778 
   12779 /** Retrieves vertex shader body for user-specified test case.
   12780  *
   12781  *  @param test_case As per description.
   12782  *
   12783  *  @return Requested string.
   12784  **/
   12785 std::string NegativeTest9::getVertexShader(const _test_case& test_case)
   12786 {
   12787 	std::stringstream result_sstream;
   12788 
   12789 	/* Form pre-amble */
   12790 	result_sstream << "#version 400\n"
   12791 					  "\n"
   12792 					  "#extension GL_ARB_shader_subroutine : require\n"
   12793 					  "\n"
   12794 					  /* Define a subroutine */
   12795 					  "subroutine void subroutineType(inout vec4 test);\n"
   12796 					  "\n"
   12797 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   12798 					  "{\n"
   12799 					  "    test += vec4(0, 1, 2, 3);\n"
   12800 					  "}\n"
   12801 					  "\n"
   12802 					  "subroutine uniform subroutineType function;\n"
   12803 					  "\n";
   12804 
   12805 	/* Include case-specific implementation */
   12806 	switch (test_case)
   12807 	{
   12808 	case TEST_CASE_INVALID_FLOAT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT:
   12809 	{
   12810 		result_sstream << "void main()\n"
   12811 						  "{\n"
   12812 						  "    function = 1.0f;\n"
   12813 						  "\n"
   12814 						  "    function(gl_Position);\n"
   12815 						  "}\n";
   12816 
   12817 		break;
   12818 	}
   12819 
   12820 	case TEST_CASE_INVALID_INT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT:
   12821 	{
   12822 		result_sstream << "void main()\n"
   12823 						  "{\n"
   12824 						  "    function = 1;\n"
   12825 						  "\n"
   12826 						  "    function(gl_Position);\n"
   12827 						  "}\n";
   12828 
   12829 		break;
   12830 	}
   12831 
   12832 	case TEST_CASE_INVALID_SUBROUTINE_UNIFORM_VALUE_COMPARISON:
   12833 	{
   12834 		result_sstream << "subroutine uniform subroutineType function2;\n"
   12835 						  "\n"
   12836 						  "void main()\n"
   12837 						  "{\n"
   12838 						  "    if (function == function2)\n"
   12839 						  "    {\n"
   12840 						  "        function(gl_Position);\n"
   12841 						  "    }\n"
   12842 						  "    else\n"
   12843 						  "    {\n"
   12844 						  "        function2(gl_Position);\n"
   12845 						  "    }\n"
   12846 						  "}\n";
   12847 
   12848 		break;
   12849 	}
   12850 
   12851 	default:
   12852 		break;
   12853 	} /* switch (test_case) */
   12854 
   12855 	/* Done */
   12856 	return result_sstream.str();
   12857 }
   12858 
   12859 /** Executes test iteration.
   12860  *
   12861  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   12862  */
   12863 tcu::TestNode::IterateResult NegativeTest9::iterate()
   12864 {
   12865 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   12866 
   12867 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   12868 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   12869 	{
   12870 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   12871 	}
   12872 
   12873 	/* Iterate over all test cases */
   12874 	for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT); ++test_case)
   12875 	{
   12876 		/* Try to build a program object using invalid vertex shader, specific to the
   12877 		 * iteration we're currently in */
   12878 		std::string vs_body = getVertexShader(static_cast<_test_case>(test_case));
   12879 
   12880 		if (ShaderSubroutine::Utils::buildProgram(gl, vs_body, "",   /* tc_body */
   12881 												  "",				 /* te_body */
   12882 												  "",				 /* gs_body */
   12883 												  "",				 /* fs_body */
   12884 												  DE_NULL,			 /* xfb_varyings */
   12885 												  0,				 /* n_xfb_varyings */
   12886 												  &m_vs_id, DE_NULL, /* out_tc_id */
   12887 												  DE_NULL,			 /* out_te_id */
   12888 												  DE_NULL,			 /* out_gs_id */
   12889 												  DE_NULL,			 /* out_fs_id */
   12890 												  &m_po_id))
   12891 		{
   12892 			m_testCtx.getLog() << tcu::TestLog::Message << "A program object was successfully built for ["
   12893 							   << getTestCaseString(static_cast<_test_case>(test_case))
   12894 							   << "] test case, even though it was invalid." << tcu::TestLog::EndMessage;
   12895 
   12896 			m_has_test_passed = false;
   12897 		}
   12898 
   12899 		/* Delete any objects that may have been created */
   12900 		deinit();
   12901 	} /* for (all test cases) */
   12902 
   12903 	/** All done */
   12904 	if (m_has_test_passed)
   12905 	{
   12906 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   12907 	}
   12908 	else
   12909 	{
   12910 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   12911 	}
   12912 
   12913 	return STOP;
   12914 }
   12915 
   12916 /** Constructor.
   12917  *
   12918  *  @param context Rendering context.
   12919  **/
   12920 NegativeTest10::NegativeTest10(deqp::Context& context)
   12921 	: TestCase(context, "function_overloading_forbidden_for_subroutines",
   12922 			   "Check that an overloaded function cannot be declared with subroutine and "
   12923 			   "a program will fail to compile or link if any shader or stage contains"
   12924 			   " two or more  functions with the same name if the name is associated with"
   12925 			   " a subroutine type.")
   12926 	, m_has_test_passed(true)
   12927 	, m_fs_id(0)
   12928 	, m_gs_id(0)
   12929 	, m_po_id(0)
   12930 	, m_tc_id(0)
   12931 	, m_te_id(0)
   12932 	, m_vs_id(0)
   12933 {
   12934 	/* Left blank intentionally */
   12935 }
   12936 
   12937 /** Deinitializes any GL objects that may have been created during
   12938  *  test execution.
   12939  **/
   12940 void NegativeTest10::deinit()
   12941 {
   12942 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   12943 
   12944 	if (m_fs_id != 0)
   12945 	{
   12946 		gl.deleteShader(m_fs_id);
   12947 
   12948 		m_fs_id = 0;
   12949 	}
   12950 
   12951 	if (m_gs_id != 0)
   12952 	{
   12953 		gl.deleteShader(m_gs_id);
   12954 
   12955 		m_gs_id = 0;
   12956 	}
   12957 
   12958 	if (m_po_id != 0)
   12959 	{
   12960 		gl.deleteProgram(m_po_id);
   12961 
   12962 		m_po_id = 0;
   12963 	}
   12964 
   12965 	if (m_tc_id != 0)
   12966 	{
   12967 		gl.deleteShader(m_tc_id);
   12968 
   12969 		m_tc_id = 0;
   12970 	}
   12971 
   12972 	if (m_te_id != 0)
   12973 	{
   12974 		gl.deleteShader(m_te_id);
   12975 
   12976 		m_te_id = 0;
   12977 	}
   12978 
   12979 	if (m_vs_id != 0)
   12980 	{
   12981 		gl.deleteShader(m_vs_id);
   12982 
   12983 		m_vs_id = 0;
   12984 	}
   12985 }
   12986 
   12987 /** Retrieves fragment shader that should be used for the purpose of the test.
   12988  *  An overloaded version of a subroutine function is inserted if
   12989  *  @param include_duplicate_function flag is set to true.
   12990  *
   12991  *  @param include_duplicate_function As per description.
   12992  *
   12993  *  @return Requested string.
   12994  **/
   12995 std::string NegativeTest10::getFragmentShader(bool include_duplicate_function)
   12996 {
   12997 	std::stringstream result_sstream;
   12998 
   12999 	result_sstream << "#version 400\n"
   13000 					  "\n"
   13001 					  "#extension GL_ARB_shader_subroutine : require\n"
   13002 					  "\n"
   13003 					  "subroutine void subroutineType(inout vec4 test);\n"
   13004 					  "\n"
   13005 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   13006 					  "{\n"
   13007 					  "    test = vec4(2, 3, 4, 5);\n"
   13008 					  "}\n"
   13009 					  "\n"
   13010 					  "subroutine uniform subroutineType function;\n"
   13011 					  "out vec4 result;\n"
   13012 					  "\n";
   13013 
   13014 	if (include_duplicate_function)
   13015 	{
   13016 		result_sstream << "void test_function(inout vec4 test)\n"
   13017 						  "{\n"
   13018 						  "    test = vec4(3, 4, 5, 6);\n"
   13019 						  "}\n"
   13020 						  "\n";
   13021 	}
   13022 
   13023 	result_sstream << "void main()\n"
   13024 					  "{\n"
   13025 					  "    test_function(result);\n"
   13026 					  "}\n";
   13027 
   13028 	return result_sstream.str();
   13029 }
   13030 
   13031 /** Retrieves geometry shader that should be used for the purpose of the test.
   13032  *  An overloaded version of a subroutine function is inserted if
   13033  *  @param include_duplicate_function flag is set to true.
   13034  *
   13035  *  @param include_duplicate_function As per description.
   13036  *
   13037  *  @return Requested string.
   13038  **/
   13039 std::string NegativeTest10::getGeometryShader(bool include_duplicate_function)
   13040 {
   13041 	std::stringstream result_sstream;
   13042 
   13043 	result_sstream << "#version 400\n"
   13044 					  "\n"
   13045 					  "#extension GL_ARB_shader_subroutine : require\n"
   13046 					  "\n"
   13047 					  "layout (triangles)                        in;\n"
   13048 					  "layout (triangle_strip, max_vertices = 4) out;\n"
   13049 					  "\n"
   13050 					  "subroutine void subroutineType(inout vec4 test);\n"
   13051 					  "\n"
   13052 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   13053 					  "{\n"
   13054 					  "    test = vec4(2, 3, 4, 5);\n"
   13055 					  "}\n"
   13056 					  "\n"
   13057 					  "subroutine uniform subroutineType function;\n"
   13058 					  "\n";
   13059 
   13060 	if (include_duplicate_function)
   13061 	{
   13062 		result_sstream << "void test_function(inout vec4 test)\n"
   13063 						  "{\n"
   13064 						  "    test = vec4(3, 4, 5, 6);\n"
   13065 						  "}\n"
   13066 						  "\n";
   13067 	}
   13068 
   13069 	result_sstream << "void main()\n"
   13070 					  "{\n"
   13071 					  "    function(gl_Position);\n"
   13072 					  "    EmitVertex();\n"
   13073 					  "    EndPrimitive();\n"
   13074 					  "}\n";
   13075 
   13076 	return result_sstream.str();
   13077 }
   13078 
   13079 /** Retrieves tess control shader that should be used for the purpose of the test.
   13080  *  An overloaded version of a subroutine function is inserted if
   13081  *  @param include_duplicate_function flag is set to true.
   13082  *
   13083  *  @param include_duplicate_function As per description.
   13084  *
   13085  *  @return Requested string.
   13086  **/
   13087 std::string NegativeTest10::getTessellationControlShader(bool include_duplicate_function)
   13088 {
   13089 	std::stringstream result_sstream;
   13090 
   13091 	result_sstream << "#version 400\n"
   13092 					  "\n"
   13093 					  "#extension GL_ARB_shader_subroutine : require\n"
   13094 					  "\n"
   13095 					  "layout (vertices = 4) out;\n"
   13096 					  "\n"
   13097 					  "subroutine void subroutineType(inout vec4 test);\n"
   13098 					  "\n"
   13099 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   13100 					  "{\n"
   13101 					  "    test = vec4(2, 3, 4, 5);\n"
   13102 					  "}\n"
   13103 					  "\n"
   13104 					  "subroutine uniform subroutineType function;\n"
   13105 					  "\n";
   13106 
   13107 	if (include_duplicate_function)
   13108 	{
   13109 		result_sstream << "void test_function(inout vec4 test)\n"
   13110 						  "{\n"
   13111 						  "    test = vec4(3, 4, 5, 6);\n"
   13112 						  "}\n"
   13113 						  "\n";
   13114 	}
   13115 
   13116 	result_sstream << "void main()\n"
   13117 					  "{\n"
   13118 					  "    vec4 temp;\n"
   13119 					  "\n"
   13120 					  "    function(temp);\n"
   13121 					  "\n"
   13122 					  "    gl_out[gl_InvocationID].gl_Position = temp;\n"
   13123 					  "    gl_TessLevelInner[0]                = temp.x;\n"
   13124 					  "    gl_TessLevelInner[1]                = temp.y;\n"
   13125 					  "    gl_TessLevelOuter[0]                = temp.z;\n"
   13126 					  "    gl_TessLevelOuter[1]                = temp.w;\n"
   13127 					  "    gl_TessLevelOuter[2]                = temp.x;\n"
   13128 					  "    gl_TessLevelOuter[3]                = temp.y;\n"
   13129 					  "}\n";
   13130 
   13131 	return result_sstream.str();
   13132 }
   13133 
   13134 /** Retrieves tess evaluation shader that should be used for the purpose of the test.
   13135  *  An overloaded version of a subroutine function is inserted if
   13136  *  @param include_duplicate_function flag is set to true.
   13137  *
   13138  *  @param include_duplicate_function As per description.
   13139  *
   13140  *  @return Requested string.
   13141  **/
   13142 std::string NegativeTest10::getTessellationEvaluationShader(bool include_duplicate_function)
   13143 {
   13144 	std::stringstream result_sstream;
   13145 
   13146 	result_sstream << "#version 400\n"
   13147 					  "\n"
   13148 					  "#extension GL_ARB_shader_subroutine : require\n"
   13149 					  "\n"
   13150 					  "layout (quads) in;\n"
   13151 					  "\n"
   13152 					  "subroutine void subroutineType(inout vec4 test);\n"
   13153 					  "\n"
   13154 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   13155 					  "{\n"
   13156 					  "    test = vec4(2, 3, 4, 5);\n"
   13157 					  "}\n"
   13158 					  "\n"
   13159 					  "subroutine uniform subroutineType function;\n"
   13160 					  "\n";
   13161 
   13162 	if (include_duplicate_function)
   13163 	{
   13164 		result_sstream << "void test_function(inout vec4 test)\n"
   13165 						  "{\n"
   13166 						  "    test = vec4(3, 4, 5, 6);\n"
   13167 						  "}\n"
   13168 						  "\n";
   13169 	}
   13170 
   13171 	result_sstream << "void main()\n"
   13172 					  "{\n"
   13173 					  "    vec4 temp;\n"
   13174 					  "\n"
   13175 					  "    function(temp);\n"
   13176 					  "\n"
   13177 					  "    gl_Position = temp;\n"
   13178 					  "}\n";
   13179 
   13180 	return result_sstream.str();
   13181 }
   13182 
   13183 /** Retrieves vertex shader that should be used for the purpose of the test.
   13184  *  An overloaded version of a subroutine function is inserted if
   13185  *  @param include_duplicate_function flag is set to true.
   13186  *
   13187  *  @param include_duplicate_function As per description.
   13188  *
   13189  *  @return Requested string.
   13190  **/
   13191 std::string NegativeTest10::getVertexShader(bool include_duplicate_function)
   13192 {
   13193 	std::stringstream result_sstream;
   13194 
   13195 	result_sstream << "#version 400\n"
   13196 					  "\n"
   13197 					  "#extension GL_ARB_shader_subroutine : require\n"
   13198 					  "\n"
   13199 					  "subroutine void subroutineType(inout vec4 test);\n"
   13200 					  "\n"
   13201 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   13202 					  "{\n"
   13203 					  "    test = vec4(2, 3, 4, 5);\n"
   13204 					  "}\n"
   13205 					  "\n"
   13206 					  "subroutine uniform subroutineType function;\n"
   13207 					  "\n";
   13208 
   13209 	if (include_duplicate_function)
   13210 	{
   13211 		result_sstream << "void test_function(inout vec4 test)\n"
   13212 						  "{\n"
   13213 						  "    test = vec4(3, 4, 5, 6);\n"
   13214 						  "}\n"
   13215 						  "\n";
   13216 	}
   13217 
   13218 	result_sstream << "void main()\n"
   13219 					  "{\n"
   13220 					  "    function(gl_Position);\n"
   13221 					  "}\n";
   13222 
   13223 	return result_sstream.str();
   13224 }
   13225 
   13226 /** Fills m_test_cases field with test case descriptors */
   13227 void NegativeTest10::initTestCases()
   13228 {
   13229 	/* For each test case, only one shader stage should define a function that
   13230 	 * has already been defined as a subroutine. */
   13231 	for (int offending_shader_stage_it = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   13232 		 offending_shader_stage_it != static_cast<int>(Utils::SHADER_STAGE_COUNT); ++offending_shader_stage_it)
   13233 	{
   13234 		Utils::_shader_stage offending_shader_stage = static_cast<Utils::_shader_stage>(offending_shader_stage_it);
   13235 		/* Form the test case descriptor */
   13236 		std::stringstream name_sstream;
   13237 		_test_case		  test_case;
   13238 
   13239 		name_sstream << "Broken shader stage:" << Utils::getShaderStageString(offending_shader_stage);
   13240 
   13241 		test_case.fs_body = getFragmentShader(offending_shader_stage == Utils::SHADER_STAGE_FRAGMENT);
   13242 		test_case.gs_body = getGeometryShader(offending_shader_stage == Utils::SHADER_STAGE_GEOMETRY);
   13243 		test_case.name	= name_sstream.str();
   13244 		test_case.tc_body =
   13245 			getTessellationControlShader(offending_shader_stage == Utils::SHADER_STAGE_TESSELLATION_CONTROL);
   13246 		test_case.te_body =
   13247 			getTessellationEvaluationShader(offending_shader_stage == Utils::SHADER_STAGE_TESSELLATION_EVALUATION);
   13248 		test_case.vs_body = getVertexShader(offending_shader_stage == Utils::SHADER_STAGE_VERTEX);
   13249 
   13250 		m_test_cases.push_back(test_case);
   13251 	}
   13252 }
   13253 
   13254 /** Executes test iteration.
   13255  *
   13256  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   13257  */
   13258 tcu::TestNode::IterateResult NegativeTest10::iterate()
   13259 {
   13260 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   13261 
   13262 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   13263 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   13264 	{
   13265 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   13266 	}
   13267 
   13268 	/* Form test cases */
   13269 	initTestCases();
   13270 
   13271 	/* Iterate over all test cases */
   13272 	for (_test_cases_const_iterator test_case_iterator = m_test_cases.begin(); test_case_iterator != m_test_cases.end();
   13273 		 ++test_case_iterator)
   13274 	{
   13275 		const _test_case& test_case = *test_case_iterator;
   13276 
   13277 		/* Try to build the program object */
   13278 		if (ShaderSubroutine::Utils::buildProgram(gl, test_case.vs_body, test_case.tc_body, test_case.te_body,
   13279 												  test_case.gs_body, test_case.fs_body, DE_NULL, /* xfb_varyings */
   13280 												  0,											 /* n_xfb_varyings */
   13281 												  &m_vs_id, (test_case.tc_body.length() > 0) ? &m_tc_id : DE_NULL,
   13282 												  (test_case.te_body.length() > 0) ? &m_te_id : DE_NULL,
   13283 												  (test_case.gs_body.length() > 0) ? &m_gs_id : DE_NULL,
   13284 												  (test_case.fs_body.length() > 0) ? &m_fs_id : DE_NULL, &m_po_id))
   13285 		{
   13286 			m_testCtx.getLog() << tcu::TestLog::Message << "A program object was successfully built for ["
   13287 							   << test_case.name << "] test case, even though it was invalid."
   13288 							   << tcu::TestLog::EndMessage;
   13289 
   13290 			m_has_test_passed = false;
   13291 		}
   13292 
   13293 		/* Delete any objects that may have been created */
   13294 		deinit();
   13295 	} /* for (all test cases) */
   13296 
   13297 	/** All done */
   13298 	if (m_has_test_passed)
   13299 	{
   13300 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   13301 	}
   13302 	else
   13303 	{
   13304 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   13305 	}
   13306 
   13307 	return STOP;
   13308 }
   13309 
   13310 /** Constructor.
   13311  *
   13312  *  @param context Rendering context.
   13313  **/
   13314 NegativeTest11::NegativeTest11(deqp::Context& context)
   13315 	: TestCase(context, "subroutine_uniforms_used_for_sampling_atomic_image_functions",
   13316 			   "Tries to use subroutine uniforms in invalid way in sampling, "
   13317 			   "atomic and image functions. Verifies that compile- or link-time "
   13318 			   "error occurs.")
   13319 	, m_has_test_passed(true)
   13320 	, m_po_id(0)
   13321 	, m_vs_id(0)
   13322 {
   13323 	/* Left blank intentionally */
   13324 }
   13325 
   13326 /** Deinitializes any GL objects that may have been created during
   13327  *  test execution.
   13328  **/
   13329 void NegativeTest11::deinit()
   13330 {
   13331 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   13332 
   13333 	if (m_po_id != 0)
   13334 	{
   13335 		gl.deleteProgram(m_po_id);
   13336 
   13337 		m_po_id = 0;
   13338 	}
   13339 
   13340 	if (m_vs_id != 0)
   13341 	{
   13342 		gl.deleteShader(m_vs_id);
   13343 
   13344 		m_vs_id = 0;
   13345 	}
   13346 }
   13347 
   13348 /** Returns a literal corresponding to user-specified test case enum.
   13349  *
   13350  *  @param test_case As per description.
   13351  *
   13352  *  @return Requested string.
   13353  **/
   13354 std::string NegativeTest11::getTestCaseString(const _test_case& test_case)
   13355 {
   13356 	std::string result = "?";
   13357 
   13358 	switch (test_case)
   13359 	{
   13360 	case TEST_CASE_INVALID_TEXTURE_SAMPLING_ATTEMPT:
   13361 		result = "TEST_CASE_INVALID_TEXTURE_SAMPLING_ATTEMPT";
   13362 		break;
   13363 	case TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT:
   13364 		result = "TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT";
   13365 		break;
   13366 	case TEST_CASE_INVALID_IMAGE_FUNCTION_USAGE_ATTEMPT:
   13367 		result = "TEST_CASE_INVALID_IMAGE_FUNCTION_USAGE_ATTEMPT";
   13368 		break;
   13369 	default:
   13370 		break;
   13371 	}
   13372 
   13373 	return result;
   13374 }
   13375 
   13376 /** Retrieves vertex shader body for user-specified test case.
   13377  *
   13378  *  @param test_case As per description.
   13379  *
   13380  *  @return Requested string.
   13381  **/
   13382 std::string NegativeTest11::getVertexShader(const _test_case& test_case)
   13383 {
   13384 	std::stringstream result_sstream;
   13385 
   13386 	/* Form pre-amble */
   13387 	result_sstream << "#version 400\n"
   13388 					  "\n"
   13389 					  "#extension GL_ARB_shader_subroutine : require\n";
   13390 
   13391 	if (test_case == TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT)
   13392 	{
   13393 		result_sstream << "#extension GL_ARB_shader_atomic_counters : require\n";
   13394 	}
   13395 
   13396 	result_sstream << "\n"
   13397 					  /* Define a subroutine */
   13398 					  "subroutine void subroutineType(inout vec4 test);\n"
   13399 					  "\n"
   13400 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   13401 					  "{\n"
   13402 					  "    test += vec4(0, 1, 2, 3);\n"
   13403 					  "}\n"
   13404 					  "\n"
   13405 					  "subroutine uniform subroutineType function;\n"
   13406 					  "\n"
   13407 
   13408 					  /* Define main() body */
   13409 					  "void main()\n"
   13410 					  "{\n";
   13411 
   13412 	/* Implement case-specific behavior */
   13413 	switch (test_case)
   13414 	{
   13415 	case TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT:
   13416 	{
   13417 		result_sstream << "if (atomicCounter(function) > 2)\n"
   13418 						  "{\n"
   13419 						  "    gl_Position = vec4(1);\n"
   13420 						  "}\n";
   13421 
   13422 		break;
   13423 	}
   13424 
   13425 	case TEST_CASE_INVALID_IMAGE_FUNCTION_USAGE_ATTEMPT:
   13426 	{
   13427 		result_sstream << "imageStore(function, vec2(0.0, 1.0), vec4(1.0) );\n";
   13428 
   13429 		break;
   13430 	}
   13431 
   13432 	case TEST_CASE_INVALID_TEXTURE_SAMPLING_ATTEMPT:
   13433 	{
   13434 		result_sstream << "gl_Position = texture(function, vec2(1.0) );\n";
   13435 
   13436 		break;
   13437 	}
   13438 
   13439 	default:
   13440 		break;
   13441 	} /* switch (test_case) */
   13442 
   13443 	/* Close main() body */
   13444 	result_sstream << "}\n";
   13445 
   13446 	/* Done */
   13447 	return result_sstream.str();
   13448 }
   13449 
   13450 /** Executes test iteration.
   13451  *
   13452  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   13453  */
   13454 tcu::TestNode::IterateResult NegativeTest11::iterate()
   13455 {
   13456 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   13457 
   13458 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   13459 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   13460 	{
   13461 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   13462 	}
   13463 
   13464 	/* Iterate over all test cases */
   13465 	for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT); ++test_case)
   13466 	{
   13467 		if (static_cast<_test_case>(test_case) == TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT &&
   13468 			!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_atomic_counters"))
   13469 		{
   13470 			/* This iteration requires atomic counter support that this GL implementation
   13471 			 * is not capable of. Skip the iteration
   13472 			 */
   13473 			continue;
   13474 		}
   13475 
   13476 		/* Try to build a program object using invalid vertex shader, specific to the
   13477 		 * iteration we're currently in */
   13478 		std::string vs_body = getVertexShader(static_cast<_test_case>(test_case));
   13479 
   13480 		if (ShaderSubroutine::Utils::buildProgram(gl, vs_body, "",   /* tc_body */
   13481 												  "",				 /* te_body */
   13482 												  "",				 /* gs_body */
   13483 												  "",				 /* fs_body */
   13484 												  DE_NULL,			 /* xfb_varyings */
   13485 												  0,				 /* n_xfb_varyings */
   13486 												  &m_vs_id, DE_NULL, /* out_tc_id */
   13487 												  DE_NULL,			 /* out_te_id */
   13488 												  DE_NULL,			 /* out_gs_id */
   13489 												  DE_NULL,			 /* out_fs_id */
   13490 												  &m_po_id))
   13491 		{
   13492 			m_testCtx.getLog() << tcu::TestLog::Message << "A program object was successfully built for ["
   13493 							   << getTestCaseString(static_cast<_test_case>(test_case))
   13494 							   << "] test case, even though it was invalid." << tcu::TestLog::EndMessage;
   13495 
   13496 			m_has_test_passed = false;
   13497 		}
   13498 
   13499 		/* Delete any objects that may have been created */
   13500 		deinit();
   13501 	} /* for (all test cases) */
   13502 
   13503 	/** All done */
   13504 	if (m_has_test_passed)
   13505 	{
   13506 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   13507 	}
   13508 	else
   13509 	{
   13510 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   13511 	}
   13512 
   13513 	return STOP;
   13514 }
   13515 
   13516 /** Constructor.
   13517  *
   13518  *  @param context Rendering context.
   13519  **/
   13520 NegativeTest12::NegativeTest12(deqp::Context& context)
   13521 	: TestCase(context, "subroutines_not_allowed_as_variables_constructors_and_argument_or_return_types",
   13522 			   "Verifies that it is not allowed to use subroutine type for "
   13523 			   "local/global variables, constructors or argument/return type.")
   13524 	, m_has_test_passed(true)
   13525 	, m_po_id(0)
   13526 	, m_vs_id(0)
   13527 {
   13528 	/* Left blank intentionally */
   13529 }
   13530 
   13531 /** Deinitializes any GL objects that may have been created during
   13532  *  test execution.
   13533  **/
   13534 void NegativeTest12::deinit()
   13535 {
   13536 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   13537 
   13538 	if (m_po_id != 0)
   13539 	{
   13540 		gl.deleteProgram(m_po_id);
   13541 
   13542 		m_po_id = 0;
   13543 	}
   13544 
   13545 	if (m_vs_id != 0)
   13546 	{
   13547 		gl.deleteShader(m_vs_id);
   13548 
   13549 		m_vs_id = 0;
   13550 	}
   13551 }
   13552 
   13553 /** Returns a literal corresponding to user-specified test case enum.
   13554  *
   13555  *  @param test_case As per description.
   13556  *
   13557  *  @return Requested string.
   13558  **/
   13559 std::string NegativeTest12::getTestCaseString(const _test_case& test_case)
   13560 {
   13561 	std::string result = "?";
   13562 
   13563 	switch (test_case)
   13564 	{
   13565 	case TEST_CASE_INVALID_LOCAL_SUBROUTINE_VARIABLE:
   13566 		result = "TEST_CASE_INVALID_LOCAL_SUBROUTINE_VARIABLE";
   13567 		break;
   13568 	case TEST_CASE_INVALID_GLOBAL_SUBROUTINE_VARIABLE:
   13569 		result = "TEST_CASE_INVALID_GLOBAL_SUBROUTINE_VARIABLE";
   13570 		break;
   13571 	case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR:
   13572 		result = "TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR";
   13573 		break;
   13574 	case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_ARGUMENT:
   13575 		result = "TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_ARGUMENT";
   13576 		break;
   13577 	case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_RETURN_TYPE:
   13578 		result = "TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_RETURN_TYPE";
   13579 		break;
   13580 	default:
   13581 		break;
   13582 	}
   13583 
   13584 	return result;
   13585 }
   13586 
   13587 /** Retrieves vertex shader body for user-specified test case.
   13588  *
   13589  *  @param test_case As per description.
   13590  *
   13591  *  @return Requested string.
   13592  **/
   13593 std::string NegativeTest12::getVertexShader(const _test_case& test_case)
   13594 {
   13595 	std::stringstream result_sstream;
   13596 
   13597 	/* Form pre-amble */
   13598 	result_sstream << "#version 400\n"
   13599 					  "\n"
   13600 					  "#extension GL_ARB_shader_subroutine : require\n"
   13601 					  "\n"
   13602 					  /* Define a subroutine */
   13603 					  "subroutine void subroutineType(inout vec4 test);\n"
   13604 					  "\n"
   13605 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   13606 					  "{\n"
   13607 					  "    test += vec4(0, 1, 2, 3);\n"
   13608 					  "}\n"
   13609 					  "\n"
   13610 					  "subroutine uniform subroutineType function;\n"
   13611 					  "\n";
   13612 
   13613 	/* Include case-specific implementation */
   13614 	switch (test_case)
   13615 	{
   13616 	case TEST_CASE_INVALID_LOCAL_SUBROUTINE_VARIABLE:
   13617 	{
   13618 		result_sstream << "void main()\n"
   13619 						  "{\n"
   13620 						  "    subroutine subroutineType function2;\n"
   13621 						  "    vec4                      result;\n"
   13622 						  "\n"
   13623 						  "    function2(result);\n"
   13624 						  "    gl_Position = result;\n"
   13625 						  "}\n";
   13626 
   13627 		break;
   13628 	}
   13629 
   13630 	case TEST_CASE_INVALID_GLOBAL_SUBROUTINE_VARIABLE:
   13631 	{
   13632 		result_sstream << "subroutine subroutineType function2;\n"
   13633 						  "\n"
   13634 						  "void main()\n"
   13635 						  "{\n"
   13636 						  "    vec4 result;\n"
   13637 						  "\n"
   13638 						  "    function2(result);\n"
   13639 						  "    gl_Position = result;\n"
   13640 						  "}\n";
   13641 
   13642 		break;
   13643 	}
   13644 
   13645 	case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR:
   13646 	{
   13647 		result_sstream << "void main()\n"
   13648 						  "{\n"
   13649 						  "    subroutineType(function);\n"
   13650 						  "}\n";
   13651 
   13652 		break;
   13653 	}
   13654 
   13655 	case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_ARGUMENT:
   13656 	{
   13657 		result_sstream << "vec4 test_function(subroutineType argument)\n"
   13658 						  "{\n"
   13659 						  "    vec4 result = vec4(1, 2, 3, 4);\n"
   13660 						  "\n"
   13661 						  "    argument(result);\n"
   13662 						  "\n"
   13663 						  "    return result;\n"
   13664 						  "}\n"
   13665 						  "\n"
   13666 						  "void main()\n"
   13667 						  "{\n"
   13668 						  "    test_function(function);\n"
   13669 						  "}\n";
   13670 
   13671 		break;
   13672 	}
   13673 
   13674 	case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_RETURN_TYPE:
   13675 	{
   13676 		result_sstream << "subroutineType test_function()\n"
   13677 						  "{\n"
   13678 						  "    return function;\n"
   13679 						  "}\n"
   13680 						  "\n"
   13681 						  "void main()\n"
   13682 						  "{\n"
   13683 						  "    test_function()(gl_Position);\n"
   13684 						  "}\n";
   13685 
   13686 		break;
   13687 	}
   13688 
   13689 	default:
   13690 		break;
   13691 	} /* switch (test_case) */
   13692 
   13693 	/* Done */
   13694 	return result_sstream.str();
   13695 }
   13696 
   13697 /** Executes test iteration.
   13698  *
   13699  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   13700  */
   13701 tcu::TestNode::IterateResult NegativeTest12::iterate()
   13702 {
   13703 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   13704 
   13705 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   13706 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   13707 	{
   13708 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   13709 	}
   13710 
   13711 	/* Iterate over all test cases */
   13712 	for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT); ++test_case)
   13713 	{
   13714 		/* Try to build a program object using invalid vertex shader, specific to the
   13715 		 * iteration we're currently in */
   13716 		std::string vs_body = getVertexShader(static_cast<_test_case>(test_case));
   13717 
   13718 		if (ShaderSubroutine::Utils::buildProgram(gl, vs_body, "",   /* tc_body */
   13719 												  "",				 /* te_body */
   13720 												  "",				 /* gs_body */
   13721 												  "",				 /* fs_body */
   13722 												  DE_NULL,			 /* xfb_varyings */
   13723 												  0,				 /* n_xfb_varyings */
   13724 												  &m_vs_id, DE_NULL, /* out_tc_id */
   13725 												  DE_NULL,			 /* out_te_id */
   13726 												  DE_NULL,			 /* out_gs_id */
   13727 												  DE_NULL,			 /* out_fs_id */
   13728 												  &m_po_id))
   13729 		{
   13730 			m_testCtx.getLog() << tcu::TestLog::Message << "A program object was successfully built for ["
   13731 							   << getTestCaseString(static_cast<_test_case>(test_case))
   13732 							   << "] test case, even though it was invalid." << tcu::TestLog::EndMessage;
   13733 
   13734 			m_has_test_passed = false;
   13735 		}
   13736 
   13737 		/* Delete any objects that may have been created */
   13738 		deinit();
   13739 	} /* for (all test cases) */
   13740 
   13741 	/** All done */
   13742 	if (m_has_test_passed)
   13743 	{
   13744 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   13745 	}
   13746 	else
   13747 	{
   13748 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   13749 	}
   13750 
   13751 	return STOP;
   13752 }
   13753 
   13754 } /* ShaderSubroutine */
   13755 
   13756 /** Constructor.
   13757  *
   13758  *  @param context Rendering context.
   13759  **/
   13760 ShaderSubroutineTests::ShaderSubroutineTests(deqp::Context& context)
   13761 	: TestCaseGroup(context, "shader_subroutine", "Verifies \"shader_subroutine\" functionality")
   13762 {
   13763 	/* Left blank on purpose */
   13764 }
   13765 
   13766 /** Initializes a texture_storage_multisample test group.
   13767  *
   13768  **/
   13769 void ShaderSubroutineTests::init(void)
   13770 {
   13771 	addChild(new ShaderSubroutine::APITest1(m_context));
   13772 	addChild(new ShaderSubroutine::APITest2(m_context));
   13773 	addChild(new ShaderSubroutine::FunctionalTest1_2(m_context));
   13774 	addChild(new ShaderSubroutine::FunctionalTest3_4(m_context));
   13775 	addChild(new ShaderSubroutine::FunctionalTest5(m_context));
   13776 	addChild(new ShaderSubroutine::FunctionalTest6(m_context));
   13777 	addChild(new ShaderSubroutine::FunctionalTest7_8(m_context));
   13778 	addChild(new ShaderSubroutine::FunctionalTest9(m_context));
   13779 	addChild(new ShaderSubroutine::FunctionalTest10(m_context));
   13780 	addChild(new ShaderSubroutine::FunctionalTest11(m_context));
   13781 	addChild(new ShaderSubroutine::FunctionalTest12(m_context));
   13782 	addChild(new ShaderSubroutine::FunctionalTest13(m_context));
   13783 	addChild(new ShaderSubroutine::FunctionalTest14_15(m_context));
   13784 	addChild(new ShaderSubroutine::FunctionalTest16(m_context));
   13785 	addChild(new ShaderSubroutine::FunctionalTest17(m_context));
   13786 	addChild(new ShaderSubroutine::FunctionalTest18_19(m_context));
   13787 	addChild(new ShaderSubroutine::NegativeTest1(m_context));
   13788 	addChild(new ShaderSubroutine::NegativeTest2(m_context));
   13789 	addChild(new ShaderSubroutine::NegativeTest3(m_context));
   13790 	addChild(new ShaderSubroutine::NegativeTest4(m_context));
   13791 	addChild(new ShaderSubroutine::NegativeTest5(m_context));
   13792 	addChild(new ShaderSubroutine::NegativeTest6(m_context));
   13793 	addChild(new ShaderSubroutine::NegativeTest7(m_context));
   13794 	addChild(new ShaderSubroutine::NegativeTest8(m_context));
   13795 	addChild(new ShaderSubroutine::NegativeTest9(m_context));
   13796 	addChild(new ShaderSubroutine::NegativeTest10(m_context));
   13797 	addChild(new ShaderSubroutine::NegativeTest11(m_context));
   13798 	addChild(new ShaderSubroutine::NegativeTest12(m_context));
   13799 }
   13800 
   13801 } /* glcts namespace */
   13802